a
This commit is contained in:
parent
5faf3e103d
commit
cf678569ee
|
|
@ -2146,11 +2146,23 @@ class PositionManager:
|
|||
except Exception:
|
||||
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关键修复:优先检查盈亏情况,避免盈利单被错误标记为止损
|
||||
# 1. 优先检查盈亏情况
|
||||
if pnl_percent > 0:
|
||||
# 1. 优先检查盈亏情况(使用基于保证金的盈亏百分比)
|
||||
if pnl_percent_for_judge > 0:
|
||||
# 盈利单:优先检查止盈价格匹配
|
||||
if tp is not None and _close_to(ep, float(tp), max_pct=0.10):
|
||||
exit_reason = "take_profit"
|
||||
|
|
@ -2175,9 +2187,10 @@ class PositionManager:
|
|||
# 方向匹配:BUY时平仓价 < 止损价,SELL时平仓价 > 止损价
|
||||
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"
|
||||
logger.info(f"{trade.get('symbol')} [同步] 价格方向匹配止损,且亏损{pnl_percent:.2f}%,标记为止损")
|
||||
logger.info(f"{trade.get('symbol')} [同步] 价格方向匹配止损,且亏损{pnl_percent_for_judge:.2f}% of margin,标记为止损")
|
||||
|
||||
# 2. 如果仍未确定,检查止盈价格匹配(作为备选)
|
||||
if exit_reason == "sync" and ep > 0:
|
||||
|
|
@ -2191,13 +2204,14 @@ class PositionManager:
|
|||
# 3. 特征判断:如果价格不匹配,但满足止损特征,也标记为止损
|
||||
if exit_reason == "sync" and entry_price_val > 0 and ep > 0:
|
||||
# 特征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:价格在止损方向
|
||||
if sl is not None:
|
||||
sl_val = float(sl)
|
||||
if (trade.get("side") == "BUY" and ep < sl_val) or (trade.get("side") == "SELL" and ep > sl_val):
|
||||
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 订单,但价格不匹配止损/止盈,可能是其他自动平仓(如移动止损)
|
||||
if exit_reason == "sync" and is_reduce_only:
|
||||
|
|
@ -2223,9 +2237,10 @@ class PositionManager:
|
|||
# 只有在价格和特征都不匹配,且不是 reduceOnly 时,才标记为手动平仓
|
||||
if not is_reduce_only:
|
||||
# 再次检查:如果亏损很大,更可能是止损触发(币安API可能不准确)
|
||||
if pnl_percent < -10.0:
|
||||
# ⚠️ 关键修复:使用基于保证金的盈亏百分比判断
|
||||
if pnl_percent_for_judge < -10.0:
|
||||
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:
|
||||
exit_reason = "manual"
|
||||
except Exception as e:
|
||||
|
|
@ -2256,12 +2271,13 @@ class PositionManager:
|
|||
|
||||
strategy_type = 'trend_following' # 默认策略类型
|
||||
|
||||
# ⚠️ 关键修复:使用基于保证金的盈亏百分比更新数据库(与实时监控逻辑一致)
|
||||
Trade.update_exit(
|
||||
trade_id=trade_id,
|
||||
exit_price=exit_price,
|
||||
exit_reason=exit_reason,
|
||||
pnl=pnl,
|
||||
pnl_percent=pnl_percent,
|
||||
pnl_percent=pnl_percent_margin, # 使用基于保证金的盈亏百分比
|
||||
exit_order_id=exit_order_id, # 保存币安平仓订单号
|
||||
strategy_type=strategy_type,
|
||||
duration_minutes=duration_minutes,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user