feat(position_manager): 优化止损与止盈逻辑,确保实际止损距离与盈亏比计算一致
在 `position_manager.py` 中更新了止损和止盈计算逻辑,确保使用实际止损距离进行盈亏比的计算,避免因保证金封顶导致的止盈不合理。同时,新增止盈上限配置,防止止盈距离过大。此改动提升了交易策略的准确性与风险控制能力。
This commit is contained in:
parent
f5570f4804
commit
43daa922a4
|
|
@ -709,17 +709,13 @@ class PositionManager:
|
|||
)
|
||||
|
||||
# ⚠️ 2026-01-29优化:计算止损距离用于盈亏比止盈计算(确保达到3:1目标)
|
||||
stop_distance_for_tp = None
|
||||
if side == 'BUY':
|
||||
stop_distance_for_tp = entry_price - stop_loss_price
|
||||
else:
|
||||
stop_distance_for_tp = stop_loss_price - entry_price
|
||||
|
||||
# 如果ATR可用,使用ATR计算更准确的止损距离(用于盈亏比止盈)
|
||||
# 实际止损距离(用于 TP1 最小盈亏比,必须与真实挂单一致,避免 SL 被保证金封顶后 TP 仍按 ATR 拉很远)
|
||||
actual_stop_distance = (entry_price - stop_loss_price) if side == 'BUY' else (stop_loss_price - entry_price)
|
||||
stop_distance_for_tp = actual_stop_distance
|
||||
# 如果ATR可用,使用ATR计算更准确的止损距离(仅用于 get_take_profit_price 的盈亏比,不用于 TP1 的 MIN_RR_FOR_TP1)
|
||||
if atr is not None and atr > 0 and entry_price > 0:
|
||||
atr_percent = atr / entry_price
|
||||
atr_multiplier = config.TRADING_CONFIG.get('ATR_STOP_LOSS_MULTIPLIER', 3.0) # 2026-02-12优化:默认3.0,避免噪音止损
|
||||
# 使用ATR计算的止损距离(更准确,用于盈亏比止盈)
|
||||
stop_distance_for_tp = entry_price * atr_percent * atr_multiplier
|
||||
|
||||
take_profit_pct_margin = config.TRADING_CONFIG.get('TAKE_PROFIT_PERCENT', 0.30)
|
||||
|
|
@ -760,13 +756,13 @@ class PositionManager:
|
|||
take_profit_1_amount = margin_usdt * take_profit_1_pct_margin
|
||||
tp1_distance = take_profit_1_amount / quantity
|
||||
|
||||
# ⚠️ 2026-02-10优化:确保TP1至少有 1.2倍 的盈亏比 (相对于止损距离)
|
||||
# 避免在高波动(宽止损)情况下,固定保证金比例止盈导致盈亏比过低
|
||||
if stop_distance_for_tp is not None and stop_distance_for_tp > 0:
|
||||
# ⚠️ 2026-02-10优化:确保TP1至少有 1.2倍 的盈亏比 (相对于【实际】止损距离)
|
||||
# 使用 actual_stop_distance(真实挂单距离),避免 SL 被保证金封顶后仍用 ATR 宽距离推高 TP 导致 4% SL vs 62% TP 的畸形
|
||||
if actual_stop_distance is not None and actual_stop_distance > 0:
|
||||
min_rr_for_tp1 = config.TRADING_CONFIG.get('MIN_RR_FOR_TP1', 1.5)
|
||||
min_tp1_distance = stop_distance_for_tp * min_rr_for_tp1
|
||||
min_tp1_distance = actual_stop_distance * min_rr_for_tp1
|
||||
if min_tp1_distance > tp1_distance:
|
||||
logger.info(f"{symbol} [优化] TP1距离 ({tp1_distance:.4f}) 小于 {min_rr_for_tp1}倍止损距离 ({min_tp1_distance:.4f}),已自动调整以保证盈亏比")
|
||||
logger.info(f"{symbol} [优化] TP1距离 ({tp1_distance:.4f}) 小于 {min_rr_for_tp1}倍实际止损距离 ({min_tp1_distance:.4f}),已自动调整以保证盈亏比")
|
||||
tp1_distance = min_tp1_distance
|
||||
|
||||
# ⚠️ 2026-02-12优化:确保TP1至少覆盖双向手续费(避免微利单实际上亏损)
|
||||
|
|
@ -776,6 +772,18 @@ class PositionManager:
|
|||
logger.info(f"{symbol} [优化] TP1距离 ({tp1_distance:.4f}) 小于 手续费磨损距离 ({min_fee_distance:.4f}),已自动调整以覆盖成本")
|
||||
tp1_distance = min_fee_distance
|
||||
|
||||
# ⚠️ 止盈上限:TP1 不超过配置的止盈比例,避免“4% 止损 vs 62% 止盈”的畸形(与 USE_MARGIN_CAP_FOR_TP 一致)
|
||||
if margin_usdt and margin_usdt > 0 and quantity > 0:
|
||||
tp1_max_pct = config.TRADING_CONFIG.get('TAKE_PROFIT_1_PERCENT', 0.20)
|
||||
if tp1_max_pct is not None and tp1_max_pct > 1:
|
||||
tp1_max_pct = tp1_max_pct / 100.0
|
||||
tp1_max_pct = (tp1_max_pct or 0.20) * 1.5 # 允许第一目标最多约 30% 保证金
|
||||
tp1_max_amount = margin_usdt * tp1_max_pct
|
||||
tp1_max_distance = tp1_max_amount / quantity
|
||||
if tp1_distance > tp1_max_distance:
|
||||
logger.info(f"{symbol} [优化] TP1距离 ({tp1_distance:.4f}) 超过止盈上限 ({tp1_max_distance:.4f},约{tp1_max_pct*100:.0f}% margin),已封顶")
|
||||
tp1_distance = tp1_max_distance
|
||||
|
||||
if tp1_distance > 0:
|
||||
if side == 'BUY':
|
||||
take_profit_1 = entry_price + tp1_distance
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user