From 2b7e26fd36820e602c34a8fac08f64085cf71103 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=96=87=E8=96=87=E5=AE=89?= Date: Fri, 16 Jan 2026 16:56:35 +0800 Subject: [PATCH] a --- trading_system/binance_client.py | 42 ++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/trading_system/binance_client.py b/trading_system/binance_client.py index ab23e43..cc3fbee 100644 --- a/trading_system/binance_client.py +++ b/trading_system/binance_client.py @@ -754,17 +754,20 @@ class BinanceClient: return None # 最终检查:确保调整后的保证金满足要求 - if required_margin < min_margin_usdt: + # 对于平仓操作(reduce_only=True),跳过最终保证金检查 + if reduce_only: + logger.info(f" 平仓操作:跳过最终保证金检查(保证金: {required_margin:.4f} USDT)") + elif required_margin < min_margin_usdt: logger.error( f"❌ {symbol} 订单保证金不足: {required_margin:.4f} USDT < " f"最小保证金要求: {min_margin_usdt:.2f} USDT,拒绝下单" ) return None - - logger.info( - f" 保证金检查通过: {required_margin:.4f} USDT >= " - f"最小要求: {min_margin_usdt:.2f} USDT (杠杆: {current_leverage}x)" - ) + else: + logger.info( + f" 保证金检查通过: {required_margin:.4f} USDT >= " + f"最小要求: {min_margin_usdt:.2f} USDT (杠杆: {current_leverage}x)" + ) # 构建订单参数 order_params = { @@ -775,9 +778,10 @@ class BinanceClient: } # 如果是平仓订单,添加 reduceOnly 参数 + # 根据币安API文档,reduceOnly 应该是字符串 "true" 或 "false" if reduce_only: - order_params['reduceOnly'] = True - logger.debug(f"{symbol} 使用 reduceOnly=True 平仓订单") + order_params['reduceOnly'] = "true" # 使用字符串格式,符合币安API要求 + logger.info(f"{symbol} 使用 reduceOnly=true 平仓订单") if order_type == 'MARKET': order = await self.client.futures_create_order(**order_params) @@ -792,6 +796,8 @@ class BinanceClient: return order except BinanceAPIException as e: error_code = e.code if hasattr(e, 'code') else None + error_msg = str(e) + if error_code == -1111: logger.error(f"下单失败 {symbol} {side}: 精度错误 - {e}") logger.error(f" 原始数量: {quantity}") @@ -802,8 +808,28 @@ class BinanceClient: logger.error(f" 订单名义价值必须至少为 5 USDT (除非选择 reduce only)") if symbol_info: logger.error(f" 最小名义价值: {symbol_info.get('minNotional', 5.0)} USDT") + elif error_code == -2022: + # ReduceOnly Order is rejected - 可能是没有持仓或持仓方向不对 + logger.error(f"下单失败 {symbol} {side}: ReduceOnly 订单被拒绝 - {e}") + logger.error(f" 可能的原因:") + logger.error(f" 1. 币安账户中没有该交易对的持仓") + logger.error(f" 2. 持仓方向与平仓方向不匹配") + logger.error(f" 3. 持仓数量不足") + elif "reduceOnly" in error_msg.lower() or "reduce only" in error_msg.lower(): + logger.error(f"下单失败 {symbol} {side}: ReduceOnly 相关错误 - {e}") + logger.error(f" 错误码: {error_code}") else: logger.error(f"下单失败 {symbol} {side}: {e}") + logger.error(f" 错误码: {error_code}") + logger.error(f" 下单参数: symbol={symbol}, side={side}, quantity={adjusted_quantity}, type={order_type}, reduceOnly={reduce_only}") + + return None + except Exception as e: + # 捕获其他异常 + logger.error(f"下单失败 {symbol} {side}: 未知错误 - {e}") + logger.error(f" 错误类型: {type(e).__name__}") + import traceback + logger.error(f" 完整错误堆栈:\n{traceback.format_exc()}") return None async def cancel_order(self, symbol: str, order_id: int) -> bool: