This commit is contained in:
薇薇安 2026-01-20 08:15:10 +08:00
parent 2d18d92069
commit 8d5ea39bd4
3 changed files with 35 additions and 12 deletions

View File

@ -1295,6 +1295,13 @@ class BinanceClient:
logger.info(f"取消订单成功: {symbol} {order_id}")
return True
except BinanceAPIException as e:
# -2011 Unknown order sent订单可能已成交/已撤销/已过期,这是典型幂等场景
# 取消操作应视为“已达成目标”(不再继续报错刷屏)
code = getattr(e, "code", None)
msg = str(e)
if code == -2011 or "code=-2011" in msg or "Unknown order sent" in msg:
logger.info(f"取消订单幂等成功(订单可能已不存在): {symbol} {order_id} | {e}")
return True
logger.error(f"取消订单失败: {e}")
return False

View File

@ -968,14 +968,27 @@ class PositionManager:
import traceback
logger.error(f" 完整错误堆栈:\n{traceback.format_exc()}")
# 尝试清理本地记录(即使平仓失败)
# 关键:平仓失败时不要盲目清理本地持仓/停止监控,否则会导致“仍有仓位但不再监控/不再自动止损止盈”
# 仅当确认币安已无持仓或实时持仓为0才清理本地记录。
try:
amt0 = await self._get_live_position_amt(symbol, position_side=None)
except Exception:
amt0 = None
if amt0 is not None and abs(amt0) <= 0:
try:
await self._stop_position_monitoring(symbol)
except Exception:
pass
try:
if symbol in self.active_positions:
del self.active_positions[symbol]
logger.info(f"{symbol} [平仓] 已清理本地持仓记录")
except Exception as cleanup_error:
logger.warning(f"{symbol} [平仓] 清理本地记录时出错: {cleanup_error}")
except Exception:
pass
logger.warning(f"{symbol} [平仓] 异常后检查币安持仓已为0已清理本地记录")
else:
logger.warning(
f"{symbol} [平仓] 异常后检查:币安持仓仍可能存在(amt={amt0}),保留本地记录与监控,等待下次同步/重试"
)
return False

View File

@ -517,12 +517,14 @@ class RiskManager:
if stop_loss_price_price is not None:
candidate_prices.append(('价格百分比', stop_loss_price_price))
# 对做多取最大的值(最宽松),对做空取最小的值(最宽松)
# 选择“更宽松/更远”的止损:
# - 做多(BUY):止损越低越宽松 → 取最小值
# - 做空(SELL):止损越高越宽松 → 取最大值
if side == 'BUY':
stop_loss_price = max(p[1] for p in candidate_prices)
stop_loss_price = min(p[1] for p in candidate_prices)
selected_method = [p[0] for p in candidate_prices if p[1] == stop_loss_price][0]
else:
stop_loss_price = min(p[1] for p in candidate_prices)
stop_loss_price = max(p[1] for p in candidate_prices)
selected_method = [p[0] for p in candidate_prices if p[1] == stop_loss_price][0]
# 如果提供了技术分析数据,计算技术止损(允许更紧的止损,但需要在保证金止损范围内)
@ -574,11 +576,12 @@ class RiskManager:
)
# 重新选择最终的止损价(包括技术止损)
# 仍保持“更宽松/更远”的选择规则
if side == 'BUY':
final_stop_loss = max(p[1] for p in candidate_prices)
final_stop_loss = min(p[1] for p in candidate_prices)
selected_method = [p[0] for p in candidate_prices if p[1] == final_stop_loss][0]
else:
final_stop_loss = min(p[1] for p in candidate_prices)
final_stop_loss = max(p[1] for p in candidate_prices)
selected_method = [p[0] for p in candidate_prices if p[1] == final_stop_loss][0]
logger.info(