This commit is contained in:
薇薇安 2026-01-27 23:04:42 +08:00
parent cf678569ee
commit dfd899256b

View File

@ -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展示 # 交易规模:名义/保证金用于统计总交易量与UI展示
try: try:
notional_usdt = float(entry_price) * float(quantity) notional_usdt = float(entry_price) * float(quantity)
@ -542,6 +536,29 @@ class PositionManager:
except Exception: except Exception:
margin_usdt = None margin_usdt = None
# 分步止盈(基于"实际成交价 + 已计算的止损/止盈"
# ⚠️ 关键修复:第一目标应该使用 TAKE_PROFIT_PERCENT10%固定止盈而不是盈亏比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 trade_id = None
if DB_AVAILABLE and Trade: if DB_AVAILABLE and Trade:
@ -1644,17 +1661,18 @@ class PositionManager:
partial_profit_taken = position_info.get('partialProfitTaken', False) partial_profit_taken = position_info.get('partialProfitTaken', False)
remaining_quantity = position_info.get('remainingQuantity', quantity) 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 not partial_profit_taken and take_profit_1 is not None:
# 计算第一目标对应的保证金百分比 # ⚠️ 关键修复:直接使用配置的 TAKE_PROFIT_PERCENT而不是从止盈价格反推
if position_info['side'] == 'BUY': # 因为第一目标现在已经是基于 TAKE_PROFIT_PERCENT 计算的,直接使用配置值更准确
take_profit_1_amount = (take_profit_1 - entry_price) * quantity take_profit_1_pct_margin_config = config.TRADING_CONFIG.get('TAKE_PROFIT_PERCENT', 0.10)
else: # SELL # 兼容百分比形式和比例形式
take_profit_1_amount = (entry_price - take_profit_1) * quantity if take_profit_1_pct_margin_config > 1:
take_profit_1_pct_margin = (take_profit_1_amount / margin * 100) if margin > 0 else 0 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: if pnl_percent_margin >= take_profit_1_pct_margin:
logger.info( logger.info(
f"{symbol} 触发第一目标止盈盈亏比1:1基于保证金: " f"{symbol} 触发第一目标止盈盈亏比1:1基于保证金: "
@ -1740,7 +1758,8 @@ class PositionManager:
f"当前价={current_price:.4f}, 目标价={take_profit_2:.4f}, " f"当前价={current_price:.4f}, 目标价={take_profit_2:.4f}, "
f"剩余数量={remaining_quantity:.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 # 简化:只计算剩余仓位盈亏 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 take_profit_2 = position_info.get('takeProfit2', position_info.get('takeProfit')) # 第二目标1.5:1
# ⚠️ 注意partial_profit_taken和remaining_quantity已在方法开头初始化这里不需要重复定义 # ⚠️ 注意partial_profit_taken和remaining_quantity已在方法开头初始化这里不需要重复定义
# 第一目标:30%固定止盈基于保证金了结50%仓位保证拿到30%盈利 # 第一目标:10%固定止盈基于保证金了结50%仓位保证拿到10%盈利
if not partial_profit_taken and take_profit_1 is not None: if not partial_profit_taken and take_profit_1 is not None:
# 计算第一目标对应的保证金百分比 # ⚠️ 关键修复:直接使用配置的 TAKE_PROFIT_PERCENT而不是从止盈价格反推
if position_info['side'] == 'BUY': # 因为第一目标现在已经是基于 TAKE_PROFIT_PERCENT 计算的,直接使用配置值更准确
take_profit_1_amount = (take_profit_1 - entry_price) * quantity take_profit_1_pct_margin_config = config.TRADING_CONFIG.get('TAKE_PROFIT_PERCENT', 0.10)
else: # SELL # 兼容百分比形式和比例形式
take_profit_1_amount = (entry_price - take_profit_1) * quantity if take_profit_1_pct_margin_config > 1:
take_profit_1_pct_margin = (take_profit_1_amount / margin * 100) if margin > 0 else 0 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: if pnl_percent_margin >= take_profit_1_pct_margin:
# ⚠️ 2026-01-27优化动态读取配置值更新日志文案 # ⚠️ 2026-01-27优化动态读取配置值更新日志文案
take_profit_pct_config = config.TRADING_CONFIG.get('TAKE_PROFIT_PERCENT', 0.10) take_profit_pct_config = config.TRADING_CONFIG.get('TAKE_PROFIT_PERCENT', 0.10)