fix(binance_client): 增强错误处理与止盈价校验逻辑

在 `binance_client.py` 中新增了对特定错误代码的处理,确保在遇到 -4509 和 -4061 错误时能够正确抛出异常。同时,优化了止盈价的合理性校验,确保在无法获取当前价格时,止盈价不低于 0.01,避免因错误数据导致的挂单被拒,提升了交易逻辑的稳定性与风险控制能力。
This commit is contained in:
薇薇安 2026-02-20 17:14:44 +08:00
parent 9b81832af2
commit f3089fdf7f

View File

@ -2226,6 +2226,9 @@ class BinanceClient:
except (ConnectionError, TimeoutError) as e: except (ConnectionError, TimeoutError) as e:
logger.debug(f"{symbol} WS 条件单失败({e}),回退到 REST") logger.debug(f"{symbol} WS 条件单失败({e}),回退到 REST")
except Exception as e: except Exception as e:
code = getattr(e, "code", None)
if code in (-4509, -4061):
raise BinanceAPIException(None, 400, json.dumps({"code": code, "msg": str(e)}))
logger.debug(f"{symbol} WS 条件单异常: {e},回退到 REST") logger.debug(f"{symbol} WS 条件单异常: {e},回退到 REST")
# 回退到 REST原有逻辑 # 回退到 REST原有逻辑
@ -2246,6 +2249,8 @@ class BinanceClient:
return None return None
except BinanceAPIException as e: except BinanceAPIException as e:
error_code = e.code if hasattr(e, 'code') else None error_code = e.code if hasattr(e, 'code') else None
if error_code in (-4509, -4061):
raise # 让 place_trigger_close_position_order 统一打一条 warning不在此处刷日志
error_msg = str(e) error_msg = str(e)
trigger_type = params.get('type', 'UNKNOWN') trigger_type = params.get('type', 'UNKNOWN')
logger.error(f"{symbol} ❌ 创建 Algo 条件单失败({trigger_type}): {error_msg}") logger.error(f"{symbol} ❌ 创建 Algo 条件单失败({trigger_type}): {error_msg}")
@ -2402,6 +2407,14 @@ class BinanceClient:
cp = float(current_price) if current_price is not None else None cp = float(current_price) if current_price is not None else None
except Exception: except Exception:
cp = None cp = None
# 止盈单校验需要当前价;若未传入则拉取一次,避免错误 triggerPrice如 0.001)导致 -4509
if (cp is None or cp <= 0) and ttype == "TAKE_PROFIT_MARKET":
try:
ticker = await self.get_ticker_24h(symbol)
if ticker and ticker.get("lastPrice"):
cp = float(ticker["lastPrice"])
except Exception:
pass
tick = 0.0 tick = 0.0
pp = 8 pp = 8
@ -2421,25 +2434,30 @@ class BinanceClient:
return None return None
# 触发价合理性:止盈价不能偏离当前价过远(避免错误数据导致挂单被拒或 -4509 # 触发价合理性:止盈价不能偏离当前价过远(避免错误数据导致挂单被拒或 -4509
if cp and cp > 0 and ttype == "TAKE_PROFIT_MARKET": if ttype == "TAKE_PROFIT_MARKET":
if pd == "SELL": if cp and cp > 0:
# 做空止盈:触发价应 < 当前价,且不应低于当前价的 1%(避免错用成 0.001 等错误数值) if pd == "SELL":
if sp >= cp: if sp >= cp:
pass # 下方会做“止盈修正” pass
elif sp < cp * 0.01: elif sp < cp * 0.01:
logger.warning( logger.warning(
f"{symbol} [止盈校验] SELL 止盈价 {sp:.8f} 远低于当前价 {cp:.8f},疑似数据错误,跳过挂单" f"{symbol} [止盈校验] SELL 止盈价 {sp:.8f} 远低于当前价 {cp:.8f},疑似数据错误,跳过挂单"
) )
return None return None
else: else:
# 做多止盈:触发价应 > 当前价,且不应超过当前价的 100 倍 if sp <= cp:
if sp <= cp: pass
pass elif sp > cp * 100:
elif sp > cp * 100: logger.warning(
logger.warning( f"{symbol} [止盈校验] BUY 止盈价 {sp:.8f} 远高于当前价 {cp:.8f},疑似数据错误,跳过挂单"
f"{symbol} [止盈校验] BUY 止盈价 {sp:.8f} 远高于当前价 {cp:.8f},疑似数据错误,跳过挂单" )
) return None
return None elif sp < 0.01:
# 无当前价时:多数 USDT 合约价格 > 0.01,过小触发价视为错误(如 0.001573
logger.warning(
f"{symbol} [止盈校验] 止盈价 {sp:.8f} 过小且无法获取当前价,疑似数据错误,跳过挂单"
)
return None
# 触发方向约束(避免立即触发): # 触发方向约束(避免立即触发):
# - long 止损:价格 <= stopPricestopPrice 应 < current至少差一个 min_step # - long 止损:价格 <= stopPricestopPrice 应 < current至少差一个 min_step