Fix OKX header trade stats stuck at zero after settings shell load.
Always SSR records summary on embed shell (including settings/risk/env), and refresh total/win-rate/PL ratio via account_snapshot so soft-nav cannot leave the strip blank. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -7458,6 +7458,9 @@ def api_account_snapshot():
|
||||
active_pnl_rows = conn.execute(
|
||||
"SELECT exchange_symbol, symbol, direction FROM order_monitors WHERE status='active'"
|
||||
).fetchall()
|
||||
from lib.instance.instance_embed_context_lib import header_trade_stats_for_window, total_funds_usdt
|
||||
|
||||
header_trade_stats = header_trade_stats_for_window(conn, _list_window_from_request(), APP_TZ)
|
||||
conn.close()
|
||||
can_trade = can_trade_new_open(
|
||||
time_allows=trading_day_reset_allows_new_open(now),
|
||||
@@ -7468,7 +7471,6 @@ def api_account_snapshot():
|
||||
extra_blocks=not risk_status.get("can_trade", True),
|
||||
)
|
||||
available_trading_usdt = get_available_trading_usdt()
|
||||
from lib.instance.instance_embed_context_lib import total_funds_usdt
|
||||
|
||||
unrealized_pnl = None
|
||||
if exchange_private_api_configured():
|
||||
@@ -7498,6 +7500,9 @@ def api_account_snapshot():
|
||||
"daily_open_alert_threshold": DAILY_OPEN_ALERT_THRESHOLD,
|
||||
"manual_min_planned_rr": MANUAL_MIN_PLANNED_RR,
|
||||
"trading_day": trading_day,
|
||||
"total": header_trade_stats["total"],
|
||||
"rate": header_trade_stats["rate"],
|
||||
"profit_loss_ratio": header_trade_stats.get("profit_loss_ratio"),
|
||||
"risk_status": risk_status,
|
||||
**force_close_template_context(
|
||||
FORCE_CLOSE_ENABLED,
|
||||
|
||||
@@ -7274,6 +7274,9 @@ def api_account_snapshot():
|
||||
active_pnl_rows = conn.execute(
|
||||
"SELECT exchange_symbol, symbol, direction FROM order_monitors WHERE status='active'"
|
||||
).fetchall()
|
||||
from lib.instance.instance_embed_context_lib import header_trade_stats_for_window, total_funds_usdt
|
||||
|
||||
header_trade_stats = header_trade_stats_for_window(conn, _list_window_from_request(), APP_TZ)
|
||||
conn.close()
|
||||
can_trade = can_trade_new_open(
|
||||
time_allows=trading_day_reset_allows_new_open(now),
|
||||
@@ -7284,7 +7287,6 @@ def api_account_snapshot():
|
||||
extra_blocks=not risk_status.get("can_trade", True),
|
||||
)
|
||||
available_trading_usdt = get_available_trading_usdt()
|
||||
from lib.instance.instance_embed_context_lib import total_funds_usdt
|
||||
|
||||
unrealized_pnl = None
|
||||
if exchange_private_api_configured():
|
||||
@@ -7317,6 +7319,9 @@ def api_account_snapshot():
|
||||
"daily_open_alert_threshold": DAILY_OPEN_ALERT_THRESHOLD,
|
||||
"manual_min_planned_rr": MANUAL_MIN_PLANNED_RR,
|
||||
"trading_day": trading_day,
|
||||
"total": header_trade_stats["total"],
|
||||
"rate": header_trade_stats["rate"],
|
||||
"profit_loss_ratio": header_trade_stats.get("profit_loss_ratio"),
|
||||
"risk_status": risk_status,
|
||||
**force_close_template_context(
|
||||
FORCE_CLOSE_ENABLED,
|
||||
|
||||
@@ -6942,6 +6942,9 @@ def api_account_snapshot():
|
||||
active_pnl_rows = conn.execute(
|
||||
"SELECT exchange_symbol, symbol, direction FROM order_monitors WHERE status='active'"
|
||||
).fetchall()
|
||||
from lib.instance.instance_embed_context_lib import header_trade_stats_for_window, total_funds_usdt
|
||||
|
||||
header_trade_stats = header_trade_stats_for_window(conn, _list_window_from_request(), APP_TZ)
|
||||
conn.close()
|
||||
open_guard_blocks_now = open_guard_enabled and now.hour < TRADING_DAY_RESET_HOUR
|
||||
can_trade = can_trade_new_open(
|
||||
@@ -6953,7 +6956,6 @@ def api_account_snapshot():
|
||||
extra_blocks=not risk_status.get("can_trade", True),
|
||||
)
|
||||
available_trading_usdt = get_available_trading_usdt()
|
||||
from lib.instance.instance_embed_context_lib import total_funds_usdt
|
||||
|
||||
unrealized_pnl = None
|
||||
if exchange_private_api_configured():
|
||||
@@ -7021,6 +7023,9 @@ def api_account_snapshot():
|
||||
"reset_hour": TRADING_DAY_RESET_HOUR,
|
||||
"manual_min_planned_rr": MANUAL_MIN_PLANNED_RR,
|
||||
"trading_day": trading_day,
|
||||
"total": header_trade_stats["total"],
|
||||
"rate": header_trade_stats["rate"],
|
||||
"profit_loss_ratio": header_trade_stats.get("profit_loss_ratio"),
|
||||
"risk_status": risk_status,
|
||||
**force_close_template_context(
|
||||
FORCE_CLOSE_ENABLED,
|
||||
|
||||
@@ -38,11 +38,11 @@ def embed_render_plan(page: str, embed_mode: str | None) -> EmbedRenderPlan:
|
||||
)
|
||||
is_shell = embed_mode == "shell"
|
||||
is_strategy = page in EMBED_STRATEGY_PAGES
|
||||
is_settings_like = page in ("settings", "risk_policy", "env_config")
|
||||
return EmbedRenderPlan(
|
||||
exchange_capitals=is_shell,
|
||||
records_rows=page == "records",
|
||||
records_summary=is_shell and page != "records" and not is_settings_like,
|
||||
# 顶栏常驻:设置/风控/env 也要统计,否则首屏 SSR 为 0 后软切 tab 不会重绘顶栏
|
||||
records_summary=is_shell and page != "records",
|
||||
key_history=page == "key_monitor",
|
||||
key_list=page in ("key_monitor", "trade") or is_strategy,
|
||||
orders=page == "trade" or is_strategy,
|
||||
@@ -157,5 +157,21 @@ def trade_records_summary(conn, start_bj: str, end_bj: str, tr_ts: str) -> dict[
|
||||
}
|
||||
|
||||
|
||||
def header_trade_stats_for_window(conn, list_window: dict[str, Any], app_tz) -> dict[str, Any]:
|
||||
"""account_snapshot / 顶栏刷新:按当前列表窗返回总交易/胜率/盈亏比."""
|
||||
from lib.common.history_window_lib import sql_list_time_field, utc_window_to_bj_sql_strings
|
||||
|
||||
start_bj, end_bj = utc_window_to_bj_sql_strings(
|
||||
list_window["start_utc"], list_window["end_utc"], app_tz
|
||||
)
|
||||
tr_ts = sql_list_time_field("closed_at", "created_at", "opened_at")
|
||||
summary = trade_records_summary(conn, start_bj, end_bj, tr_ts)
|
||||
return {
|
||||
"total": summary["total"],
|
||||
"rate": summary["rate"],
|
||||
"profit_loss_ratio": summary.get("profit_loss_ratio"),
|
||||
}
|
||||
|
||||
|
||||
def minimal_stats_bundle(reset_hour: int) -> dict[str, Any]:
|
||||
return {"stats_reset_hour": reset_hour, "segments": []}
|
||||
|
||||
@@ -1178,6 +1178,20 @@ function applyAccountSnapshot(data){
|
||||
if(typeof data.unrealized_pnl !== "undefined"){
|
||||
updateRealtimePnl(data.unrealized_pnl);
|
||||
}
|
||||
if(typeof data.total !== "undefined" && data.total !== null){
|
||||
setFundsFieldText("stat-total", String(data.total));
|
||||
}
|
||||
if(typeof data.rate !== "undefined" && data.rate !== null){
|
||||
setFundsFieldText("stat-rate", `${Number(data.rate)}%`);
|
||||
}
|
||||
if(typeof data.profit_loss_ratio !== "undefined"){
|
||||
setFundsFieldText(
|
||||
"stat-pl-ratio",
|
||||
data.profit_loss_ratio != null && data.profit_loss_ratio !== ""
|
||||
? String(data.profit_loss_ratio)
|
||||
: "—"
|
||||
);
|
||||
}
|
||||
if(typeof data.available_trading_usdt !== "undefined" && data.available_trading_usdt !== null){
|
||||
latestAvailableUsdt = Number(data.available_trading_usdt);
|
||||
}
|
||||
|
||||
@@ -1659,6 +1659,20 @@ function applyAccountSnapshot(data){
|
||||
if(typeof data.unrealized_pnl !== "undefined"){
|
||||
updateRealtimePnl(data.unrealized_pnl);
|
||||
}
|
||||
if(typeof data.total !== "undefined" && data.total !== null){
|
||||
setFundsFieldText("stat-total", String(data.total));
|
||||
}
|
||||
if(typeof data.rate !== "undefined" && data.rate !== null){
|
||||
setFundsFieldText("stat-rate", `${Number(data.rate)}%`);
|
||||
}
|
||||
if(typeof data.profit_loss_ratio !== "undefined"){
|
||||
setFundsFieldText(
|
||||
"stat-pl-ratio",
|
||||
data.profit_loss_ratio != null && data.profit_loss_ratio !== ""
|
||||
? String(data.profit_loss_ratio)
|
||||
: "—"
|
||||
);
|
||||
}
|
||||
if(typeof data.available_trading_usdt !== "undefined" && data.available_trading_usdt !== null){
|
||||
latestAvailableUsdt = Number(data.available_trading_usdt);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,14 @@ def test_embed_shell_trade_summary_only():
|
||||
assert plan.records_rows is False
|
||||
|
||||
|
||||
def test_embed_shell_settings_still_loads_header_summary():
|
||||
plan = embed_render_plan("settings", "shell")
|
||||
assert plan.records_summary is True
|
||||
assert plan.records_rows is False
|
||||
plan_risk = embed_render_plan("risk_policy", "shell")
|
||||
assert plan_risk.records_summary is True
|
||||
|
||||
|
||||
def test_embed_records_page_loads_rows():
|
||||
plan = embed_render_plan("records", "fragment")
|
||||
assert plan.records_rows is True
|
||||
|
||||
Reference in New Issue
Block a user