From fe08fa527098546f7a01fc355e0b50dfb5a3e880 Mon Sep 17 00:00:00 2001 From: dekun Date: Tue, 13 Oct 2026 09:18:03 +0800 Subject: [PATCH] =?UTF-8?q?fix=E5=8E=86=E5=8F=B2=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E8=84=9A=E6=9C=AC:=E6=A1=A5=E5=B0=81=E9=A1=B6=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=E4=B8=8D=E5=86=8D=E5=8F=8D=E5=A4=8D=E6=B8=85=E7=A9=BA?= =?UTF-8?q?=E5=B7=B2=E6=81=A2=E5=A4=8D=E7=9A=84=E6=AD=A3=E7=9B=88=E4=BA=8F?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 当账户A已与统计B接近时接受A;否则用口径B回填复盘冻结。 Co-authored-by: Cursor --- scripts/repair_options_dual_pnl.py | 44 +++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 7 deletions(-) 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), )