Fix TP/SL exit classification when exchange fill slips past the tight band.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,8 +1,67 @@
|
||||
"""交易结果展示与入库时的语义归一化."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Optional
|
||||
|
||||
_WIN_EPS = 1e-9
|
||||
|
||||
|
||||
def classify_exit_by_levels(
|
||||
direction,
|
||||
trigger_price,
|
||||
stop_loss,
|
||||
take_profit,
|
||||
exit_price,
|
||||
) -> Optional[str]:
|
||||
"""根据成交价相对止盈/止损位归类;无法可靠归类时返回 None.
|
||||
|
||||
交易所条件止盈常按标记价触发、市价成交,成交价可能偏离计划止盈数个 tick.
|
||||
因此先用窄带,失败后再用宽带;仍失败则看是否落在入场→止盈/止损的「盈利/亏损侧」。
|
||||
"""
|
||||
try:
|
||||
tp = float(take_profit)
|
||||
sl = float(stop_loss)
|
||||
ex = float(exit_price)
|
||||
trig = float(trigger_price)
|
||||
except (TypeError, ValueError):
|
||||
return None
|
||||
d = (direction or "").strip().lower()
|
||||
if d not in ("long", "short"):
|
||||
return None
|
||||
band = max(abs(trig) * 0.0008, abs(tp - sl) * 0.003, 1e-12)
|
||||
# 宽带:覆盖 BTC 等高价币种条件单滑点(实测 Gate 止盈成交可偏出窄带 ~100U)
|
||||
band_loose = max(abs(trig) * 0.003, abs(tp - sl) * 0.05, band * 4.0, 1e-12)
|
||||
|
||||
def _is_tp(b: float) -> bool:
|
||||
return ex >= tp - b if d == "long" else ex <= tp + b
|
||||
|
||||
def _is_sl(b: float) -> bool:
|
||||
return ex <= sl + b if d == "long" else ex >= sl - b
|
||||
|
||||
if _is_tp(band):
|
||||
return "止盈"
|
||||
if _is_sl(band):
|
||||
return "止损"
|
||||
if _is_tp(band_loose):
|
||||
return "止盈"
|
||||
if _is_sl(band_loose):
|
||||
return "止损"
|
||||
|
||||
# 盈利侧且更靠近止盈 → 止盈; 亏损侧且更靠近止损 → 止损
|
||||
if d == "long":
|
||||
if ex > trig and abs(ex - tp) <= abs(ex - trig):
|
||||
return "止盈"
|
||||
if ex < trig and abs(ex - sl) <= abs(ex - trig):
|
||||
return "止损"
|
||||
else:
|
||||
if ex < trig and abs(ex - tp) <= abs(ex - trig):
|
||||
return "止盈"
|
||||
if ex > trig and abs(ex - sl) <= abs(ex - trig):
|
||||
return "止损"
|
||||
return None
|
||||
|
||||
|
||||
def normalize_display_result(result):
|
||||
"""展示用:外部平仓一律视为手动平仓."""
|
||||
res = (result or "").strip()
|
||||
|
||||
Reference in New Issue
Block a user