From 857974070ef360615186d362a78ad0aa2ad6806f Mon Sep 17 00:00:00 2001 From: dekun Date: Thu, 20 Aug 2026 17:25:49 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A1=B6=E6=A0=8F=E5=AE=9E=E6=97=B6=E7=9B=88?= =?UTF-8?q?=E4=BA=8F=EF=BC=9A=E5=B8=81=E6=9C=AC=E4=BD=8D=E6=8C=89=20ETH/BT?= =?UTF-8?q?C=20=E6=8C=87=E6=95=B0=E6=8A=98=E7=AE=97=E4=B8=BA=20USDT?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cursor --- lib/exchange/okx_options_lib.py | 20 ++++++++++++++++---- lib/options/options_positions_lib.py | 21 ++++++++++++++++++--- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/lib/exchange/okx_options_lib.py b/lib/exchange/okx_options_lib.py index acd878d..4f86c3f 100644 --- a/lib/exchange/okx_options_lib.py +++ b/lib/exchange/okx_options_lib.py @@ -1617,9 +1617,9 @@ def resolve_option_close_from_history( def fetch_options_unrealized_pnl_usdc(ex: ccxt.okx) -> float | None: """ - 期权浮盈合计(USDC≈U). - 优先返回交易所标记价 upl;实例顶栏应改用 - `options_positions_lib.sum_options_net_pnl_usdc`(买一净盈亏)以与持仓卡一致. + 期权浮盈合计(USDT/USDC≈U). + 优先返回交易所标记价 upl;币本位 upl 按 idxPx 折 U. + 实例顶栏应改用 `options_positions_lib.sum_options_net_pnl_usdc`(买一净盈亏)以与持仓卡一致. """ positions = fetch_option_positions(ex) if positions is None: @@ -1630,8 +1630,20 @@ def fetch_options_unrealized_pnl_usdc(ex: ccxt.okx) -> float | None: upl = _safe_float(pos.get("upl")) if upl is None: continue + inst = str(pos.get("instId") or "") + # 币本位合约:upl 为币;折指数为 U + try: + from lib.options.options_margin_mode_lib import MODE_COIN, margin_mode_from_inst_id + + if margin_mode_from_inst_id(inst) == MODE_COIN: + idx = _safe_float(pos.get("idxPx")) + if idx is None or idx <= 0: + continue + upl = float(upl) * float(idx) + except Exception: + pass found = True - total += upl + total += float(upl) return round(total, 4) if found else None diff --git a/lib/options/options_positions_lib.py b/lib/options/options_positions_lib.py index a3d6a1d..6081933 100644 --- a/lib/options/options_positions_lib.py +++ b/lib/options/options_positions_lib.py @@ -118,14 +118,29 @@ def display_pnl_from_option_row(row: dict[str, Any]) -> float | None: return _safe_float(row.get("upl")) +def display_pnl_usdt_from_option_row(row: dict[str, Any]) -> float | None: + """顶栏「实时盈亏」用:币本位净盈亏按指数折 USDT;USDC 仓原样.""" + pnl = display_pnl_from_option_row(row) + if pnl is None: + return None + ccy = str(row.get("premium_ccy") or "USDC").strip().upper() or "USDC" + if ccy in ("ETH", "BTC"): + idx = _safe_float(row.get("idx_px") or row.get("idxPx") or row.get("index_px")) + if idx is None or idx <= 0: + # 无指数时无法折算,跳过该仓以免把「币数量」当成 U + return None + return float(pnl) * float(idx) + return float(pnl) + + def sum_options_net_pnl_usdc( cfg: dict[str, Any], ex: Any, raw_positions: list[dict[str, Any]] | None = None, ) -> float | None: """ - 期权浮盈合计(USDC),与顶栏实时盈亏/中控口径对齐为「净盈亏」: - 各仓买一可回收 − 权利金之和;残档则回退该仓交易所 upl. + 期权浮盈合计(USDT/USDC 口径),与顶栏实时盈亏对齐: + 各仓买一可回收 − 权利金;币本位再 × 指数折成 U;残档回退该仓 upl(同样折算). 获取失败返回 None;无持仓返回 0. """ raw = raw_positions @@ -139,7 +154,7 @@ def sum_options_net_pnl_usdc( total = 0.0 found = False for p in positions: - pnl = display_pnl_from_option_row(p) + pnl = display_pnl_usdt_from_option_row(p) if pnl is None: continue found = True