diff --git a/trading_system/position_manager.py b/trading_system/position_manager.py index 722ff8e..3b26ce6 100644 --- a/trading_system/position_manager.py +++ b/trading_system/position_manager.py @@ -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