This commit is contained in:
薇薇安 2026-01-27 22:40:23 +08:00
parent 5faf3e103d
commit cf678569ee

View File

@ -2146,11 +2146,23 @@ class PositionManager:
except Exception: except Exception:
pass pass
pnl_percent = float(trade.get("pnl_percent", 0) or 0) # ⚠️ 关键修复:使用基于保证金的盈亏百分比判断盈利/亏损,而不是价格涨跌幅
# 因为价格涨跌幅如2.35%和基于保证金的盈亏百分比如18.82%)差异很大
# 对于SELL单价格从0.119跌到0.1162价格涨跌幅只有2.35%但基于保证金的盈亏百分比是18.82%
pnl_percent_price = float(trade.get("pnl_percent", 0) or 0) # 价格涨跌幅(数据库可能存储的是这个)
# 重新计算基于保证金的盈亏百分比(更准确)
leverage = float(trade.get("leverage", 8) or 8)
entry_value = entry_price * quantity
margin = entry_value / leverage if leverage > 0 else entry_value
pnl_percent_margin = (pnl / margin * 100) if margin > 0 else 0
# 使用基于保证金的盈亏百分比判断(与实时监控逻辑一致)
pnl_percent_for_judge = pnl_percent_margin
# ⚠️ 2026-01-27关键修复优先检查盈亏情况避免盈利单被错误标记为止损 # ⚠️ 2026-01-27关键修复优先检查盈亏情况避免盈利单被错误标记为止损
# 1. 优先检查盈亏情况 # 1. 优先检查盈亏情况(使用基于保证金的盈亏百分比)
if pnl_percent > 0: if pnl_percent_for_judge > 0:
# 盈利单:优先检查止盈价格匹配 # 盈利单:优先检查止盈价格匹配
if tp is not None and _close_to(ep, float(tp), max_pct=0.10): if tp is not None and _close_to(ep, float(tp), max_pct=0.10):
exit_reason = "take_profit" exit_reason = "take_profit"
@ -2175,9 +2187,10 @@ class PositionManager:
# 方向匹配BUY时平仓价 < 止损价SELL时平仓价 > 止损价 # 方向匹配BUY时平仓价 < 止损价SELL时平仓价 > 止损价
elif (trade.get("side") == "BUY" and ep < sl_val) or (trade.get("side") == "SELL" and ep > sl_val): elif (trade.get("side") == "BUY" and ep < sl_val) or (trade.get("side") == "SELL" and ep > sl_val):
# 如果价格在止损方向,且亏损比例较大,更可能是止损触发 # 如果价格在止损方向,且亏损比例较大,更可能是止损触发
if pnl_percent < -5.0: # 亏损超过5% # ⚠️ 关键修复:使用基于保证金的盈亏百分比判断
if pnl_percent_for_judge < -5.0: # 亏损超过5%(基于保证金)
exit_reason = "stop_loss" exit_reason = "stop_loss"
logger.info(f"{trade.get('symbol')} [同步] 价格方向匹配止损,且亏损{pnl_percent:.2f}%,标记为止损") logger.info(f"{trade.get('symbol')} [同步] 价格方向匹配止损,且亏损{pnl_percent_for_judge:.2f}% of margin,标记为止损")
# 2. 如果仍未确定,检查止盈价格匹配(作为备选) # 2. 如果仍未确定,检查止盈价格匹配(作为备选)
if exit_reason == "sync" and ep > 0: if exit_reason == "sync" and ep > 0:
@ -2191,13 +2204,14 @@ class PositionManager:
# 3. 特征判断:如果价格不匹配,但满足止损特征,也标记为止损 # 3. 特征判断:如果价格不匹配,但满足止损特征,也标记为止损
if exit_reason == "sync" and entry_price_val > 0 and ep > 0: if exit_reason == "sync" and entry_price_val > 0 and ep > 0:
# 特征1持仓时间短< 30分钟且亏损 # 特征1持仓时间短< 30分钟且亏损
if duration_minutes and duration_minutes < 30 and pnl_percent < -5.0: # ⚠️ 关键修复:使用基于保证金的盈亏百分比判断
if duration_minutes and duration_minutes < 30 and pnl_percent_for_judge < -5.0:
# 特征2价格在止损方向 # 特征2价格在止损方向
if sl is not None: if sl is not None:
sl_val = float(sl) sl_val = float(sl)
if (trade.get("side") == "BUY" and ep < sl_val) or (trade.get("side") == "SELL" and ep > sl_val): if (trade.get("side") == "BUY" and ep < sl_val) or (trade.get("side") == "SELL" and ep > sl_val):
exit_reason = "stop_loss" exit_reason = "stop_loss"
logger.info(f"{trade.get('symbol')} [同步] 特征判断:持仓{duration_minutes:.1f}分钟,亏损{pnl_percent:.2f}%,价格在止损方向,标记为止损") logger.info(f"{trade.get('symbol')} [同步] 特征判断:持仓{duration_minutes:.1f}分钟,亏损{pnl_percent_for_judge:.2f}% of margin,价格在止损方向,标记为止损")
# 4. 如果之前标记为 sync 且是 reduceOnly 订单,但价格不匹配止损/止盈,可能是其他自动平仓(如移动止损) # 4. 如果之前标记为 sync 且是 reduceOnly 订单,但价格不匹配止损/止盈,可能是其他自动平仓(如移动止损)
if exit_reason == "sync" and is_reduce_only: if exit_reason == "sync" and is_reduce_only:
@ -2223,9 +2237,10 @@ class PositionManager:
# 只有在价格和特征都不匹配,且不是 reduceOnly 时,才标记为手动平仓 # 只有在价格和特征都不匹配,且不是 reduceOnly 时,才标记为手动平仓
if not is_reduce_only: if not is_reduce_only:
# 再次检查如果亏损很大更可能是止损触发币安API可能不准确 # 再次检查如果亏损很大更可能是止损触发币安API可能不准确
if pnl_percent < -10.0: # ⚠️ 关键修复:使用基于保证金的盈亏百分比判断
if pnl_percent_for_judge < -10.0:
exit_reason = "stop_loss" # 大额亏损,更可能是止损 exit_reason = "stop_loss" # 大额亏损,更可能是止损
logger.warning(f"{trade.get('symbol')} [同步] 大额亏损{pnl_percent:.2f}%即使reduceOnly=false也标记为止损") logger.warning(f"{trade.get('symbol')} [同步] 大额亏损{pnl_percent_for_judge:.2f}% of margin即使reduceOnly=false也标记为止损")
else: else:
exit_reason = "manual" exit_reason = "manual"
except Exception as e: except Exception as e:
@ -2256,12 +2271,13 @@ class PositionManager:
strategy_type = 'trend_following' # 默认策略类型 strategy_type = 'trend_following' # 默认策略类型
# ⚠️ 关键修复:使用基于保证金的盈亏百分比更新数据库(与实时监控逻辑一致)
Trade.update_exit( Trade.update_exit(
trade_id=trade_id, trade_id=trade_id,
exit_price=exit_price, exit_price=exit_price,
exit_reason=exit_reason, exit_reason=exit_reason,
pnl=pnl, pnl=pnl,
pnl_percent=pnl_percent, pnl_percent=pnl_percent_margin, # 使用基于保证金的盈亏百分比
exit_order_id=exit_order_id, # 保存币安平仓订单号 exit_order_id=exit_order_id, # 保存币安平仓订单号
strategy_type=strategy_type, strategy_type=strategy_type,
duration_minutes=duration_minutes, duration_minutes=duration_minutes,