diff --git a/crypto_monitor_binance/app.py b/crypto_monitor_binance/app.py index 1a41356..f2bf368 100644 --- a/crypto_monitor_binance/app.py +++ b/crypto_monitor_binance/app.py @@ -272,6 +272,22 @@ def send_wechat_msg(content): pass +_BREAKEVEN_EXCHANGE_WARNED_IDS = set() + + +def _send_breakeven_exchange_warn_once(order_id, message): + """移动保本同步交易所失败:同一笔监控单只推送一次,避免轮询刷屏。""" + oid = int(order_id) + if oid in _BREAKEVEN_EXCHANGE_WARNED_IDS: + return + _BREAKEVEN_EXCHANGE_WARNED_IDS.add(oid) + send_wechat_msg(message) + + +def _clear_breakeven_exchange_warn(order_id): + _BREAKEVEN_EXCHANGE_WARNED_IDS.discard(int(order_id)) + + def _wechat_account_label(): return (os.getenv("BINANCE_ACCOUNT_LABEL") or "binance实盘账户").strip() @@ -4958,6 +4974,7 @@ def check_order_monitors(): direction == "long" and new_sl > float(stop_loss) ) if should_move: + was_armed = breakeven_armed ex_sym = resolve_monitor_exchange_symbol(r) new_sl = round_price_to_exchange(ex_sym, new_sl) tp_ex = float(take_profit or 0) @@ -4967,13 +4984,15 @@ def check_order_monitors(): try: replace_active_monitor_tpsl_on_exchange(r, new_sl, tp_ex) synced_ex = True + _clear_breakeven_exchange_warn(pid) except Exception as e: print( f"[breakeven] exchange tpsl replace failed order={pid} {sym}: {e}", flush=True, ) - send_wechat_msg( - f"⚠️ {sym} 移动保本止损未同步交易所:{friendly_exchange_error(e)}" + _send_breakeven_exchange_warn_once( + pid, + f"⚠️ {sym} 移动保本止损未同步交易所:{friendly_exchange_error(e)}", ) elif ok_live: print( @@ -4986,18 +5005,20 @@ def check_order_monitors(): (new_sl, new_sl, pid), ) stop_loss = new_sl - arm_txt = "保本止盈" if not breakeven_armed else "移动止盈" - be_msg = build_wechat_breakeven_message( - sym, - direction, - arm_txt, - now_rr, - locked_r, - new_sl, - ) - if ok_live: - be_msg += "\n- 交易所:已先撤后挂止盈止损" - send_wechat_msg(be_msg) + breakeven_armed = 1 + if not was_armed: + arm_txt = "保本止盈" + be_msg = build_wechat_breakeven_message( + sym, + direction, + arm_txt, + now_rr, + locked_r, + new_sl, + ) + if ok_live: + be_msg += "\n- 交易所:已先撤后挂止盈止损" + send_wechat_msg(be_msg) res = None # 做多 diff --git a/crypto_monitor_gate/app.py b/crypto_monitor_gate/app.py index b5bc027..c925020 100644 --- a/crypto_monitor_gate/app.py +++ b/crypto_monitor_gate/app.py @@ -266,6 +266,22 @@ def send_wechat_msg(content): pass +_BREAKEVEN_EXCHANGE_WARNED_IDS = set() + + +def _send_breakeven_exchange_warn_once(order_id, message): + """移动保本同步交易所失败:同一笔监控单只推送一次,避免轮询刷屏。""" + oid = int(order_id) + if oid in _BREAKEVEN_EXCHANGE_WARNED_IDS: + return + _BREAKEVEN_EXCHANGE_WARNED_IDS.add(oid) + send_wechat_msg(message) + + +def _clear_breakeven_exchange_warn(order_id): + _BREAKEVEN_EXCHANGE_WARNED_IDS.discard(int(order_id)) + + def _wechat_account_label(): return (os.getenv("GATE_ACCOUNT_LABEL") or "gate实盘账户").strip() @@ -4817,6 +4833,7 @@ def check_order_monitors(): direction == "long" and new_sl > float(stop_loss) ) if should_move: + was_armed = breakeven_armed ex_sym = resolve_monitor_exchange_symbol(r) new_sl = round_price_to_exchange(ex_sym, new_sl) tp_ex = float(take_profit or 0) @@ -4826,13 +4843,15 @@ def check_order_monitors(): try: replace_active_monitor_tpsl_on_exchange(r, new_sl, tp_ex) synced_ex = True + _clear_breakeven_exchange_warn(pid) except Exception as e: print( f"[breakeven] exchange tpsl replace failed order={pid} {sym}: {e}", flush=True, ) - send_wechat_msg( - f"⚠️ {sym} 移动保本止损未同步交易所:{friendly_exchange_error(e)}" + _send_breakeven_exchange_warn_once( + pid, + f"⚠️ {sym} 移动保本止损未同步交易所:{friendly_exchange_error(e)}", ) elif ok_live: print( @@ -4845,18 +4864,20 @@ def check_order_monitors(): (new_sl, new_sl, pid), ) stop_loss = new_sl - arm_txt = "保本止盈" if not breakeven_armed else "移动止盈" - be_msg = build_wechat_breakeven_message( - sym, - direction, - arm_txt, - now_rr, - locked_r, - new_sl, - ) - if ok_live: - be_msg += "\n- 交易所:已先撤后挂止盈止损" - send_wechat_msg(be_msg) + breakeven_armed = 1 + if not was_armed: + arm_txt = "保本止盈" + be_msg = build_wechat_breakeven_message( + sym, + direction, + arm_txt, + now_rr, + locked_r, + new_sl, + ) + if ok_live: + be_msg += "\n- 交易所:已先撤后挂止盈止损" + send_wechat_msg(be_msg) res = None # 做多 diff --git a/crypto_monitor_gate_bot/app.py b/crypto_monitor_gate_bot/app.py index fbf48e6..7e2decd 100644 --- a/crypto_monitor_gate_bot/app.py +++ b/crypto_monitor_gate_bot/app.py @@ -263,6 +263,22 @@ def send_wechat_msg(content): pass +_BREAKEVEN_EXCHANGE_WARNED_IDS = set() + + +def _send_breakeven_exchange_warn_once(order_id, message): + """移动保本同步交易所失败:同一笔监控单只推送一次,避免轮询刷屏。""" + oid = int(order_id) + if oid in _BREAKEVEN_EXCHANGE_WARNED_IDS: + return + _BREAKEVEN_EXCHANGE_WARNED_IDS.add(oid) + send_wechat_msg(message) + + +def _clear_breakeven_exchange_warn(order_id): + _BREAKEVEN_EXCHANGE_WARNED_IDS.discard(int(order_id)) + + def _wechat_account_label(): return (os.getenv("GATE_ACCOUNT_LABEL") or "gate实盘账户").strip() @@ -4644,6 +4660,7 @@ def check_order_monitors(): direction == "long" and new_sl > float(stop_loss) ) if should_move: + was_armed = breakeven_armed ex_sym = resolve_monitor_exchange_symbol(r) new_sl = round_price_to_exchange(ex_sym, new_sl) tp_ex = float(take_profit or 0) @@ -4653,13 +4670,15 @@ def check_order_monitors(): try: replace_active_monitor_tpsl_on_exchange(r, new_sl, tp_ex) synced_ex = True + _clear_breakeven_exchange_warn(pid) except Exception as e: print( f"[breakeven] exchange tpsl replace failed order={pid} {sym}: {e}", flush=True, ) - send_wechat_msg( - f"⚠️ {sym} 移动保本止损未同步交易所:{friendly_exchange_error(e)}" + _send_breakeven_exchange_warn_once( + pid, + f"⚠️ {sym} 移动保本止损未同步交易所:{friendly_exchange_error(e)}", ) elif ok_live: print( @@ -4672,18 +4691,20 @@ def check_order_monitors(): (new_sl, new_sl, pid), ) stop_loss = new_sl - arm_txt = "保本止盈" if not breakeven_armed else "移动止盈" - be_msg = build_wechat_breakeven_message( - sym, - direction, - arm_txt, - now_rr, - locked_r, - new_sl, - ) - if ok_live: - be_msg += "\n- 交易所:已先撤后挂止盈止损" - send_wechat_msg(be_msg) + breakeven_armed = 1 + if not was_armed: + arm_txt = "保本止盈" + be_msg = build_wechat_breakeven_message( + sym, + direction, + arm_txt, + now_rr, + locked_r, + new_sl, + ) + if ok_live: + be_msg += "\n- 交易所:已先撤后挂止盈止损" + send_wechat_msg(be_msg) res = None # 做多