中控期权浮盈只显示U;总浮盈亏按指数把币本位浮盈计入USDT

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-08-20 18:13:39 +08:00
parent 467f4f092f
commit 1ddfe3f72e
4 changed files with 136 additions and 14 deletions
+66 -9
View File
@@ -74,21 +74,50 @@ def options_balances_usdt_equiv(options_snap: dict[str, Any] | None) -> dict[str
def options_float_pnl_usdt(options_snap: dict[str, Any] | None) -> Optional[float]:
"""期权浮盈合计(USDT).币本位按指数换算,勿把 ETH/BTC 数量当 U."""
snap = options_snap if isinstance(options_snap, dict) else {}
if snap.get("enabled") is False or snap.get("ok") is False:
return None
upl = snap.get("upl_total_usdc")
if upl is not None:
def _safe(v: Any) -> float | None:
if v is None or v == "":
return None
try:
return round(float(upl), 4)
return float(v)
except (TypeError, ValueError):
pass
# 快照偶发缺合计时,按持仓行回退汇总(与卡片展示一致)
return None
def _index_px() -> float | None:
px = _safe(snap.get("options_index_px") or snap.get("index_px"))
if px is not None and px > 0:
return px
for p in snap.get("positions") or []:
if not isinstance(p, dict):
continue
px = _safe(p.get("idx_px") or p.get("idxPx"))
if px is not None and px > 0:
return px
return None
def _row_is_coin(p: dict[str, Any]) -> bool:
ccy = str(p.get("premium_ccy") or "").strip().upper()
if ccy in ("ETH", "BTC"):
return True
if str(p.get("margin_mode") or "").strip().lower() == "coin":
return True
mid = str(p.get("inst_id") or "")
return "-USD-" in mid.upper() and "_UM" not in mid.upper()
mode = str(snap.get("options_margin_mode") or snap.get("margin_mode") or "").strip().lower()
snap_coin = mode == "coin"
idx = _index_px()
try:
from lib.options.options_positions_lib import display_pnl_from_option_row
total = 0.0
total_u = 0.0
found = False
missing_fx = False
for p in snap.get("positions") or []:
if not isinstance(p, dict):
continue
@@ -96,10 +125,38 @@ def options_float_pnl_usdt(options_snap: dict[str, Any] | None) -> Optional[floa
if pnl is None:
continue
found = True
total += float(pnl)
return round(total, 4) if found else None
if snap_coin or _row_is_coin(p):
px = _safe(p.get("idx_px") or p.get("idxPx"))
if px is None or px <= 0:
px = idx
if px is None or px <= 0:
missing_fx = True
continue
total_u += float(pnl) * float(px)
else:
total_u += float(pnl)
if found and not missing_fx:
return round(total_u, 4)
if found and missing_fx and abs(total_u) > 1e-12:
# 部分腿已换算成功时仍返回可得合计
return round(total_u, 4)
except Exception:
return None
pass
upl = snap.get("upl_total_usdc")
if upl is not None:
try:
raw = float(upl)
except (TypeError, ValueError):
return None
if snap_coin or any(
isinstance(p, dict) and _row_is_coin(p) for p in (snap.get("positions") or [])
):
if idx is None or idx <= 0:
return None
return round(raw * float(idx), 4)
return round(raw, 4)
return None
def options_open_position_count(options_snap: dict[str, Any] | None) -> int: