统计已实现盈亏扣手续费,并按平仓时指数冻结为 U。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -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"]),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user