Fix target-exit mismatch: correct close reason and executable PnL gate.

Locked premium exits no longer label as fixed_usdt; mark/book optimism no longer triggers close into a realized loss.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-08-07 22:05:34 +08:00
parent a88d708ea3
commit bf3441537e
6 changed files with 74 additions and 31 deletions
+17 -9
View File
@@ -2233,13 +2233,19 @@ class Matcher:
est_opt_close_fee = of.fee
opt_mark = bid
opt_bid_sz = float(oq.bid_sz) if oq.bid_sz is not None else None
# 浮盈亏:买一×数量 − 初始权利金(对齐可市价卖出
option_upl = bid * opt_qty - initial_premium
# 与 close_group 一致:用含费率调整的可卖出价(勿用裸买一虚高触发达标
if opt_entry > 0:
option_upl = (float(of.fill_px) - float(opt_entry)) * opt_qty
else:
option_upl = float(of.fill_px) * opt_qty - initial_premium
elif oq:
opt_mark = oq.bid or oq.mark_px
opt_bid_sz = float(oq.bid_sz) if oq.bid_sz is not None else None
if opt_mark is not None:
option_upl = float(opt_mark) * opt_qty - initial_premium
if opt_entry > 0:
option_upl = (float(opt_mark) - float(opt_entry)) * opt_qty
else:
option_upl = float(opt_mark) * opt_qty - initial_premium
book_close_fees = est_perp_close_fee + est_opt_close_fee
@@ -2266,13 +2272,15 @@ class Matcher:
expiry_ymd = str(g["expiry_ymd"]) if g and g["expiry_ymd"] else None
open_at_ms = int(g["open_at_ms"]) if g and g["open_at_ms"] else None
open_fees = abs(float(g["fees"] or 0)) if g else 0.0
# 净盈利:浮盈 入场手续费×2(离场费按入场估算);无入场费时退回盘口估平仓费
if open_fees > 1e-12:
est_close_fees = open_fees
net_pnl = perp_upl + option_upl - open_fees * 2.0
# 净盈利:浮盈 已付开仓费 − 预估平仓费(与 close_group 入账口径对齐)
if book_close_fees > 1e-12 or open_fees > 1e-12:
est_close_fees = (
book_close_fees if book_close_fees > 1e-12 else open_fees
)
net_pnl = perp_upl + option_upl - open_fees - est_close_fees
else:
est_close_fees = book_close_fees
net_pnl = perp_upl + option_upl - est_close_fees
est_close_fees = 0.0
net_pnl = perp_upl + option_upl
expiry_ms = None
if expiry_ymd and len(expiry_ymd) == 6:
try: