平仓bug处理

This commit is contained in:
薇薇安 2026-02-03 11:21:50 +08:00
parent 464b6af410
commit cc6750fa47
2 changed files with 56 additions and 22 deletions

View File

@ -713,24 +713,54 @@ class BinanceClient:
Returns:
持仓列表
"""
try:
positions = await self.client.futures_position_information()
open_positions = [
{
'symbol': pos['symbol'],
'positionAmt': float(pos['positionAmt']),
'entryPrice': float(pos['entryPrice']),
'markPrice': float(pos.get('markPrice', 0)),
'unRealizedProfit': float(pos['unRealizedProfit']),
'leverage': int(pos['leverage'])
}
for pos in positions
if float(pos['positionAmt']) != 0
]
return open_positions
except BinanceAPIException as e:
logger.error(f"获取持仓信息失败: {e}")
return []
retries = 3
last_error = None
for attempt in range(retries):
try:
# 增加 recvWindow 以避免 -1021 错误
positions = await self.client.futures_position_information(recvWindow=20000)
open_positions = [
{
'symbol': pos['symbol'],
'positionAmt': float(pos['positionAmt']),
'entryPrice': float(pos['entryPrice']),
'markPrice': float(pos.get('markPrice', 0)),
'unRealizedProfit': float(pos['unRealizedProfit']),
'leverage': int(pos['leverage'])
}
for pos in positions
if float(pos['positionAmt']) != 0
]
return open_positions
except (asyncio.TimeoutError, BinanceAPIException) as e:
last_error = e
# 如果是API异常检查是否是网络相关或服务器错误
is_network_error = False
if isinstance(e, BinanceAPIException):
# -1021: Timestamp for this request is outside of the recvWindow
# 5xx: Server Error
if e.code == -1021 or str(e.code).startswith('5'):
is_network_error = True
else:
# TimeoutError
is_network_error = True
if is_network_error:
if attempt < retries - 1:
logger.warning(f"获取持仓信息失败 (第 {attempt + 1}/{retries} 次): {e},将在 1秒后重试...")
await asyncio.sleep(1)
continue
logger.error(f"获取持仓信息失败: {e}")
return []
except Exception as e:
logger.error(f"获取持仓信息失败: {e}")
return []
if last_error:
logger.error(f"获取持仓信息最终失败 (已重试 {retries} 次): {last_error}")
return []
async def get_recent_trades(self, symbol: str, limit: int = 50) -> List[Dict]:
"""
@ -1309,6 +1339,9 @@ class BinanceClient:
logger.info(f"{symbol} 使用 reduceOnly=true 平仓订单")
async def _submit(params: Dict[str, Any]) -> Dict[str, Any]:
# 增加 recvWindow 以避免 -1021 错误
params['recvWindow'] = 20000
if order_type == 'MARKET':
return await self.client.futures_create_order(**params)
if price is None:

View File

@ -133,7 +133,7 @@ class PositionManager:
last_status = None
while time.time() < deadline:
try:
info = await self.client.client.futures_get_order(symbol=symbol, orderId=order_id)
info = await self.client.client.futures_get_order(symbol=symbol, orderId=order_id, recvWindow=20000)
status = info.get("status")
last_status = status
if status == "FILLED":
@ -913,7 +913,7 @@ class PositionManager:
# 从币安获取订单详情,获取实际成交价格
try:
order_info = await self.client.client.futures_get_order(symbol=symbol, orderId=order_id)
order_info = await self.client.client.futures_get_order(symbol=symbol, orderId=order_id, recvWindow=20000)
if order_info:
# 优先使用平均成交价格avgPrice如果没有则使用价格字段
exit_price = float(order_info.get('avgPrice', 0)) or float(order_info.get('price', 0))
@ -1160,7 +1160,7 @@ class PositionManager:
try:
if not getattr(self.client, "client", None):
return None
res = await self.client.client.futures_position_information(symbol=symbol)
res = await self.client.client.futures_position_information(symbol=symbol, recvWindow=20000)
if not isinstance(res, list):
return None
ps = (position_side or "").upper()
@ -2082,7 +2082,8 @@ class PositionManager:
orders = await self.client.client.futures_get_all_orders(
symbol=symbol,
startTime=start_time,
endTime=end_time
endTime=end_time,
recvWindow=20000
)
# 验证 orders 的类型