修复已实现盈亏重复扣手续费,并自动纠正偏亏冻结值。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-10-08 23:03:31 +08:00
parent 5e8b578f75
commit 2369aae362
4 changed files with 258 additions and 84 deletions
+37 -23
View File
@@ -199,7 +199,10 @@ def backfill_closed_options_realized_pnl_from_history(
if not rows:
return 0
from lib.options.options_pnl_settle_lib import resolve_close_index_px, settle_closed_pnl
from lib.options.options_pnl_settle_lib import (
resolve_close_index_px,
settle_exchange_realized_pnl,
)
groups: dict[str, list[Any]] = {}
for row in rows:
@@ -262,18 +265,17 @@ def backfill_closed_options_realized_pnl_from_history(
ord_ok = (not matched_pos) or (local_ord == matched_pos)
if pnl_ok and quote_ok and ord_ok:
continue
prem_recv = round(paid + share, 4)
ofee = float(_safe_float(r["open_fee"]) or 0.0)
cfee = float(_safe_float(r["close_fee"]) or 0.0)
# OKX realizedPnl 已含手续费,只冻结折 U,禁止再减 open_fee/close_fee
prem_ccy = str(r["premium_ccy"] or "").strip() or "ETH"
settled = settle_closed_pnl(
premium_paid=paid,
premium_received=prem_recv,
open_fee=ofee,
close_fee=cfee,
settled = settle_exchange_realized_pnl(
realized_pnl=share,
premium_ccy=prem_ccy,
index_px=close_idx,
)
# 展示用收回≈已付+净盈亏+已记手续费(毛额近似,不参与再扣费)
ofee = float(_safe_float(r["open_fee"]) or 0.0)
cfee = float(_safe_float(r["close_fee"]) or 0.0)
prem_recv = round(paid + share + ofee + cfee, 4)
conn.execute(
"""
UPDATE options_trades
@@ -321,7 +323,11 @@ def sync_open_options_trades(
updated = 0
closed_inst_ids: list[str] = []
now_ms = int(time.time() * 1000)
from lib.options.options_pnl_settle_lib import resolve_close_index_px, settle_closed_pnl
from lib.options.options_pnl_settle_lib import (
resolve_close_index_px,
settle_closed_pnl,
settle_exchange_realized_pnl,
)
for row in rows:
inst_id = str(row["inst_id"] or "")
@@ -345,8 +351,6 @@ def sync_open_options_trades(
close_quote = close_info.get("close_quote")
realized_pnl = close_info.get("realized_pnl")
close_ord_id = close_info.get("pos_id")
if realized_pnl is not None:
prem_recv = round(paid + float(realized_pnl), 4)
close_ms = close_info.get("close_ms")
if close_ms:
closed_at = ms_to_options_app_str(close_ms)
@@ -367,17 +371,27 @@ def sync_open_options_trades(
prem_ccy = str(row["premium_ccy"] or "").strip() or "ETH"
underly = str(row["underlying"] or "").strip()
close_idx = resolve_close_index_px(None, inst_id=inst_id, underlying=underly)
# 交易所 pnl 多为权利金差;再扣本地开仓费后冻结(平仓费此处无单号,记 0)
if prem_recv is None and realized_pnl is not None:
prem_recv = round(paid + float(realized_pnl), 4)
settled = settle_closed_pnl(
premium_paid=paid,
premium_received=prem_recv if prem_recv is not None else (paid + float(realized_pnl or 0)),
open_fee=open_fee,
close_fee=0,
premium_ccy=prem_ccy,
index_px=close_idx,
)
if close_reason == "exchange" and realized_pnl is not None:
# OKX realizedPnl 已含费,禁止再减 open_fee
settled = settle_exchange_realized_pnl(
realized_pnl=realized_pnl,
premium_ccy=prem_ccy,
index_px=close_idx,
fee_hint=open_fee,
)
prem_recv = round(paid + float(realized_pnl) + open_fee, 4)
else:
# 到期归零:本地权利金口径,只扣一次开仓费
if prem_recv is None:
prem_recv = 0.0
settled = settle_closed_pnl(
premium_paid=paid,
premium_received=prem_recv,
open_fee=open_fee,
close_fee=0,
premium_ccy=prem_ccy,
index_px=close_idx,
)
realized_pnl = settled.get("realized_pnl")
pnl_usdt = settled.get("realized_pnl_usdt")