같은 캔들에 대한 중복 알림 방지 (per-candle dedup)
## 문제 30s 폴링 × 3캔들 윈도우 × 600s 쿨다운이 맞물려, 동일 캔들에 대한 알림이 한 번 발송된 뒤 쿨다운(10분)이 풀리는 시점에 같은 캔들이 여전히 tail(3) 윈도우 안에 남아있으면(5m 기준 최대 15분 머무름) 두 번째 알림이 다시 발송 되는 현상. ## 변경 사항 - 시그널별로 마지막 발화 캔들의 open_time 을 추적하는 _last_fired_candle dict 추가. - check_and_alert 에서 tail(3) 중 신호가 True 인 가장 최신 캔들의 open_time 을 키로 잡고, 직전 발화와 동일하면 스킵. - 기존 ALERT_COOLDOWN(시간 기반) 가드는 그대로 유지 — 다른 캔들로 신호가 연속 발생할 때의 과다 알림은 여전히 차단. 결과적으로 한 캔들당 시그널 종류별로 1회만 알림이 발송됨. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+14
-3
@@ -53,6 +53,7 @@ BASE = "https://fapi.binance.com"
|
|||||||
KST = timedelta(hours=9)
|
KST = timedelta(hours=9)
|
||||||
|
|
||||||
_last_alert = {"strong_long": 0, "strong_short": 0, "long": 0, "short": 0, "vol_long": 0, "vol_short": 0, "short_caution": 0}
|
_last_alert = {"strong_long": 0, "strong_short": 0, "long": 0, "short": 0, "vol_long": 0, "vol_short": 0, "short_caution": 0}
|
||||||
|
_last_fired_candle = {"strong_long": None, "strong_short": None, "long": None, "short": None, "vol_long": None, "vol_short": None, "short_caution": None}
|
||||||
|
|
||||||
# ──────────────────────────────────────────────
|
# ──────────────────────────────────────────────
|
||||||
# 텔레그램
|
# 텔레그램
|
||||||
@@ -76,9 +77,19 @@ def check_and_alert(df, symbol, interval):
|
|||||||
("vol_short_signal", "vol_short", f"🔽 볼륨급등 숏 신호\n{symbol} {interval}"),
|
("vol_short_signal", "vol_short", f"🔽 볼륨급등 숏 신호\n{symbol} {interval}"),
|
||||||
("short_caution_signal","short_caution",f"⚠️ 숏 진입 주의 신호\n{symbol} {interval}"),
|
("short_caution_signal","short_caution",f"⚠️ 숏 진입 주의 신호\n{symbol} {interval}"),
|
||||||
]:
|
]:
|
||||||
if sig in recent.columns and recent[sig].fillna(False).any() and now - _last_alert[key] > ALERT_COOLDOWN:
|
if sig not in recent.columns:
|
||||||
send_telegram(msg)
|
continue
|
||||||
_last_alert[key] = now
|
triggered = recent[recent[sig].fillna(False)]
|
||||||
|
if triggered.empty:
|
||||||
|
continue
|
||||||
|
candle_time = triggered.iloc[-1]["open_time"]
|
||||||
|
if candle_time == _last_fired_candle.get(key):
|
||||||
|
continue
|
||||||
|
if now - _last_alert[key] <= ALERT_COOLDOWN:
|
||||||
|
continue
|
||||||
|
send_telegram(msg)
|
||||||
|
_last_alert[key] = now
|
||||||
|
_last_fired_candle[key] = candle_time
|
||||||
|
|
||||||
# ──────────────────────────────────────────────
|
# ──────────────────────────────────────────────
|
||||||
# 데이터 수집
|
# 데이터 수집
|
||||||
|
|||||||
Reference in New Issue
Block a user