Move fleet stats to nav page; backfill funds and loss metrics from curve/status.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -278,6 +278,26 @@ async def node_status(
|
||||
return await _collect_one_status(node)
|
||||
|
||||
|
||||
def _max_single_loss_from_curve(curve: list[Any]) -> float:
|
||||
pnls = [float(x.get("realized_pnl") or 0) for x in curve if isinstance(x, dict)]
|
||||
if not pnls:
|
||||
return 0.0
|
||||
worst = min(pnls)
|
||||
return float(worst) if worst < 0 else 0.0
|
||||
|
||||
|
||||
def _loss_streak_from_curve(curve: list[Any]) -> int:
|
||||
streak = 0
|
||||
for item in reversed(curve):
|
||||
if not isinstance(item, dict):
|
||||
continue
|
||||
if float(item.get("realized_pnl") or 0) < 0:
|
||||
streak += 1
|
||||
else:
|
||||
break
|
||||
return streak
|
||||
|
||||
|
||||
async def _collect_one_stats(node: dict[str, Any]) -> dict[str, Any]:
|
||||
base = {
|
||||
"id": node["id"],
|
||||
@@ -304,16 +324,37 @@ async def _collect_one_stats(node: dict[str, Any]) -> dict[str, Any]:
|
||||
if code >= 400 or not isinstance(data, dict):
|
||||
base["error"] = _http_detail(data) if data else f"HTTP {code}"
|
||||
return base
|
||||
|
||||
curve = data.get("equity_curve") if isinstance(data.get("equity_curve"), list) else []
|
||||
max_loss = data.get("max_single_loss")
|
||||
if max_loss is None:
|
||||
max_loss = _max_single_loss_from_curve(curve)
|
||||
loss_streak = data.get("loss_streak")
|
||||
if loss_streak is None:
|
||||
loss_streak = _loss_streak_from_curve(curve)
|
||||
|
||||
latest_funds = data.get("latest_funds")
|
||||
if latest_funds is None:
|
||||
# 旧版策略机 stats 无资金字段:回落 status.latest_funds
|
||||
try:
|
||||
sc, sd = await call_node(node, "GET", "/api/fleet/status", timeout=8.0)
|
||||
if sc < 400 and isinstance(sd, dict) and sd.get("latest_funds") is not None:
|
||||
latest_funds = sd.get("latest_funds")
|
||||
except Exception:
|
||||
pass
|
||||
if latest_funds is None:
|
||||
latest_funds = 0.0
|
||||
|
||||
base.update(
|
||||
{
|
||||
"ok": True,
|
||||
"latest_funds": data.get("latest_funds"),
|
||||
"latest_funds": latest_funds,
|
||||
"groups": data.get("groups"),
|
||||
"fees_perp": data.get("fees_perp"),
|
||||
"fees_option": data.get("fees_option"),
|
||||
"total_fees": data.get("total_fees"),
|
||||
"max_single_loss": data.get("max_single_loss"),
|
||||
"loss_streak": data.get("loss_streak"),
|
||||
"max_single_loss": max_loss,
|
||||
"loss_streak": loss_streak,
|
||||
"total_pnl": data.get("total_pnl"),
|
||||
"mode": data.get("mode"),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user