a
This commit is contained in:
parent
e3ecaf1232
commit
69145c4345
|
|
@ -978,8 +978,16 @@ class BinanceClient:
|
|||
# 如果是平仓订单,添加 reduceOnly 参数
|
||||
# 根据币安API文档,reduceOnly 应该是字符串 "true" 或 "false"
|
||||
if reduce_only:
|
||||
order_params['reduceOnly'] = "true" # 使用字符串格式,符合币安API要求
|
||||
logger.info(f"{symbol} 使用 reduceOnly=true 平仓订单")
|
||||
# 实测:某些账户/模式下(尤其是对冲模式 + positionSide)会报:
|
||||
# APIError(code=-1106): Parameter 'reduceonly' sent when not required.
|
||||
# 因此:当我们已经明确指定 positionSide=LONG/SHORT 时,不再传 reduceOnly;
|
||||
# 其余情况仍保留 reduceOnly 以避免反向开仓。
|
||||
if order_params.get("positionSide") in {"LONG", "SHORT"}:
|
||||
logger.info(f"{symbol} 对冲模式平仓:已指定 positionSide,跳过 reduceOnly(避免 -1106)")
|
||||
else:
|
||||
# python-binance 可以接受 bool;同时后面也做 -1106 自动兜底重试
|
||||
order_params['reduceOnly'] = True
|
||||
logger.info(f"{symbol} 使用 reduceOnly=true 平仓订单")
|
||||
|
||||
async def _submit(params: Dict[str, Any]) -> Dict[str, Any]:
|
||||
if order_type == 'MARKET':
|
||||
|
|
@ -991,19 +999,31 @@ class BinanceClient:
|
|||
params['price'] = price
|
||||
return await self.client.futures_create_order(**params)
|
||||
|
||||
# 提交订单;若遇到 -4061,则在“带/不带 positionSide”之间做一次兜底重试
|
||||
# 提交订单;若遇到:
|
||||
# -4061: positionSide 与账户模式不匹配 → 在“带/不带 positionSide”之间兜底切换重试
|
||||
# -1106: reduceOnly not required → 去掉 reduceOnly 重试(避免自动平仓失败)
|
||||
try:
|
||||
order = await _submit(order_params)
|
||||
except BinanceAPIException as e:
|
||||
if getattr(e, "code", None) == -4061:
|
||||
logger.error(f"{symbol} 触发 -4061(持仓模式不匹配),尝试自动兜底重试一次")
|
||||
code = getattr(e, "code", None)
|
||||
if code in (-4061, -1106):
|
||||
retry_params = dict(order_params)
|
||||
if "positionSide" in retry_params:
|
||||
retry_params.pop("positionSide", None)
|
||||
else:
|
||||
ps = await self._resolve_position_side_for_order(symbol, side, reduce_only, position_side)
|
||||
if ps:
|
||||
retry_params["positionSide"] = ps
|
||||
if code == -4061:
|
||||
logger.error(f"{symbol} 触发 -4061(持仓模式不匹配),尝试自动兜底重试一次")
|
||||
if "positionSide" in retry_params:
|
||||
retry_params.pop("positionSide", None)
|
||||
else:
|
||||
ps = await self._resolve_position_side_for_order(symbol, side, reduce_only, position_side)
|
||||
if ps:
|
||||
retry_params["positionSide"] = ps
|
||||
elif code == -1106:
|
||||
# 常见:Parameter 'reduceonly' sent when not required.
|
||||
msg = str(e).lower()
|
||||
if "reduceonly" in msg or "reduce only" in msg:
|
||||
logger.error(f"{symbol} 触发 -1106(reduceOnly 不被接受),去掉 reduceOnly 后重试一次")
|
||||
retry_params.pop("reduceOnly", None)
|
||||
else:
|
||||
raise
|
||||
order = await _submit(retry_params)
|
||||
else:
|
||||
raise
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user