fix真盈亏只认历史币盈亏不再另扣费,刷新按固定量价重算;修模拟到期币盈亏。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+69
-28
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user