From dfd899256b263b1c7b91d415388c7f46a008c64d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=96=87=E8=96=87=E5=AE=89?= Date: Tue, 27 Jan 2026 23:04:42 +0800 Subject: [PATCH] a --- trading_system/position_manager.py | 66 +++++++++++++++++++----------- 1 file changed, 43 insertions(+), 23 deletions(-) diff --git a/trading_system/position_manager.py b/trading_system/position_manager.py index 4b03b4a..ccb9cfc 100644 --- a/trading_system/position_manager.py +++ b/trading_system/position_manager.py @@ -526,12 +526,6 @@ class PositionManager: ) # 分步止盈(基于“实际成交价 + 已计算的止损/止盈”) - if side == 'BUY': - take_profit_1 = entry_price + (entry_price - stop_loss_price) # 盈亏比1:1 - else: - take_profit_1 = entry_price - (stop_loss_price - entry_price) # 盈亏比1:1 - take_profit_2 = take_profit_price - # 交易规模:名义/保证金(用于统计总交易量与UI展示) try: notional_usdt = float(entry_price) * float(quantity) @@ -542,6 +536,29 @@ class PositionManager: except Exception: margin_usdt = None + # 分步止盈(基于"实际成交价 + 已计算的止损/止盈") + # ⚠️ 关键修复:第一目标应该使用 TAKE_PROFIT_PERCENT(10%固定止盈),而不是盈亏比1:1 + # 这样第一目标更容易触发,保证拿到10%盈利,然后剩余50%追求更高收益 + # 第一目标和触发条件必须一致,都使用 TAKE_PROFIT_PERCENT + take_profit_1_pct_margin = config.TRADING_CONFIG.get('TAKE_PROFIT_PERCENT', 0.10) + # 兼容百分比形式和比例形式 + if take_profit_1_pct_margin is not None and take_profit_1_pct_margin > 1: + take_profit_1_pct_margin = take_profit_1_pct_margin / 100.0 + # 计算第一目标止盈价(基于保证金10%) + if margin_usdt and margin_usdt > 0 and quantity > 0: + take_profit_1_amount = margin_usdt * take_profit_1_pct_margin + if side == 'BUY': + take_profit_1 = entry_price + (take_profit_1_amount / quantity) # 10%固定止盈 + else: + take_profit_1 = entry_price - (take_profit_1_amount / quantity) # 10%固定止盈 + else: + # 如果无法计算保证金,回退到盈亏比1:1 + if side == 'BUY': + take_profit_1 = entry_price + (entry_price - stop_loss_price) # 盈亏比1:1 + else: + take_profit_1 = entry_price - (stop_loss_price - entry_price) # 盈亏比1:1 + take_profit_2 = take_profit_price + # 记录到数据库(只有在订单真正成交后才保存) trade_id = None if DB_AVAILABLE and Trade: @@ -1644,17 +1661,18 @@ class PositionManager: partial_profit_taken = position_info.get('partialProfitTaken', False) remaining_quantity = position_info.get('remainingQuantity', quantity) - # 第一目标:盈亏比1:1,了结50%仓位 + # 第一目标:10%固定止盈(基于保证金),了结50%仓位,保证拿到10%盈利 # ✅ 已移除时间锁限制,可以立即执行 if not partial_profit_taken and take_profit_1 is not None: - # 计算第一目标对应的保证金百分比 - if position_info['side'] == 'BUY': - take_profit_1_amount = (take_profit_1 - entry_price) * quantity - else: # SELL - take_profit_1_amount = (entry_price - take_profit_1) * quantity - take_profit_1_pct_margin = (take_profit_1_amount / margin * 100) if margin > 0 else 0 + # ⚠️ 关键修复:直接使用配置的 TAKE_PROFIT_PERCENT,而不是从止盈价格反推 + # 因为第一目标现在已经是基于 TAKE_PROFIT_PERCENT 计算的,直接使用配置值更准确 + take_profit_1_pct_margin_config = config.TRADING_CONFIG.get('TAKE_PROFIT_PERCENT', 0.10) + # 兼容百分比形式和比例形式 + if take_profit_1_pct_margin_config > 1: + take_profit_1_pct_margin_config = take_profit_1_pct_margin_config / 100.0 + take_profit_1_pct_margin = take_profit_1_pct_margin_config * 100 # 转换为百分比 - # 直接比较当前盈亏百分比与第一目标(基于保证金) + # 直接比较当前盈亏百分比与第一目标(基于保证金,使用配置值) if pnl_percent_margin >= take_profit_1_pct_margin: logger.info( f"{symbol} 触发第一目标止盈(盈亏比1:1,基于保证金): " @@ -1740,7 +1758,8 @@ class PositionManager: f"当前价={current_price:.4f}, 目标价={take_profit_2:.4f}, " f"剩余数量={remaining_quantity:.4f}" ) - exit_reason = 'take_profit' + # ⚠️ 关键修复:统一使用 'take_profit_partial_then_take_profit' 来区分"第一目标止盈后第二目标止盈" + exit_reason = 'take_profit_partial_then_take_profit' # 计算总盈亏(原始仓位 + 部分止盈的盈亏) # 部分止盈时的价格需要从数据库或记录中获取,这里简化处理 total_pnl_amount = remaining_pnl_amount # 简化:只计算剩余仓位盈亏 @@ -2939,16 +2958,17 @@ class PositionManager: take_profit_2 = position_info.get('takeProfit2', position_info.get('takeProfit')) # 第二目标(1.5:1) # ⚠️ 注意:partial_profit_taken和remaining_quantity已在方法开头初始化,这里不需要重复定义 - # 第一目标:30%固定止盈(基于保证金),了结50%仓位,保证拿到30%盈利 + # 第一目标:10%固定止盈(基于保证金),了结50%仓位,保证拿到10%盈利 if not partial_profit_taken and take_profit_1 is not None: - # 计算第一目标对应的保证金百分比 - if position_info['side'] == 'BUY': - take_profit_1_amount = (take_profit_1 - entry_price) * quantity - else: # SELL - take_profit_1_amount = (entry_price - take_profit_1) * quantity - take_profit_1_pct_margin = (take_profit_1_amount / margin * 100) if margin > 0 else 0 + # ⚠️ 关键修复:直接使用配置的 TAKE_PROFIT_PERCENT,而不是从止盈价格反推 + # 因为第一目标现在已经是基于 TAKE_PROFIT_PERCENT 计算的,直接使用配置值更准确 + take_profit_1_pct_margin_config = config.TRADING_CONFIG.get('TAKE_PROFIT_PERCENT', 0.10) + # 兼容百分比形式和比例形式 + if take_profit_1_pct_margin_config > 1: + take_profit_1_pct_margin_config = take_profit_1_pct_margin_config / 100.0 + take_profit_1_pct_margin = take_profit_1_pct_margin_config * 100 # 转换为百分比 - # 直接比较当前盈亏百分比与第一目标(基于保证金) + # 直接比较当前盈亏百分比与第一目标(基于保证金,使用配置值) if pnl_percent_margin >= take_profit_1_pct_margin: # ⚠️ 2026-01-27优化:动态读取配置值,更新日志文案 take_profit_pct_config = config.TRADING_CONFIG.get('TAKE_PROFIT_PERCENT', 0.10)