From e06687b7a5795190f97eca63b380d46f06759ff4 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 17:07:38 +0800 Subject: [PATCH] a --- backend/api/routes/account.py | 57 +++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 12 deletions(-) diff --git a/backend/api/routes/account.py b/backend/api/routes/account.py index af1ad3f..218cd2c 100644 --- a/backend/api/routes/account.py +++ b/backend/api/routes/account.py @@ -407,20 +407,53 @@ async def close_position(symbol: str): side = 'SELL' if position_amt > 0 else 'BUY' quantity = abs(position_amt) - logger.info(f"开始执行平仓操作: {symbol} {side} {quantity:.4f} @ MARKET...") + logger.info(f"开始执行平仓操作: {symbol} {side} {quantity:.4f} @ MARKET (reduceOnly=true)...") - # 直接调用 BinanceClient 平仓(使用 reduceOnly=True) - order = await client.place_order( - symbol=symbol, - side=side, - quantity=quantity, - order_type='MARKET', - reduce_only=True - ) - - if not order: - error_msg = f"{symbol} 平仓失败:下单返回 None,请检查日志" + # 直接调用币安 API 平仓,绕过 BinanceClient 的检查逻辑 + # 对于平仓操作,应该直接使用币安 API,不需要名义价值和保证金检查 + try: + # 获取交易对精度信息,调整数量精度 + symbol_info = await client.get_symbol_info(symbol) + if symbol_info: + quantity_precision = symbol_info.get('quantityPrecision', 8) + step_size = symbol_info.get('stepSize', 0) + min_qty = symbol_info.get('minQty', 0) + + # 调整数量精度 + if step_size > 0: + adjusted_quantity = float(int(quantity / step_size)) * step_size + else: + adjusted_quantity = round(quantity, quantity_precision) + + # 确保不小于最小数量 + if min_qty > 0 and adjusted_quantity < min_qty: + adjusted_quantity = min_qty + + adjusted_quantity = round(adjusted_quantity, quantity_precision) + if adjusted_quantity != quantity: + logger.info(f"数量精度调整: {quantity} -> {adjusted_quantity}") + quantity = adjusted_quantity + + # 直接调用币安 API 下单(使用 reduceOnly="true") + order = await client.client.futures_create_order( + symbol=symbol, + side=side, + type='MARKET', + quantity=quantity, + reduceOnly="true" # 使用字符串格式,符合币安API要求 + ) + + if not order: + error_msg = f"{symbol} 平仓失败:币安API返回 None" + logger.error(error_msg) + raise HTTPException(status_code=500, detail=error_msg) + + except Exception as order_error: + error_msg = f"{symbol} 平仓失败:下单异常 - {str(order_error)}" logger.error(error_msg) + logger.error(f" 错误类型: {type(order_error).__name__}") + import traceback + logger.error(f" 完整错误堆栈:\n{traceback.format_exc()}") raise HTTPException(status_code=500, detail=error_msg) order_id = order.get('orderId')