feat(hub): mobile AI tabs and dashboard position lines

Mobile AI coach uses four top tabs (trading, general, history, new) with single-panel view and wider desktop history. Dashboard account cards show key levels and positions one per line with colored float PnL.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-11 11:16:28 +08:00
parent c59a17f9ac
commit 1042fdeef3
7 changed files with 185 additions and 39 deletions
+37
View File
@@ -652,6 +652,43 @@ def format_account_remark(ac: dict) -> str:
return "".join(parts)
def format_dashboard_account_lines(ac: dict) -> list[dict[str, Any]]:
"""数据看板分户卡片:监控与持仓逐行展示(含浮盈亏数值供前端着色)。"""
lines: list[dict[str, Any]] = []
mon = ac.get("monitor_lines") or {}
for row in (mon.get("keys") or [])[:3]:
if row:
lines.append({"kind": "monitor", "text": str(row)})
for row in (mon.get("orders") or [])[:3]:
if row:
lines.append({"kind": "monitor", "text": str(row)})
for row in (mon.get("trends") or [])[:2]:
if row:
lines.append({"kind": "monitor", "text": str(row)})
for row in (mon.get("rolls") or [])[:2]:
if row:
lines.append({"kind": "monitor", "text": str(row)})
for p in _filter_open_positions(ac.get("positions") or []):
sym = p.get("symbol") or "?"
side = p.get("side") or "?"
upnl = _position_float_pnl(p)
lines.append(
{
"kind": "position",
"text": f"{sym} {side}",
"pnl": round(upnl, 4),
}
)
if not lines:
issues = ac.get("issues") or []
if issues:
for iss in issues[:3]:
lines.append({"kind": "issue", "text": str(iss)})
else:
lines.append({"kind": "empty", "text": ""})
return lines
def collect_closed_trades_snapshot(
accounts: list[dict],
*,