Stage 07.4.3.6 — Smart alert throttling
This commit is contained in:
@@ -36,6 +36,10 @@ class AutoTradeRunner:
|
|||||||
_retry_after_until: float = 0.0
|
_retry_after_until: float = 0.0
|
||||||
_last_strong_alert_key: str | None = None
|
_last_strong_alert_key: str | None = None
|
||||||
|
|
||||||
|
# защита от частых одинаковых alert-ов
|
||||||
|
_strong_alert_cooldown_seconds = 120
|
||||||
|
_last_strong_alert_at_by_key: dict[str, float] = {}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def register_screen(
|
def register_screen(
|
||||||
cls,
|
cls,
|
||||||
@@ -187,10 +191,27 @@ class AutoTradeRunner:
|
|||||||
f"{state.decision_status}:{reason}"
|
f"{state.decision_status}:{reason}"
|
||||||
)
|
)
|
||||||
|
|
||||||
if alert_key == cls._last_strong_alert_key:
|
now = time.monotonic()
|
||||||
return
|
last_alert_at = cls._last_strong_alert_at_by_key.get(alert_key)
|
||||||
|
|
||||||
|
if last_alert_at is not None:
|
||||||
|
elapsed = now - last_alert_at
|
||||||
|
|
||||||
|
if elapsed < cls._strong_alert_cooldown_seconds:
|
||||||
|
cls._log_suppressed_strong_alert(
|
||||||
|
signal=signal,
|
||||||
|
symbol=symbol,
|
||||||
|
strategy=strategy,
|
||||||
|
repeat_count=repeat_count,
|
||||||
|
confidence=confidence,
|
||||||
|
leverage=leverage,
|
||||||
|
reason=reason,
|
||||||
|
cooldown_left=round(cls._strong_alert_cooldown_seconds - elapsed, 2),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
cls._last_strong_alert_key = alert_key
|
cls._last_strong_alert_key = alert_key
|
||||||
|
cls._last_strong_alert_at_by_key[alert_key] = now
|
||||||
|
|
||||||
signal_icon = {
|
signal_icon = {
|
||||||
"BUY": "🟢",
|
"BUY": "🟢",
|
||||||
@@ -235,6 +256,39 @@ class AutoTradeRunner:
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _log_suppressed_strong_alert(
|
||||||
|
cls,
|
||||||
|
*,
|
||||||
|
signal: str,
|
||||||
|
symbol: str,
|
||||||
|
strategy: str,
|
||||||
|
repeat_count: int,
|
||||||
|
confidence: float,
|
||||||
|
leverage: object,
|
||||||
|
reason: str,
|
||||||
|
cooldown_left: float,
|
||||||
|
) -> None:
|
||||||
|
try:
|
||||||
|
JournalService().log_ui_info(
|
||||||
|
event_type="auto_strong_signal_alert_suppressed",
|
||||||
|
message=f"Повторное уведомление о сильном сигнале {signal} подавлено.",
|
||||||
|
screen="auto",
|
||||||
|
action="strong_signal_alert",
|
||||||
|
payload={
|
||||||
|
"symbol": symbol,
|
||||||
|
"strategy": strategy,
|
||||||
|
"signal": signal,
|
||||||
|
"repeat_count": repeat_count,
|
||||||
|
"confidence": confidence,
|
||||||
|
"leverage": leverage,
|
||||||
|
"reason": reason,
|
||||||
|
"cooldown_left": cooldown_left,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def _refresh_screen(cls, *, force: bool = False) -> None:
|
async def _refresh_screen(cls, *, force: bool = False) -> None:
|
||||||
now = time.monotonic()
|
now = time.monotonic()
|
||||||
|
|||||||
@@ -166,6 +166,12 @@
|
|||||||
- journal logging for debug actions
|
- journal logging for debug actions
|
||||||
- full pipeline testing without market dependency
|
- full pipeline testing without market dependency
|
||||||
|
|
||||||
|
#### Stage 07.4.3.6 - Smart Alert Throttling ✅
|
||||||
|
- cooldown для Telegram сигналов
|
||||||
|
- suppression повторных BUY/SELL
|
||||||
|
- journal logging suppressed событий
|
||||||
|
- не влияет на execution pipeline
|
||||||
|
|
||||||
### 07.4.4
|
### 07.4.4
|
||||||
⏳ Grid Strategy
|
⏳ Grid Strategy
|
||||||
|
|
||||||
|
|||||||
@@ -154,6 +154,13 @@
|
|||||||
- journal logging for debug actions
|
- journal logging for debug actions
|
||||||
- full pipeline testing without market dependency
|
- full pipeline testing without market dependency
|
||||||
|
|
||||||
|
#### Stage 07.4.3.6 - Smart Alert Throttling ✅
|
||||||
|
|
||||||
|
- cooldown для Telegram сигналов
|
||||||
|
- suppression повторных BUY/SELL
|
||||||
|
- journal logging suppressed событий
|
||||||
|
- не влияет на execution pipeline
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 07.4.4
|
### 07.4.4
|
||||||
|
|||||||
158
docs/stages/stage-07_4_3_6-smart-alert-throttling.md
Normal file
158
docs/stages/stage-07_4_3_6-smart-alert-throttling.md
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
# Stage 07.4.3.6 — Smart Alert Throttling
|
||||||
|
|
||||||
|
## 🎯 Цель
|
||||||
|
|
||||||
|
Добавить интеллектуальное ограничение отправки Telegram-уведомлений о сильных сигналах (BUY / SELL), чтобы:
|
||||||
|
|
||||||
|
* исключить спам при повторяющихся сигналах
|
||||||
|
* сохранить информативность уведомлений
|
||||||
|
* не влиять на execution (открытие/закрытие позиций)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚙️ Основные изменения
|
||||||
|
|
||||||
|
### 1. Cooldown для сигналов
|
||||||
|
|
||||||
|
Добавлено ограничение:
|
||||||
|
|
||||||
|
* одинаковый сигнал (по ключу) не отправляется чаще, чем раз в N секунд
|
||||||
|
* по умолчанию:
|
||||||
|
|
||||||
|
_strong_alert_cooldown_seconds = 120
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2. Уникальный ключ сигнала
|
||||||
|
|
||||||
|
Формируется alert_key:
|
||||||
|
|
||||||
|
symbol + strategy + signal + repeat_count + confidence + decision_status + reason
|
||||||
|
|
||||||
|
Это позволяет:
|
||||||
|
|
||||||
|
* различать похожие сигналы
|
||||||
|
* не блокировать новые реальные сигналы
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3. Хранение времени отправки
|
||||||
|
|
||||||
|
_last_strong_alert_at_by_key: dict[str, float]
|
||||||
|
|
||||||
|
Используется time.monotonic() для стабильного расчёта времени.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 4. Подавление повторных alert-ов
|
||||||
|
|
||||||
|
Если сигнал приходит повторно в пределах cooldown:
|
||||||
|
|
||||||
|
* Telegram-сообщение НЕ отправляется
|
||||||
|
* создаётся запись в журнале:
|
||||||
|
|
||||||
|
event_type = auto_strong_signal_alert_suppressed
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 5. Журналирование suppressed событий
|
||||||
|
|
||||||
|
Фиксируется:
|
||||||
|
|
||||||
|
* сигнал
|
||||||
|
* инструмент
|
||||||
|
* стратегия
|
||||||
|
* confidence
|
||||||
|
* repeat_count
|
||||||
|
* оставшийся cooldown
|
||||||
|
|
||||||
|
Это позволяет:
|
||||||
|
|
||||||
|
* дебажить поведение системы
|
||||||
|
* анализировать частоту сигналов
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧠 Архитектура
|
||||||
|
|
||||||
|
Важно:
|
||||||
|
|
||||||
|
Signal (EventBus)
|
||||||
|
↓
|
||||||
|
Alert (Telegram)
|
||||||
|
↓
|
||||||
|
Execution (отдельно)
|
||||||
|
|
||||||
|
Throttling применяется только к alert-слою:
|
||||||
|
|
||||||
|
* ❌ не влияет на ExecutionEngine
|
||||||
|
* ❌ не влияет на AutoTradeService
|
||||||
|
* ❌ не ломает debug режим
|
||||||
|
* ✅ влияет только на отправку сообщений
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧪 Проверка
|
||||||
|
|
||||||
|
### Сценарий 1 — повтор сигнала
|
||||||
|
|
||||||
|
/debug_signal BUY
|
||||||
|
/debug_signal BUY
|
||||||
|
|
||||||
|
Ожидаемо:
|
||||||
|
|
||||||
|
* 1-й сигнал → сообщение отправлено
|
||||||
|
* 2-й сигнал → подавлен (suppressed)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Сценарий 2 — другой сигнал
|
||||||
|
|
||||||
|
/debug_signal BUY
|
||||||
|
/debug_signal SELL
|
||||||
|
|
||||||
|
Ожидаемо:
|
||||||
|
|
||||||
|
* оба сообщения отправлены
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Сценарий 3 — после cooldown
|
||||||
|
|
||||||
|
Через 120 сек:
|
||||||
|
|
||||||
|
/debug_signal BUY
|
||||||
|
|
||||||
|
Ожидаемо:
|
||||||
|
|
||||||
|
* сообщение снова отправляется
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 📊 Результат
|
||||||
|
|
||||||
|
Система:
|
||||||
|
|
||||||
|
* не спамит одинаковыми сигналами
|
||||||
|
* сохраняет реакцию на новые сигналы
|
||||||
|
* полностью совместима с production execution
|
||||||
|
* логирует подавленные события
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔜 Следующий этап:
|
||||||
|
|
||||||
|
07.4.3.7 — Alert Priority & Aggregation
|
||||||
|
|
||||||
|
🧭 Обновление master-roadmap
|
||||||
|
|
||||||
|
В блоке AutoTrade / Alerts:
|
||||||
|
|
||||||
|
- Smart alert throttling (cooldown + suppression) — completed
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Коммит
|
||||||
|
|
||||||
|
git add .
|
||||||
|
git commit -m "Stage 07.4.3.6 — Smart alert throttling"
|
||||||
Reference in New Issue
Block a user