From 42c6904604deef008c6b720b318e37089782ed4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=96=87=E8=96=87=E5=AE=89?= Date: Fri, 13 Feb 2026 21:39:10 +0800 Subject: [PATCH] 1 --- trading_system/position_manager.py | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/trading_system/position_manager.py b/trading_system/position_manager.py index 51824c5..c1ec679 100644 --- a/trading_system/position_manager.py +++ b/trading_system/position_manager.py @@ -190,6 +190,12 @@ class PositionManager: try: # 0) 防止同一 symbol 重复挂入场单/快速重复尝试(去抖 + 冷却) now_ms = int(time.time() * 1000) + + # ⚠️ 关键修复:检查是否已经在持仓中(防止重复开仓) + if symbol in self.active_positions: + logger.info(f"{symbol} [入场] 已在持仓中 (active_positions),跳过重复开仓") + return None + cooldown_sec = int(config.TRADING_CONFIG.get("ENTRY_SYMBOL_COOLDOWN_SEC", 120) or 0) last_ms = self._last_entry_attempt_ms.get(symbol) if last_ms and cooldown_sec > 0 and now_ms - last_ms < cooldown_sec * 1000: @@ -1521,14 +1527,22 @@ class PositionManager: take_profit_val = float(take_profit) # 检查是否已经触发止盈 + # ⚠️ 关键修复:增加0.5%的缓冲,避免因价格轻微触及或市场波动导致的过早止盈 + # 如果价格只是刚好碰到止盈价,不立即触发,而是尝试挂单或让WebSocket监控决定 triggered_tp = False - if side == "BUY" and current_price_val >= take_profit_val: - triggered_tp = True - elif side == "SELL" and current_price_val <= take_profit_val: - triggered_tp = True + buffer_pct = 0.005 # 0.5% buffer + + if side == "BUY": + # 做多:当前价 >= 止盈价 * (1 + buffer) + if current_price_val >= take_profit_val * (1 + buffer_pct): + triggered_tp = True + elif side == "SELL": + # 做空:当前价 <= 止盈价 * (1 - buffer) + if current_price_val <= take_profit_val * (1 - buffer_pct): + triggered_tp = True if triggered_tp: - logger.info(f"{symbol} 🎯 当前价格({current_price_val:.8f})已达到止盈价({take_profit_val:.8f}),立即执行市价止盈!") + logger.info(f"{symbol} 🎯 当前价格({current_price_val:.8f})已显著超过止盈价({take_profit_val:.8f}),立即执行市价止盈!") await self.close_position(symbol, reason='take_profit') return except Exception as e: @@ -1547,8 +1561,10 @@ class PositionManager: # 处理 -2021: Order would immediately trigger error_msg = str(e) if "-2021" in error_msg or "immediately trigger" in error_msg: - logger.warning(f"{symbol} ⚠️ 止盈单会立即触发(-2021),视为已到达止盈位,立即执行市价止盈") - await self.close_position(symbol, reason='take_profit') + # ⚠️ 关键修复:如果止盈单会立即触发,不立即平仓,而是依赖WebSocket监控 + # 这样可以避免因价格微小波动导致的过早止盈,让利润奔跑(WebSocket有最小盈利检查) + logger.warning(f"{symbol} ⚠️ 止盈单会立即触发(-2021),跳过挂交易所止盈单,将依赖WebSocket监控执行止盈") + # await self.close_position(symbol, reason='take_profit') <-- 已移除立即平仓 return else: logger.warning(f"{symbol} 挂止盈单失败: {e}")