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
+15
View File
@@ -5,6 +5,21 @@ from __future__ import annotations
from app.strategy.exits import check_exits, resolve_exit_target
def test_locked_premium_mode_keeps_premium_reason() -> None:
"""锁定目标金额后,平仓原因仍应按权利金倍数模式标记,而非写死 fixed_usdt。"""
d = check_exits(
net_pnl=25.0,
exit_mode="premium_multiple",
net_profit_target=15.0,
premium_exit_multiple=1.0,
initial_premium=20.0,
locked_exit_target=20.0,
)
assert d.should_close is True
assert d.target == 20.0
assert d.reason == "premium_multiple"
def test_locked_target_ignores_setting_drift() -> None:
d = check_exits(
net_pnl=20.0,
+8 -8
View File
@@ -45,14 +45,14 @@ class _FakeClient:
return -1.5
def test_enrich_live_unrealized_entry_fee_times_two() -> None:
def test_enrich_live_unrealized_keeps_book_net_plus_funding() -> None:
base = {
"has_position": True,
"group_id": "G1",
"perp_side": "short",
"perp_upl": 1.0,
"option_upl": 5.0,
"est_close_fees": 9.9,
"est_close_fees": 0.8,
"net_pnl": -3.9,
}
@@ -69,12 +69,12 @@ def test_enrich_live_unrealized_entry_fee_times_two() -> None:
perp_side="short",
open_at_ms=1,
)
assert out["perp_upl"] == 8.0
assert out["perp_upl"] == 1.0 # 盘口可平
assert out["perp_upl_exchange"] == 8.0
assert out["option_upl"] == 5.0
assert out["fees_paid"] == 0.5
assert out["funding_usdt"] == -1.5
# 离场费按入场估算
assert out["est_close_fees"] == 0.5
# 8 + 5 - 0.5*2 + (-1.5) = 10.5
assert abs(out["net_pnl"] - 10.5) < 1e-9
assert out["pnl_source"] == "live_exchange"
assert out["est_close_fees"] == 0.8
# 盯盘净利 = 盘口净利 + 资金费,不用标记 UPL 覆盖
assert abs(out["net_pnl"] - (-3.9 - 1.5)) < 1e-9
assert out["pnl_source"] == "live_book_plus_funding"