fix: _get_strategy_trade_stats 兼容旧数据(strategy文本)和新数据(strategy_id),修复open_positions计算(含tp1_hit),current_balance实时计算
This commit is contained in:
parent
d3784aaf79
commit
06f900b89b
@ -2456,22 +2456,39 @@ def _strategy_row_to_detail(row: dict) -> dict:
|
||||
|
||||
|
||||
async def _get_strategy_trade_stats(strategy_id: str) -> dict:
|
||||
"""Fetch trade statistics for a strategy by strategy_id"""
|
||||
rows = await async_fetch(
|
||||
"""SELECT status, pnl_r, tp1_hit, entry_ts, exit_ts
|
||||
FROM paper_trades
|
||||
WHERE strategy_id=$1 AND status != 'active'
|
||||
ORDER BY entry_ts DESC""",
|
||||
strategy_id
|
||||
)
|
||||
"""Fetch trade statistics for a strategy by strategy_id.
|
||||
兼容新数据(strategy_id列)和旧数据(strategy文本列)。
|
||||
"""
|
||||
# 固定 UUID → legacy strategy文本名映射(迁移时写死的三条策略)
|
||||
LEGACY_NAME_MAP = {
|
||||
"00000000-0000-0000-0000-000000000053": "v53",
|
||||
"00000000-0000-0000-0000-000000000054": "v53_middle",
|
||||
"00000000-0000-0000-0000-000000000055": "v53_fast",
|
||||
}
|
||||
legacy_name = LEGACY_NAME_MAP.get(strategy_id)
|
||||
|
||||
# 查已关闭的交易记录(同时兼容新旧两种匹配方式)
|
||||
if legacy_name:
|
||||
rows = await async_fetch(
|
||||
"""SELECT status, pnl_r, tp1_hit, entry_ts, exit_ts
|
||||
FROM paper_trades
|
||||
WHERE status NOT IN ('active', 'tp1_hit')
|
||||
AND (strategy_id=$1 OR (strategy_id IS NULL AND strategy=$2))
|
||||
ORDER BY entry_ts DESC""",
|
||||
strategy_id, legacy_name
|
||||
)
|
||||
else:
|
||||
rows = await async_fetch(
|
||||
"""SELECT status, pnl_r, tp1_hit, entry_ts, exit_ts
|
||||
FROM paper_trades
|
||||
WHERE strategy_id=$1 AND status NOT IN ('active', 'tp1_hit')
|
||||
ORDER BY entry_ts DESC""",
|
||||
strategy_id
|
||||
)
|
||||
|
||||
if not rows:
|
||||
return {
|
||||
"trade_count": 0, "win_rate": 0.0,
|
||||
"avg_win_r": 0.0, "avg_loss_r": 0.0,
|
||||
"open_positions": 0,
|
||||
"pnl_usdt_24h": 0.0, "pnl_r_24h": 0.0,
|
||||
"last_trade_at": None,
|
||||
}
|
||||
# 即使没有历史记录也要查持仓
|
||||
pass
|
||||
|
||||
total = len(rows)
|
||||
wins = [r for r in rows if (r["pnl_r"] or 0) > 0]
|
||||
@ -2487,12 +2504,21 @@ async def _get_strategy_trade_stats(strategy_id: str) -> dict:
|
||||
pnl_r_24h = round(sum(r["pnl_r"] or 0 for r in rows_24h), 3)
|
||||
pnl_usdt_24h = round(pnl_r_24h * 200, 2)
|
||||
|
||||
# Open positions
|
||||
open_rows = await async_fetch(
|
||||
"SELECT COUNT(*) as cnt FROM paper_trades WHERE strategy_id=$1 AND status='active'",
|
||||
strategy_id
|
||||
)
|
||||
open_positions = open_rows[0]["cnt"] if open_rows else 0
|
||||
# Open positions — status IN ('active','tp1_hit'),同时兼容新旧记录
|
||||
if legacy_name:
|
||||
open_rows = await async_fetch(
|
||||
"""SELECT COUNT(*) as cnt FROM paper_trades
|
||||
WHERE status IN ('active','tp1_hit')
|
||||
AND (strategy_id=$1 OR (strategy_id IS NULL AND strategy=$2))""",
|
||||
strategy_id, legacy_name
|
||||
)
|
||||
else:
|
||||
open_rows = await async_fetch(
|
||||
"""SELECT COUNT(*) as cnt FROM paper_trades
|
||||
WHERE strategy_id=$1 AND status IN ('active','tp1_hit')""",
|
||||
strategy_id
|
||||
)
|
||||
open_positions = int(open_rows[0]["cnt"]) if open_rows else 0
|
||||
|
||||
return {
|
||||
"trade_count": total,
|
||||
@ -2503,6 +2529,8 @@ async def _get_strategy_trade_stats(strategy_id: str) -> dict:
|
||||
"pnl_usdt_24h": pnl_usdt_24h,
|
||||
"pnl_r_24h": pnl_r_24h,
|
||||
"last_trade_at": last_trade_at,
|
||||
"net_r": round(sum(r["pnl_r"] or 0 for r in rows), 3),
|
||||
"net_usdt": round(sum(r["pnl_r"] or 0 for r in rows) * 200, 2),
|
||||
}
|
||||
|
||||
|
||||
@ -2569,6 +2597,8 @@ async def list_strategies(
|
||||
d = _strategy_row_to_card(dict(row))
|
||||
stats = await _get_strategy_trade_stats(str(row["strategy_id"]))
|
||||
d.update(stats)
|
||||
# 用实时计算的 net_usdt 覆盖 DB 静态的 current_balance
|
||||
d["current_balance"] = round(row["initial_balance"] + d["net_usdt"], 2)
|
||||
result.append(d)
|
||||
return {"strategies": result}
|
||||
|
||||
@ -2580,6 +2610,7 @@ async def get_strategy(sid: str, user: dict = Depends(get_current_user)):
|
||||
detail = _strategy_row_to_detail(row)
|
||||
stats = await _get_strategy_trade_stats(sid)
|
||||
detail.update(stats)
|
||||
detail["current_balance"] = round(row["initial_balance"] + detail["net_usdt"], 2)
|
||||
return {"strategy": detail}
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user