a
This commit is contained in:
parent
cd74e96c22
commit
1344435667
|
|
@ -476,7 +476,8 @@ class BinanceClient:
|
|||
side: str,
|
||||
quantity: float,
|
||||
order_type: str = 'MARKET',
|
||||
price: Optional[float] = None
|
||||
price: Optional[float] = None,
|
||||
reduce_only: bool = False
|
||||
) -> Optional[Dict]:
|
||||
"""
|
||||
下单
|
||||
|
|
@ -528,24 +529,27 @@ class BinanceClient:
|
|||
logger.warning(f" 需要增加数量或提高仓位大小")
|
||||
return None
|
||||
|
||||
# 构建订单参数
|
||||
order_params = {
|
||||
'symbol': symbol,
|
||||
'side': side,
|
||||
'type': order_type,
|
||||
'quantity': adjusted_quantity
|
||||
}
|
||||
|
||||
# 如果是平仓订单,添加 reduceOnly 参数
|
||||
if reduce_only:
|
||||
order_params['reduceOnly'] = True
|
||||
logger.debug(f"{symbol} 使用 reduceOnly=True 平仓订单")
|
||||
|
||||
if order_type == 'MARKET':
|
||||
order = await self.client.futures_create_order(
|
||||
symbol=symbol,
|
||||
side=side,
|
||||
type='MARKET',
|
||||
quantity=adjusted_quantity
|
||||
)
|
||||
order = await self.client.futures_create_order(**order_params)
|
||||
else:
|
||||
if price is None:
|
||||
raise ValueError("限价单必须指定价格")
|
||||
order = await self.client.futures_create_order(
|
||||
symbol=symbol,
|
||||
side=side,
|
||||
type='LIMIT',
|
||||
timeInForce='GTC',
|
||||
quantity=adjusted_quantity,
|
||||
price=price
|
||||
)
|
||||
order_params['timeInForce'] = 'GTC'
|
||||
order_params['price'] = price
|
||||
order = await self.client.futures_create_order(**order_params)
|
||||
|
||||
logger.info(f"下单成功: {symbol} {side} {adjusted_quantity} @ {order_type} (名义价值: {notional_value:.2f} USDT)")
|
||||
return order
|
||||
|
|
|
|||
|
|
@ -280,13 +280,24 @@ class PositionManager:
|
|||
f"(持仓数量: {position_amt:.4f})"
|
||||
)
|
||||
|
||||
# 平仓
|
||||
order = await self.client.place_order(
|
||||
symbol=symbol,
|
||||
side=side,
|
||||
quantity=quantity,
|
||||
order_type='MARKET'
|
||||
)
|
||||
# 平仓(使用 reduceOnly=True 确保只减少持仓,不增加反向持仓)
|
||||
try:
|
||||
logger.debug(f"{symbol} [平仓] 调用 place_order: {side} {quantity:.4f} @ MARKET (reduceOnly=True)")
|
||||
order = await self.client.place_order(
|
||||
symbol=symbol,
|
||||
side=side,
|
||||
quantity=quantity,
|
||||
order_type='MARKET',
|
||||
reduce_only=True # 平仓时使用 reduceOnly=True
|
||||
)
|
||||
logger.debug(f"{symbol} [平仓] place_order 返回: {order}")
|
||||
except Exception as order_error:
|
||||
logger.error(f"{symbol} [平仓] ❌ 下单失败: {order_error}")
|
||||
logger.error(f" 下单参数: symbol={symbol}, side={side}, quantity={quantity:.4f}, order_type=MARKET")
|
||||
logger.error(f" 错误类型: {type(order_error).__name__}")
|
||||
import traceback
|
||||
logger.error(f" 完整错误堆栈:\n{traceback.format_exc()}")
|
||||
raise # 重新抛出异常,让外层捕获
|
||||
|
||||
if order:
|
||||
logger.info(f"{symbol} [平仓] ✓ 平仓订单已提交 (订单ID: {order.get('orderId', 'N/A')})")
|
||||
|
|
@ -351,13 +362,48 @@ class PositionManager:
|
|||
f"(原因: {reason})"
|
||||
)
|
||||
return True
|
||||
|
||||
return False
|
||||
else:
|
||||
# place_order 返回 None,说明下单失败
|
||||
logger.error(f"{symbol} [平仓] ❌ 下单返回 None,可能的原因:")
|
||||
logger.error(f" 1. 订单名义价值不足(小于最小要求)")
|
||||
logger.error(f" 2. 数量精度调整后为 0 或负数")
|
||||
logger.error(f" 3. 无法获取价格信息")
|
||||
logger.error(f" 4. 其他下单错误(已在 place_order 中记录)")
|
||||
logger.error(f" 持仓信息: {side} {quantity:.4f} @ MARKET")
|
||||
|
||||
# 尝试获取更多诊断信息
|
||||
try:
|
||||
symbol_info = await self.client.get_symbol_info(symbol)
|
||||
ticker = await self.client.get_ticker_24h(symbol)
|
||||
if ticker:
|
||||
current_price = ticker['price']
|
||||
notional_value = quantity * current_price
|
||||
min_notional = symbol_info.get('minNotional', 5.0) if symbol_info else 5.0
|
||||
logger.error(f" 当前价格: {current_price:.4f} USDT")
|
||||
logger.error(f" 订单名义价值: {notional_value:.2f} USDT")
|
||||
logger.error(f" 最小名义价值: {min_notional:.2f} USDT")
|
||||
if notional_value < min_notional:
|
||||
logger.error(f" ⚠ 订单名义价值不足,无法平仓")
|
||||
except Exception as diag_error:
|
||||
logger.warning(f" 无法获取诊断信息: {diag_error}")
|
||||
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"{symbol} [平仓] ❌ 平仓失败: {e}")
|
||||
logger.error(f" 错误类型: {type(e).__name__}")
|
||||
import traceback
|
||||
logger.error(f" 错误详情:\n{traceback.format_exc()}")
|
||||
logger.error(f" 完整错误堆栈:\n{traceback.format_exc()}")
|
||||
|
||||
# 尝试清理本地记录(即使平仓失败)
|
||||
try:
|
||||
await self._stop_position_monitoring(symbol)
|
||||
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}")
|
||||
|
||||
return False
|
||||
|
||||
async def check_stop_loss_take_profit(self) -> List[str]:
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user