diff --git a/trading_system/binance_client.py b/trading_system/binance_client.py index c3aa960..941eba7 100644 --- a/trading_system/binance_client.py +++ b/trading_system/binance_client.py @@ -1600,17 +1600,37 @@ class BinanceClient: return False try: - await self.client.futures_cancel_order(symbol=symbol, orderId=order_id) + # 使用更大的 recvWindow,降低在网络抖动时触发 -1021 的概率 + await self.client.futures_cancel_order(symbol=symbol, orderId=order_id, recvWindow=20000) logger.info(f"取消订单成功: {symbol} {order_id}") return True except BinanceAPIException as e: - # -2011 Unknown order sent:订单可能已成交/已撤销/已过期,这是典型幂等场景 - # 取消操作应视为“已达成目标”(不再继续报错刷屏) code = getattr(e, "code", None) msg = str(e) + # -2011 Unknown order sent:订单可能已成交/已撤销/已过期,这是典型幂等场景 if code == -2011 or "code=-2011" in msg or "Unknown order sent" in msg: logger.info(f"取消订单幂等成功(订单可能已不存在): {symbol} {order_id} | {e}") return True + # -1021 时间戳不在 recvWindow 内:尝试同步服务器时间并重试一次 + if code == -1021 or "code=-1021" in msg or "Timestamp for this request is outside of the recvWindow" in msg: + logger.warning(f"取消订单触发 -1021 时间戳错误,尝试同步服务器时间并重试一次: {symbol} {order_id} | {e}") + try: + # 触发一次与服务器对时,让 python-binance 更新内部时间偏差 + await self.client.get_server_time() + except Exception as sync_e: + logger.debug(f"同步币安服务器时间失败(可忽略,继续重试取消): {sync_e}") + try: + await self.client.futures_cancel_order(symbol=symbol, orderId=order_id, recvWindow=20000) + logger.info(f"取消订单重试成功: {symbol} {order_id}") + return True + except BinanceAPIException as e2: + code2 = getattr(e2, "code", None) + msg2 = str(e2) + if code2 == -2011 or "code=-2011" in msg2 or "Unknown order sent" in msg2: + logger.info(f"取消订单幂等成功(重试后订单可能已不存在): {symbol} {order_id} | {e2}") + return True + logger.error(f"取消订单失败(重试后仍错误): {symbol} {order_id} | {e2}") + return False logger.error(f"取消订单失败: {e}") return False @@ -2010,4 +2030,4 @@ class BinanceClient: cache_age = time.time() - cached.get('timestamp', 0) if cache_age < self._price_cache_ttl: return cached.get('price') - return None \ No newline at end of file + return None