Fix hub options float summary blank when bid book is invalid.

Stop treating total_received=0 as a real bid recycle, fall back to exchange upl for display totals, and keep row/summary aligned.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-08-07 09:47:14 +08:00
parent d41028b766
commit 4bc238b014
12 changed files with 182 additions and 48 deletions
+5 -5
View File
@@ -66,17 +66,17 @@ def build_options_hub_snapshot(cfg: dict[str, Any]) -> dict[str, Any]:
conn.close()
except Exception:
target_monitors = []
from lib.options.options_positions_lib import net_pnl_from_display_row
from lib.options.options_positions_lib import display_pnl_from_option_row
upl_total = 0.0
has_upl = False
for p in positions:
# 与持仓卡「净盈亏」一致(买一回收−权利金);不用交易所标记价 upl
net = net_pnl_from_display_row(p)
if net is None:
# 与持仓卡展示一致:优先买一净盈亏,残档回退交易所 upl
pnl = display_pnl_from_option_row(p)
if pnl is None:
continue
has_upl = True
upl_total += float(net)
upl_total += float(pnl)
bal = cfg["fetch_options_balances"](ex)
return {
"ok": True,
+19 -5
View File
@@ -92,13 +92,26 @@ def net_pnl_from_display_row(row: dict[str, Any]) -> float | None:
return float(net)
except (TypeError, ValueError):
pass
# 仅当实际吃到买盘张数时,才用 total_received 权利金(避免 bid 无效时 total_received=0 算出 −权利金假亏)
try:
covered = float(preview.get("covered_sheets") or 0)
except (TypeError, ValueError):
covered = 0.0
recv = _safe_float(preview.get("total_received"))
paid = _safe_float(row.get("premium_paid"))
if recv is not None and paid is not None:
if covered > 0 and recv is not None and paid is not None:
return round(recv - paid, 4)
return None
def display_pnl_from_option_row(row: dict[str, Any]) -> float | None:
"""展示用盈亏:优先买一净盈亏;残档/无买一时回退交易所标记浮盈 upl."""
net = net_pnl_from_display_row(row)
if net is not None:
return net
return _safe_float(row.get("upl"))
def sum_options_net_pnl_usdc(
cfg: dict[str, Any],
ex: Any,
@@ -106,7 +119,8 @@ def sum_options_net_pnl_usdc(
) -> float | None:
"""
期权浮盈合计(USDC),与顶栏实时盈亏/中控口径对齐为「净盈亏」:
各仓买一可回收 权利金之和.获取失败返回 None;无持仓返回 0.
各仓买一可回收 权利金之和;残档则回退该仓交易所 upl.
获取失败返回 None;无持仓返回 0.
"""
raw = raw_positions
if raw is None:
@@ -119,11 +133,11 @@ def sum_options_net_pnl_usdc(
total = 0.0
found = False
for p in positions:
net = net_pnl_from_display_row(p)
if net is None:
pnl = display_pnl_from_option_row(p)
if pnl is None:
continue
found = True
total += float(net)
total += float(pnl)
return round(total, 4) if found else (0.0 if not positions else None)
+1 -1
View File
@@ -324,4 +324,4 @@
</div>
</div>
<script src="/static/options_expiry_countdown.js?v=1"></script>
<script src="/static/options_panel.js?v=52"></script>
<script src="/static/options_panel.js?v=53"></script>