统计已实现盈亏扣手续费,并按平仓时指数冻结为 U。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-10-08 22:50:21 +08:00
parent e8f8a76753
commit 5e8b578f75
12 changed files with 726 additions and 54 deletions
+61 -5
View File
@@ -187,7 +187,8 @@ def backfill_closed_options_realized_pnl_from_history(
rows = conn.execute(
"""
SELECT id, inst_id, sheets, premium_paid, realized_pnl, close_quote,
created_at, closed_at, close_ord_id
created_at, closed_at, close_ord_id, realized_pnl_usdt,
open_fee, close_fee, premium_ccy, underlying
FROM options_trades
WHERE status = 'closed'
ORDER BY id DESC
@@ -198,8 +199,13 @@ 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
groups: dict[str, list[Any]] = {}
for row in rows:
# 已冻结 U 的本地结算不再被交易所历史覆盖
if _safe_float(row["realized_pnl_usdt"]) is not None:
continue
inst = str(row["inst_id"] or "").strip()
if not inst or inst not in by_inst:
continue
@@ -233,6 +239,8 @@ def backfill_closed_options_realized_pnl_from_history(
total_paid = 0.0
for r in group:
total_paid += float(_safe_float(r["premium_paid"]) or 0.0)
underly = str(group[0]["underlying"] or "").strip()
close_idx = resolve_close_index_px(None, inst_id=inst, underlying=underly)
allocated = 0.0
for i, r in enumerate(group):
paid = float(_safe_float(r["premium_paid"]) or 0.0)
@@ -255,16 +263,37 @@ def backfill_closed_options_realized_pnl_from_history(
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)
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,
premium_ccy=prem_ccy,
index_px=close_idx,
)
conn.execute(
"""
UPDATE options_trades
SET realized_pnl = ?,
premium_received = ?,
close_quote = COALESCE(?, close_quote),
close_ord_id = COALESCE(?, close_ord_id)
WHERE id = ?
close_ord_id = COALESCE(?, close_ord_id),
close_index_px = COALESCE(?, close_index_px),
realized_pnl_usdt = COALESCE(?, realized_pnl_usdt)
WHERE id = ? AND realized_pnl_usdt IS NULL
""",
(share, prem_recv, close_quote, matched_pos, int(r["id"])),
(
settled.get("realized_pnl"),
prem_recv,
close_quote,
matched_pos,
settled.get("close_index_px"),
settled.get("realized_pnl_usdt"),
int(r["id"]),
),
)
updated += 1
return updated
@@ -283,7 +312,8 @@ def sync_open_options_trades(
"""
rows = conn.execute(
"""
SELECT id, inst_id, premium_paid, exp_time, created_at
SELECT id, inst_id, premium_paid, exp_time, created_at,
open_fee, premium_ccy, underlying, exchange_ord_id
FROM options_trades
WHERE status = 'open'
"""
@@ -291,6 +321,8 @@ 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
for row in rows:
inst_id = str(row["inst_id"] or "")
if not inst_id or inst_id in live_inst_ids:
@@ -331,6 +363,24 @@ def sync_open_options_trades(
if not closed_at:
closed_at = options_app_now_str()
open_fee = float(_safe_float(row["open_fee"]) or 0.0)
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,
)
realized_pnl = settled.get("realized_pnl")
pnl_usdt = settled.get("realized_pnl_usdt")
conn.execute(
"""
UPDATE options_trades
@@ -340,6 +390,9 @@ def sync_open_options_trades(
realized_pnl = ?,
close_ord_id = COALESCE(?, close_ord_id),
closed_at = COALESCE(?, closed_at),
close_index_px = COALESCE(?, close_index_px),
realized_pnl_usdt = COALESCE(?, realized_pnl_usdt),
fee_ccy = COALESCE(fee_ccy, ?),
signal_note = CASE
WHEN ? = 'expired' AND (signal_note IS NULL OR TRIM(signal_note) = '')
THEN '到期结算'
@@ -353,6 +406,9 @@ def sync_open_options_trades(
realized_pnl,
close_ord_id,
closed_at,
settled.get("close_index_px"),
pnl_usdt,
prem_ccy,
close_reason,
int(row["id"]),
),