Anchor semi exit to strike +/- move points; side-by-side semi cards.

Forward target is K+/-N not spot+/-N; UI shows option target and perp net lock.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-08-08 14:59:48 +08:00
parent 6f983ed2ab
commit 4f56eff40c
8 changed files with 162 additions and 70 deletions
+20 -14
View File
@@ -201,17 +201,18 @@ class SemiExitDecision:
def check_semi_exits(
*,
net_pnl: float,
entry_index: float | None,
strike: float | None,
index_px: float | None,
view_side: str,
option_move_points: float,
perp_exit_unit: float,
risk_k: float = 1.0,
entry_index: float | None = None,
) -> SemiExitDecision:
"""
顺方向:标的波动达到目标点 且 组合净利>0 → 全平。
逆方向兑现:组合净利 ≥ 永续出场基数×k → 全平
流动性在 close_group 内再验;平仓顺序已是先期权后永续
顺方向:指数到达「行权价 ± 波动点」且组合净利>0 → 全平。
多/Call:目标 = K + N;空/Put:目标 = K − N(N 为设置的波动点,不是现价±N)
逆方向兑现(永续锁定净利):组合净利 ≥ 净利基数×k → 全平
"""
view = (view_side or "long").strip().lower()
if view not in ("long", "short"):
@@ -221,34 +222,39 @@ def check_semi_exits(
net_tgt = max(0.0, float(perp_exit_unit)) * k
net = float(net_pnl)
# 逆方向 / 对冲兑现:净利达标即可离场(不必等点位)
# 逆方向 / 永续净利锁定:达标即可离场(不必等点位)
if net_tgt > 0 and net + 1e-9 >= net_tgt:
return SemiExitDecision(
True,
REASON_PERP_NET,
f"半自动·净利{net_tgt:.2f}U(基数×k",
f"半自动·永续净利锁定{net_tgt:.2f}U(基数×k",
net_target=net_tgt,
)
if entry_index is None or index_px is None:
if index_px is None:
return SemiExitDecision(False, "", "缺指数")
entry = float(entry_index)
idx = float(index_px)
if entry <= 0 or idx <= 0 or move <= 0:
# 锚定行权价;无 strike 时才回退开仓指数(兼容旧仓)
anchor = None
if strike is not None and float(strike) > 0:
anchor = float(strike)
elif entry_index is not None and float(entry_index) > 0:
anchor = float(entry_index)
if anchor is None or idx <= 0 or move <= 0:
return SemiExitDecision(False, "", "点位无效")
if view == "long":
target_idx = entry + move
target_idx = anchor + move
hit = idx + 1e-9 >= target_idx
else:
target_idx = entry - move
target_idx = anchor - move
hit = idx - 1e-9 <= target_idx
if hit and net > 0:
return SemiExitDecision(
True,
REASON_POINTS,
f"半自动·标的到{target_idx:.2f}组合净利>0",
f"半自动·指数到期权目{target_idx:.2f}K{anchor:g}±{move:g}且净利>0",
target_index=target_idx,
net_target=0.0,
)
@@ -256,13 +262,13 @@ def check_semi_exits(
return SemiExitDecision(
False,
"",
f"已到点位{target_idx:.2f}但组合净利≤0{net:.2f}),继续持有",
f"已到期权目标{target_idx:.2f}但组合净利≤0{net:.2f}),继续持有",
target_index=target_idx,
)
return SemiExitDecision(
False,
"",
f"未到点位(目标{target_idx:.2f}",
f"未到期权目标(K{anchor:g}{target_idx:.2f}",
target_index=target_idx,
net_target=net_tgt,
)