diff --git a/scripts/repair_options_dual_pnl.py b/scripts/repair_options_dual_pnl.py index 355fed0..5b7f0a3 100644 --- a/scripts/repair_options_dual_pnl.py +++ b/scripts/repair_options_dual_pnl.py @@ -97,7 +97,7 @@ def repair(conn: sqlite3.Connection, *, apply: bool) -> list[dict[str, Any]]: and settled_u < 0 ) - # 桥侧:coin_sold ≈ premium 且远小于 recv → 未卖盈利币 + # 桥侧:coin_sold ≈ premium 且远小于 recv → 历史上曾按权利金封顶卖 bridge_hint = "" bid = r["bridge_id"] coin_bought = coin_sold = None @@ -118,18 +118,44 @@ def repair(conn: sqlite3.Connection, *, apply: bool) -> list[dict[str, Any]]: and recv > paid * 1.2 ): bridge_hint = "sell_capped_at_premium" - suspicious = True except Exception: pass action = "ok" new_settled_u = settled_u new_pnl_settled = 1 if settled else 0 - if suspicious: - # 无法可靠重建 after 时解除错误冻结,待卖回后重结算 + + # A 已为正且与口径 B 接近 → 视为已恢复,勿因桥历史反复 unsettle + a_ok_near_b = ( + settled_u is not None + and settled_u > 0 + and stats_u is not None + and stats_u > 0 + and abs(settled_u - stats_u) / max(abs(stats_u), 1.0) <= 0.15 + ) + + if suspicious and not a_ok_near_b: + # 负冻结且无法对上 B:解除错误冻结 action = "unsettle_bad_account_freeze" new_pnl_settled = 0 new_settled_u = None + elif ( + (not settled or suspicious) + and bridge_hint == "sell_capped_at_premium" + and coin_pnl is not None + and coin_pnl > 0 + and stats_u is not None + and stats_u > 0 + and (settled_u is None or settled_u < 0 or a_ok_near_b) + ): + # 桥记录不可信时:优先保留已接近 B 的正 A,否则用口径 B 回填复盘 + if a_ok_near_b: + action = "accept_recovered_account_A" + new_settled_u = round(float(settled_u), 4) + else: + action = "backfill_A_from_stats_B" + new_settled_u = round(float(stats_u), 4) + new_pnl_settled = 1 elif before is not None and after is not None and not settled: action = "settle_from_snapshots" new_settled_u = round(after - before, 4) @@ -174,16 +200,20 @@ def repair(conn: sqlite3.Connection, *, apply: bool) -> list[dict[str, Any]]: """ UPDATE options_trades SET pnl_settled=0, realized_pnl_usdt=NULL, trading_usdt_after=NULL - WHERE id=? AND COALESCE(pnl_settled,0)=1 + WHERE id=? """, (tid,), ) - elif action == "settle_from_snapshots" and new_settled_u is not None: + elif action in ( + "settle_from_snapshots", + "accept_recovered_account_A", + "backfill_A_from_stats_B", + ) and new_settled_u is not None: conn.execute( """ UPDATE options_trades SET realized_pnl_usdt=?, pnl_settled=1 - WHERE id=? AND COALESCE(pnl_settled,0)=0 + WHERE id=? """, (new_settled_u, tid), )