From 60b3743e8d573b156b8f7863c2c92afb50e5cd27 Mon Sep 17 00:00:00 2001 From: dekun Date: Sun, 2 Aug 2026 12:51:47 +0800 Subject: [PATCH] Add initial funds to fleet stats and color total PnL. Co-authored-by: Cursor --- backend/app/api/stats.py | 9 +++++++++ control/backend/app/api/nodes.py | 10 ++++++++++ control/frontend/src/pages/Stats.tsx | 6 ++++++ control/frontend/src/styles.css | 12 ++++++++++++ 4 files changed, 37 insertions(+) diff --git a/backend/app/api/stats.py b/backend/app/api/stats.py index 3830c5b..6fa0d7a 100644 --- a/backend/app/api/stats.py +++ b/backend/app/api/stats.py @@ -79,6 +79,14 @@ def build_stats_summary(db: Any | None = None) -> dict[str, Any]: except Exception: latest_funds = 0.0 + try: + initial_funds = float( + database.get_setting("initial_equity", str(s.initial_equity)) + or s.initial_equity + ) + except Exception: + initial_funds = float(s.initial_equity) + return { "mode": mode, "show_slip": mode == "SIM", @@ -92,6 +100,7 @@ def build_stats_summary(db: Any | None = None) -> dict[str, Any]: "total_slip": total_slip if mode == "SIM" else 0.0, "close_reasons": reasons, "equity_curve": curve, + "initial_funds": initial_funds, "latest_funds": latest_funds, "max_single_loss": max_single_loss, "loss_streak": _current_loss_streak(curve), diff --git a/control/backend/app/api/nodes.py b/control/backend/app/api/nodes.py index d89bcdd..3804475 100644 --- a/control/backend/app/api/nodes.py +++ b/control/backend/app/api/nodes.py @@ -304,6 +304,7 @@ async def _collect_one_stats(node: dict[str, Any]) -> dict[str, Any]: "name": node["name"], "ok": False, "error": None, + "initial_funds": None, "latest_funds": None, "groups": None, "fees_perp": None, @@ -345,9 +346,18 @@ async def _collect_one_stats(node: dict[str, Any]) -> dict[str, Any]: if latest_funds is None: latest_funds = 0.0 + initial_funds = data.get("initial_funds") + if initial_funds is None: + # 旧版策略机:用最新资金 − 已实现盈亏近似初始资金 + try: + initial_funds = float(latest_funds) - float(data.get("total_pnl") or 0) + except Exception: + initial_funds = None + base.update( { "ok": True, + "initial_funds": initial_funds, "latest_funds": latest_funds, "groups": data.get("groups"), "fees_perp": data.get("fees_perp"), diff --git a/control/frontend/src/pages/Stats.tsx b/control/frontend/src/pages/Stats.tsx index 3c06a91..a66aa6f 100644 --- a/control/frontend/src/pages/Stats.tsx +++ b/control/frontend/src/pages/Stats.tsx @@ -6,6 +6,7 @@ type FleetStatsRow = { name: string; ok: boolean; error?: string | null; + initial_funds?: number | null; latest_funds?: number | null; groups?: number | null; fees_perp?: number | null; @@ -82,6 +83,7 @@ export default function StatsPage() { 机器名 + 初始资金 最新资金 轮次 永续手续费 @@ -103,6 +105,9 @@ export default function StatsPage() { ) : null} + + {row.ok ? fmt(row.initial_funds ?? 0, 2) : "—"} + {row.ok ? fmt(row.latest_funds ?? 0, 2) : "—"} @@ -139,6 +144,7 @@ export default function StatsPage() { ({okRows.length}/{fleetStats.length}) + {fmt(sum("initial_funds"), 2)} {fmt(sum("latest_funds"), 2)} {sum("groups")} {fmt(sum("fees_perp"), 4)} diff --git a/control/frontend/src/styles.css b/control/frontend/src/styles.css index 8211734..96b546d 100644 --- a/control/frontend/src/styles.css +++ b/control/frontend/src/styles.css @@ -422,6 +422,18 @@ input { color: var(--accent); } +.stats-table tfoot .stats-total-row td.pnl-pos { + color: var(--pnl-pos); +} + +.stats-table tfoot .stats-total-row td.pnl-neg { + color: var(--pnl-neg); +} + +.stats-table tfoot .stats-total-row td.pnl-flat { + color: var(--text); +} + .btn-sm { padding: 4px 8px; font-size: 0.78rem;