a
This commit is contained in:
parent
8d5ea39bd4
commit
d23ed2252c
|
|
@ -72,6 +72,9 @@ class PositionManager:
|
|||
self._monitoring_enabled = True # 是否启用实时监控
|
||||
self._pending_entry_orders: Dict[str, Dict] = {} # 未成交的入场订单(避免重复挂单)
|
||||
self._last_entry_attempt_ms: Dict[str, int] = {} # 每个symbol的最近一次尝试(冷却/去抖)
|
||||
# 自动平仓去抖/限流(避免止损触发后反复下单/刷屏)
|
||||
self._last_auto_close_attempt_ms: Dict[str, int] = {}
|
||||
self._last_auto_close_fail_log_ms: Dict[str, int] = {}
|
||||
|
||||
@staticmethod
|
||||
def _pct_like_to_ratio(v: float) -> float:
|
||||
|
|
@ -2456,6 +2459,20 @@ class PositionManager:
|
|||
|
||||
# 如果触发止损止盈,执行平仓
|
||||
if should_close:
|
||||
# 自动平仓限流:避免同一 symbol 短时间内反复触发平仓请求(WebSocket 高频推送下很常见)
|
||||
try:
|
||||
now_ms = int(time.time() * 1000)
|
||||
except Exception:
|
||||
now_ms = None
|
||||
if now_ms is not None:
|
||||
cooldown_sec = int(config.TRADING_CONFIG.get("AUTO_CLOSE_COOLDOWN_SEC", 20) or 0)
|
||||
last_ms = self._last_auto_close_attempt_ms.get(symbol)
|
||||
if last_ms and cooldown_sec > 0 and now_ms - last_ms < cooldown_sec * 1000:
|
||||
# 不重复刷屏:仅 debug
|
||||
logger.debug(f"{symbol} [自动平仓] 冷却中({cooldown_sec}s),跳过重复平仓尝试")
|
||||
return
|
||||
self._last_auto_close_attempt_ms[symbol] = now_ms
|
||||
|
||||
logger.info(
|
||||
f"{symbol} [自动平仓] 开始执行平仓操作 | "
|
||||
f"原因: {exit_reason} | "
|
||||
|
|
@ -2478,7 +2495,37 @@ class PositionManager:
|
|||
except Exception as sync_error:
|
||||
logger.warning(f"{symbol} [自动平仓] 状态同步失败: {sync_error}")
|
||||
else:
|
||||
logger.error(f"{symbol} [自动平仓] ❌ 平仓失败")
|
||||
# 平仓失败:先二次核对币安是否已无仓位(常见于竞态/网络抖动/幂等场景)
|
||||
live_amt = None
|
||||
try:
|
||||
live_amt = await self._get_live_position_amt(symbol, position_side=None)
|
||||
except Exception:
|
||||
live_amt = None
|
||||
|
||||
if live_amt is not None and abs(live_amt) <= 0:
|
||||
logger.warning(f"{symbol} [自动平仓] 平仓返回失败,但币安持仓已为0,按已平仓处理(避免误报)")
|
||||
# 尝试同步一次,让DB与界面尽快一致(失败也不刷屏)
|
||||
try:
|
||||
await self.sync_positions_with_binance()
|
||||
except Exception:
|
||||
pass
|
||||
return
|
||||
|
||||
# 仍有仓位:减少刷屏(按时间窗口合并/限流)
|
||||
should_log = True
|
||||
if now_ms is not None:
|
||||
log_cd = int(config.TRADING_CONFIG.get("AUTO_CLOSE_FAIL_LOG_COOLDOWN_SEC", 600) or 0)
|
||||
last_log = self._last_auto_close_fail_log_ms.get(symbol)
|
||||
if last_log and log_cd > 0 and now_ms - last_log < log_cd * 1000:
|
||||
should_log = False
|
||||
else:
|
||||
self._last_auto_close_fail_log_ms[symbol] = now_ms
|
||||
|
||||
if should_log:
|
||||
logger.error(f"{symbol} [自动平仓] ❌ 平仓失败(币安持仓仍存在: {live_amt})")
|
||||
else:
|
||||
logger.warning(f"{symbol} [自动平仓] 平仓仍失败(已在短时间内记录,暂不重复输出)")
|
||||
|
||||
# 即使平仓失败,也尝试同步状态(可能币安已经平仓了)
|
||||
try:
|
||||
await self.sync_positions_with_binance()
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user