07.4.4.1.6 — Signal Aging & Runtime Expiration
This commit is contained in:
@@ -0,0 +1,261 @@
|
||||
# 07.4.4.1.6 — Signal Aging & Runtime Expiration
|
||||
|
||||
## Цель этапа
|
||||
|
||||
Добавить слой контроля возраста runtime-состояния автоторговли, чтобы сигналы, market analysis и внутренние окна стратегий не жили бесконечно и не влияли на новые решения после пауз, смены актива, смены стратегии или простоя рынка.
|
||||
|
||||
Этап закрывает проблему “устаревшего runtime”:
|
||||
|
||||
- старый BUY/SELL не должен продолжаться после долгой паузы;
|
||||
- READY-состояние не должно сохраняться бесконечно;
|
||||
- market diagnostics не должны визуально залипать;
|
||||
- runtime-окна стратегий не должны использовать старые цены после простоя;
|
||||
- HOLD lifecycle должен оставаться живым и понятным в UI.
|
||||
|
||||
---
|
||||
|
||||
## Что было до этапа
|
||||
|
||||
До внедрения Signal Aging runtime-состояние было логически изолировано по активам и стратегиям, но не имело срока жизни.
|
||||
|
||||
Это означало, что:
|
||||
|
||||
- `_price_window` мог хранить старые цены;
|
||||
- `last_signal` мог оставаться актуальным дольше, чем фактический рынок;
|
||||
- `READY` мог визуально выглядеть свежим, хотя сигнал уже устарел;
|
||||
- market diagnostics могли оставаться на экране после смены условий;
|
||||
- пользователь видел состояние, но не всегда понимал, насколько оно свежее.
|
||||
|
||||
---
|
||||
|
||||
## Что внедрено
|
||||
|
||||
### 1. Signal aging fields в AutoTradeState
|
||||
|
||||
В состояние автоторговли добавлены поля для отслеживания возраста runtime:
|
||||
|
||||
```python
|
||||
signal_updated_at
|
||||
market_analysis_updated_at
|
||||
runtime_expired_reason
|
||||
runtime_expired_message
|
||||
```
|
||||
|
||||
Теперь состояние знает:
|
||||
|
||||
- когда последний раз обновлялся сигнал;
|
||||
- когда последний раз обновлялась аналитика рынка;
|
||||
- была ли runtime-информация сброшена по expiration;
|
||||
- почему она была сброшена.
|
||||
|
||||
---
|
||||
|
||||
### 2. Signal TTL
|
||||
|
||||
Добавлен TTL для сигналов:
|
||||
|
||||
```python
|
||||
_signal_ttl_seconds = 90
|
||||
```
|
||||
|
||||
Если сигнал живёт дольше допустимого времени без актуального обновления, runtime сбрасывается.
|
||||
|
||||
Это защищает от ситуаций:
|
||||
|
||||
```text
|
||||
BUY появился
|
||||
↓
|
||||
бот/рынок/цикл остановился
|
||||
↓
|
||||
через долгое время BUY всё ещё считается актуальным
|
||||
```
|
||||
|
||||
Теперь такой сигнал считается устаревшим и должен быть пересобран заново.
|
||||
|
||||
---
|
||||
|
||||
### 3. Market analysis TTL
|
||||
|
||||
Добавлен TTL для market diagnostics:
|
||||
|
||||
```python
|
||||
_market_analysis_ttl_seconds = 180
|
||||
```
|
||||
|
||||
Если анализ рынка устарел, очищаются:
|
||||
|
||||
```python
|
||||
market_state
|
||||
market_trend
|
||||
market_volatility
|
||||
market_analysis_interval
|
||||
market_analysis_reason
|
||||
entry_block_reason
|
||||
entry_block_message
|
||||
```
|
||||
|
||||
Это предотвращает визуальное залипание старого состояния рынка.
|
||||
|
||||
---
|
||||
|
||||
### 4. Runtime expiration handler
|
||||
|
||||
В AutoTradeService добавлен метод:
|
||||
|
||||
```python
|
||||
_expire_runtime_if_needed()
|
||||
```
|
||||
|
||||
Он проверяет возраст:
|
||||
|
||||
- текущего сигнала;
|
||||
- последнего market analysis;
|
||||
- runtime diagnostics.
|
||||
|
||||
При необходимости он сбрасывает устаревшие данные и подготавливает state к новой оценке рынка.
|
||||
|
||||
---
|
||||
|
||||
### 5. Runtime expiration logging
|
||||
|
||||
Добавлено событие журнала:
|
||||
|
||||
```python
|
||||
runtime_expired
|
||||
```
|
||||
|
||||
Оно используется для фиксации случаев, когда runtime был сброшен по TTL.
|
||||
|
||||
Логика защищена от spam logging одинаковых expiration-событий.
|
||||
|
||||
---
|
||||
|
||||
### 6. Runtime window TTL для TREND
|
||||
|
||||
В TrendStrategy добавлен TTL live-окна:
|
||||
|
||||
```python
|
||||
_window_ttl_seconds = 60
|
||||
_price_window_updated_at
|
||||
```
|
||||
|
||||
Теперь live-окно TREND очищается, если между обновлениями был слишком большой разрыв.
|
||||
|
||||
Это защищает от анализа старых цен как будто они свежие.
|
||||
|
||||
---
|
||||
|
||||
### 7. Runtime window TTL для SCALP
|
||||
|
||||
В ScalpStrategy добавлен отдельный TTL:
|
||||
|
||||
```python
|
||||
_window_ttl_seconds = 30
|
||||
_price_window_updated_at
|
||||
```
|
||||
|
||||
SCALP чувствительнее к времени, поэтому его окно живёт меньше.
|
||||
|
||||
---
|
||||
|
||||
### 8. Runtime reset теперь очищает не только цены
|
||||
|
||||
`reset_runtime()` теперь очищает:
|
||||
|
||||
- `_price_window`;
|
||||
- `_price_window_updated_at`.
|
||||
|
||||
Это важно, потому что сам факт времени последнего обновления тоже является runtime-состоянием.
|
||||
|
||||
---
|
||||
|
||||
### 9. UI продолжает показывать HOLD duration
|
||||
|
||||
Строка:
|
||||
|
||||
```text
|
||||
Сигнал 🟡 HOLD · 27с
|
||||
```
|
||||
|
||||
оставлена намеренно.
|
||||
|
||||
Это не торговый сигнал, а индикатор живого runtime-цикла:
|
||||
|
||||
- экран обновляется;
|
||||
- HOLD не залип;
|
||||
- цикл автоторговли работает;
|
||||
- пользователь видит возраст текущего режима ожидания.
|
||||
|
||||
---
|
||||
|
||||
### 10. Compact Telegram UI
|
||||
|
||||
В рамках проверки этапа UI был приведён к более короткому виду.
|
||||
|
||||
Market state теперь отображается компактно:
|
||||
|
||||
```python
|
||||
"TREND_UP": "📈 Тренд · Вверх"
|
||||
"TREND_DOWN": "📉 Тренд · Вниз"
|
||||
"RANGE": "🟰 Рынок · Флэт"
|
||||
"HIGH_VOLATILITY": "⚠️ Рынок · Высокая волатильность"
|
||||
"LOW_VOLATILITY": "🟰 Рынок · Низкая активность"
|
||||
```
|
||||
|
||||
Entry diagnostics разделены по смыслу:
|
||||
|
||||
```text
|
||||
Ожидание · слабый импульс
|
||||
Вход · слабый импульс
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Проверка этапа
|
||||
|
||||
Проверено на live UI:
|
||||
|
||||
- HOLD timer работает;
|
||||
- market state отображается компактно;
|
||||
- после runtime reset старые данные не протекают;
|
||||
- UI не залипает на старом активе;
|
||||
- entry diagnostics стали короче;
|
||||
- runtime state не смешивается между активами;
|
||||
- выбранный актив отображается корректно;
|
||||
- подготовка ордера продолжает рассчитываться штатно.
|
||||
|
||||
---
|
||||
|
||||
## Что обнаружено дополнительно
|
||||
|
||||
На LTC был выявлен uncovered HOLD diagnostic сценарий:
|
||||
|
||||
```text
|
||||
Сигнал 🟡 HOLD
|
||||
📉 Тренд · Вниз
|
||||
```
|
||||
|
||||
При этом UI не показал причину, почему при нисходящем тренде не был выдан SELL.
|
||||
|
||||
Причина: не все HOLD-ветки TrendStrategy передают `entry_block_reason` и `entry_block_message`.
|
||||
|
||||
Это не блокер этапа 07.4.4.1.6, потому что относится не к aging, а к полноте диагностического слоя стратегии.
|
||||
|
||||
Рекомендуется вынести в следующий этап:
|
||||
|
||||
```text
|
||||
Advanced Market Diagnostics Layer
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Итог этапа
|
||||
|
||||
Этап 07.4.4.1.6 добавил фундамент runtime expiration:
|
||||
|
||||
- сигналы получили возраст;
|
||||
- market analysis получил возраст;
|
||||
- runtime-окна стратегий получили TTL;
|
||||
- stale state теперь можно сбрасывать;
|
||||
- UI показывает живое состояние runtime;
|
||||
- система подготовлена к adaptive thresholds и расширенной диагностике входа.
|
||||
Reference in New Issue
Block a user