fix期权复盘与数据统计双口径盈亏,并修复卖回封顶导致盈利单冻成亏损。

平仓卖光可卖币后再按账户差分结算复盘;数据统计改为历史币盈亏×卖回价;复盘展示初始权利金与盈利率,并附历史修复脚本。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-10-13 09:10:13 +08:00
parent d4de6a23ae
commit 9d77a430e5
16 changed files with 2858 additions and 2242 deletions
+23 -7
View File
@@ -610,6 +610,14 @@ def _insert_coin_trade(conn: Any, **kwargs: Any) -> int:
tusdt_before = float(tusdt_before) if tusdt_before is not None else None
except (TypeError, ValueError):
tusdt_before = None
paid = kwargs.get("premium_paid")
try:
paid_f = float(paid) if paid is not None else None
except (TypeError, ValueError):
paid_f = None
initial_premium_usdt = None
if open_index_px is not None and paid_f is not None and paid_f > 0:
initial_premium_usdt = round(float(open_index_px) * float(paid_f), 4)
cur = conn.execute(
"""
INSERT INTO options_trades(
@@ -617,8 +625,9 @@ def _insert_coin_trade(conn: Any, **kwargs: Any) -> int:
open_quote, premium_paid, status, signal_note, exchange_ord_id,
margin_mode, premium_ccy, bridge_id, budget_usdt,
open_fee, fee_ccy, open_index_px, trading_usdt_before, pnl_settled,
initial_premium_usdt,
profit_exit_enabled, profit_exit_mult, profit_exit_state, created_at
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 'open', ?, ?, 'coin', ?, ?, ?, ?, ?, ?, ?, 0, ?, ?, ?, ?)
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 'open', ?, ?, 'coin', ?, ?, ?, ?, ?, ?, ?, 0, ?, ?, ?, ?, ?)
""",
(
kwargs["inst_id"],
@@ -639,6 +648,7 @@ def _insert_coin_trade(conn: Any, **kwargs: Any) -> int:
fee_ccy,
open_index_px,
tusdt_before,
initial_premium_usdt,
pe,
pe_mult,
pe_state,
@@ -685,17 +695,20 @@ def maybe_sell_spot_after_close(
underlying=underlying,
inst_id=inst_id,
)
# 卖回成功:交易账户 after − 开仓 before → 冻结本单盈亏
# 卖回完成(sell_complete):交易账户 after − 开仓 before → 冻结本单盈亏
try:
from lib.options.options_account_pnl_lib import try_settle_after_sellback
if (result or {}).get("ok"):
bid = (result or {}).get("bridge_id")
res = result or {}
if res.get("ok") and res.get("sell_complete", True) and not res.get("incomplete"):
bid = res.get("bridge_id")
try_settle_after_sellback(
cfg["get_db"],
ex,
bridge_id=int(bid) if bid is not None else None,
cfg=cfg,
underlying=underlying,
sell_complete=True,
)
except Exception:
pass
@@ -766,20 +779,23 @@ def sweep_spot_after_options_flat(
underlying=uly,
inst_id=None,
)
if (out or {}).get("ok"):
out = out or {}
if out.get("ok") and out.get("sell_complete", True) and not out.get("incomplete"):
try:
from lib.options.options_account_pnl_lib import try_settle_after_sellback
bid = (out or {}).get("bridge_id")
bid = out.get("bridge_id")
try_settle_after_sellback(
cfg["get_db"],
exchange,
bridge_id=int(bid) if bid is not None else None,
cfg=cfg,
underlying=uly,
sell_complete=True,
)
except Exception:
pass
sold.append({"underlying": uly, **(out or {})})
sold.append({"underlying": uly, **out})
except Exception as e:
sold.append({"underlying": uly, "ok": False, "msg": str(e)})
return {"ok": True, "results": sold, "skipped": not sold}