Align options realtime PnL with bid-net and show totals in stats.
Header float PnL now uses bid recycle minus premium like position cards. Stats adds realized/open/total net PnL. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -81,6 +81,52 @@ def forget_close_gate_for_inst(inst_id: str) -> None:
|
||||
clear_close_gate(inst_id)
|
||||
|
||||
|
||||
def net_pnl_from_display_row(row: dict[str, Any]) -> float | None:
|
||||
"""与持仓卡「净盈亏」同口径:买一可回收 − 权利金;残档买一则无净值."""
|
||||
preview = row.get("close_preview") if isinstance(row.get("close_preview"), dict) else {}
|
||||
if preview.get("bid_invalid"):
|
||||
return None
|
||||
net = preview.get("estimated_pnl")
|
||||
if net is not None:
|
||||
try:
|
||||
return float(net)
|
||||
except (TypeError, ValueError):
|
||||
pass
|
||||
recv = _safe_float(preview.get("total_received"))
|
||||
paid = _safe_float(row.get("premium_paid"))
|
||||
if recv is not None and paid is not None:
|
||||
return round(recv - paid, 4)
|
||||
return None
|
||||
|
||||
|
||||
def sum_options_net_pnl_usdc(
|
||||
cfg: dict[str, Any],
|
||||
ex: Any,
|
||||
raw_positions: list[dict[str, Any]] | None = None,
|
||||
) -> float | None:
|
||||
"""
|
||||
期权浮盈合计(USDC),与顶栏实时盈亏/中控口径对齐为「净盈亏」:
|
||||
各仓买一可回收 − 权利金之和.获取失败返回 None;无持仓返回 0.
|
||||
"""
|
||||
raw = raw_positions
|
||||
if raw is None:
|
||||
raw = cfg["fetch_option_positions"](ex)
|
||||
if raw is None:
|
||||
return None
|
||||
if not raw:
|
||||
return 0.0
|
||||
positions = build_display_option_positions(cfg, ex, raw)
|
||||
total = 0.0
|
||||
found = False
|
||||
for p in positions:
|
||||
net = net_pnl_from_display_row(p)
|
||||
if net is None:
|
||||
continue
|
||||
found = True
|
||||
total += float(net)
|
||||
return round(total, 4) if found else (0.0 if not positions else None)
|
||||
|
||||
|
||||
def build_display_option_positions(
|
||||
cfg: dict[str, Any],
|
||||
ex: Any,
|
||||
|
||||
Reference in New Issue
Block a user