fix真盈亏只认历史币盈亏不再另扣费,刷新按固定量价重算;修模拟到期币盈亏。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-10-13 11:30:07 +08:00
parent aa8b16ce27
commit dd979d9dd0
7 changed files with 278 additions and 128 deletions
+69 -28
View File
@@ -790,47 +790,88 @@ class SimBroker:
prem_ccy = _premium_ccy_for_inst(inst_id)
# 币本位到期兑付用币数量: 实值/指数 × 张数 × 乘数
# 注意: option_expiry_pnl 的 intrinsic 是 U,减权利金时币本位不能直接用
if prem_ccy in ("ETH", "BTC") and float(spot) > 0:
settle_recv = round(
max(0.0, (intrinsic_u / float(spot)) * sheets * ct_mult),
8,
)
# 币盈亏 = 兑付币 − 仓位权利金币(与 options_trades.premium_paid 同口径)
pnl = round(float(settle_recv) - float(prem), 8)
else:
settle_recv = round(max(0.0, prem + pnl), 4)
pnl = round(float(pnl), 4)
conn = self.get_db()
try:
conn.execute("DELETE FROM sim_option_positions WHERE inst_id=?", (inst_id,))
try:
closed_at = _now()
open_ids = [
int(r["id"])
for r in conn.execute(
"SELECT id FROM options_trades WHERE inst_id=? AND status='open'",
(inst_id,),
).fetchall()
]
conn.execute(
open_rows = conn.execute(
"""
UPDATE options_trades
SET status = 'closed',
close_quote = ?,
premium_received = ?,
realized_pnl = ?,
closed_at = COALESCE(closed_at, ?),
signal_note = CASE
WHEN signal_note IS NULL OR TRIM(signal_note) = ''
THEN '到期结算'
ELSE signal_note
END
WHERE inst_id = ? AND status = 'open'
SELECT id, premium_paid, open_fee, close_fee
FROM options_trades
WHERE inst_id=? AND status='open'
""",
(
round(intrinsic_u, 6),
settle_recv,
round(pnl, 4),
closed_at,
inst_id,
),
)
(inst_id,),
).fetchall()
open_ids = [int(r["id"]) for r in open_rows]
total_paid = 0.0
for r in open_rows:
try:
total_paid += float(r["premium_paid"] or 0)
except (TypeError, ValueError):
pass
n_open = len(open_rows) or 1
for r in open_rows:
paid_i = 0.0
try:
paid_i = float(r["premium_paid"] or 0)
except (TypeError, ValueError):
paid_i = 0.0
ofee_i = 0.0
try:
ofee_i = abs(float(r["open_fee"] or 0))
except (TypeError, ValueError):
ofee_i = 0.0
# 多笔开仓按权利金占比拆兑付;单笔拿全部
if n_open == 1:
recv_i = float(settle_recv)
elif total_paid > 1e-12:
recv_i = float(settle_recv) * (paid_i / total_paid)
else:
recv_i = float(settle_recv) / float(n_open)
if prem_ccy in ("ETH", "BTC"):
recv_i = round(recv_i, 8)
pnl_i = round(recv_i - paid_i - ofee_i, 8)
else:
recv_i = round(recv_i, 4)
pnl_i = round(recv_i - paid_i - ofee_i, 4)
conn.execute(
"""
UPDATE options_trades
SET status = 'closed',
close_quote = ?,
premium_received = ?,
realized_pnl = ?,
close_index_px = COALESCE(close_index_px, ?),
closed_at = COALESCE(closed_at, ?),
signal_note = CASE
WHEN signal_note IS NULL OR TRIM(signal_note) = ''
THEN '到期结算'
ELSE signal_note
END
WHERE id = ? AND status = 'open'
""",
(
round(intrinsic_u, 6),
recv_i,
pnl_i,
float(spot),
closed_at,
int(r["id"]),
),
)
if open_ids:
from lib.options.options_notify_lib import (
active_options_notify_cfg,