ui: 顶栏透明、设置两列、下单与持仓监控优化

导航栏与页面背景一致;系统设置双列布局;下单三行表单与开仓状态反馈;持仓卡片增加平仓与止盈止损挂单展示。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-24 12:46:23 +08:00
parent 528d9811e3
commit 67683f5562
8 changed files with 304 additions and 75 deletions
+83
View File
@@ -48,6 +48,7 @@ from ctp_symbol import ths_to_vnpy_symbol
from vnpy_bridge import (
ctp_connect,
ctp_get_account,
ctp_list_active_orders,
ctp_list_positions,
ctp_status,
execute_order,
@@ -110,6 +111,68 @@ def install_trading(app, *, login_required, require_nav, get_db, get_setting, se
except Exception:
return ""
def _build_pending_orders(conn, mode: str) -> list[dict]:
pending: list[dict] = []
for r in conn.execute(
"SELECT * FROM trade_order_monitors WHERE status='active' ORDER BY id DESC"
).fetchall():
mon = dict(r)
sym = mon.get("symbol") or ""
direction = mon.get("direction") or "long"
lots = int(mon.get("lots") or 0)
base = {
"symbol_code": sym,
"symbol": mon.get("symbol_name") or sym,
"direction": direction,
"direction_label": "做多" if direction == "long" else "做空",
"lots": lots,
"source": "monitor",
}
sl = mon.get("stop_loss")
tp = mon.get("take_profit")
if sl is not None:
pending.append({
**base,
"order_kind": "stop_loss",
"label": "止损挂单",
"price": float(sl),
})
if tp is not None:
pending.append({
**base,
"order_kind": "take_profit",
"label": "止盈挂单",
"price": float(tp),
})
ctp_st = ctp_status(mode)
if ctp_st.get("connected"):
for o in _ctp_active_orders(mode):
sym = o.get("symbol") or ""
offset_s = (o.get("offset") or "").upper()
kind = "limit"
label = "委托挂单"
if "CLOSE" in offset_s:
label = "平仓委托"
pending.append({
"symbol_code": sym,
"symbol": sym,
"direction": o.get("direction") or "long",
"direction_label": "做多" if o.get("direction") == "long" else "做空",
"lots": int(o.get("lots") or 0),
"price": float(o.get("price") or 0),
"order_kind": kind,
"label": label,
"source": "ctp",
"order_id": o.get("order_id"),
})
return pending
def _ctp_active_orders(mode: str) -> list:
try:
return ctp_list_active_orders(mode)
except Exception:
return []
def _build_trading_live_rows(conn) -> list[dict]:
from zoneinfo import ZoneInfo
tz = ZoneInfo("Asia/Shanghai")
@@ -150,6 +213,23 @@ def install_trading(app, *, login_required, require_nav, get_db, get_setting, se
break
sl = float(mon["stop_loss"]) if mon and mon.get("stop_loss") is not None else None
tp = float(mon["take_profit"]) if mon and mon.get("take_profit") is not None else None
pending_for_row: list[dict] = []
if sl is not None:
pending_for_row.append({
"order_kind": "stop_loss",
"label": "止损挂单",
"price": sl,
"lots": lots,
"source": "monitor",
})
if tp is not None:
pending_for_row.append({
"order_kind": "take_profit",
"label": "止盈挂单",
"price": tp,
"lots": lots,
"source": "monitor",
})
rows.append({
"key": f"ctp:{sym.lower()}:{direction}",
"source": "ctp",
@@ -169,6 +249,7 @@ def install_trading(app, *, login_required, require_nav, get_db, get_setting, se
"price_precision": tick.get("price_precision"),
"tick_size": tick.get("tick_size"),
"can_close": True,
"pending_orders": pending_for_row,
})
return rows
@@ -234,11 +315,13 @@ def install_trading(app, *, login_required, require_nav, get_db, get_setting, se
mode = get_trading_mode(get_setting)
ctp_st = ctp_status(mode)
rows = _build_trading_live_rows(conn)
pending_orders = _build_pending_orders(conn, mode)
capital = _capital(conn)
risk = get_risk_status(conn)
conn.commit()
return jsonify({
"rows": rows,
"pending_orders": pending_orders,
"capital": capital,
"ctp_status": ctp_st,
"trading_mode_label": trading_mode_label(get_setting),