07.4.4.1.1 — Market State Human UI + HOLD Lifecycle Fix
This commit is contained in:
@@ -0,0 +1,391 @@
|
||||
# 07.4.4.1.1 — Market State Human UI + HOLD Lifecycle Fix
|
||||
|
||||
## Статус
|
||||
|
||||
Этап завершён.
|
||||
|
||||
## Цель этапа
|
||||
|
||||
Цель этапа — довести первый рабочий слой Market State Engine до понятного пользовательского отображения в Auto UI, исправить некорректное журналирование HOLD-серий и подготовить аналитику рынка к дальнейшему использованию в стратегии.
|
||||
|
||||
После этапа 07.4.4.1 в системе уже появился базовый Market State Engine:
|
||||
|
||||
- загрузка свечей через REST `/api/v2/klines`
|
||||
- анализ 200 свечей
|
||||
- поддержка таймфреймов 1m / 5m / 15m
|
||||
- расчёт EMA / ATR / RSI
|
||||
- определение состояния рынка
|
||||
- проброс market analysis в стратегию TREND
|
||||
- блокировка входов при неподходящем рынке
|
||||
|
||||
Но после первичной интеграции оставались проблемы:
|
||||
|
||||
- технический вид строки рынка в Auto UI
|
||||
- отображение `UNKNOWN`, `trend=UNKNOWN`, `volatility=UNKNOWN`
|
||||
- слишком длинный формат market state в Telegram
|
||||
- лишний технический таймфрейм в основном UI
|
||||
- некорректное журналирование `HOLD → HOLD`
|
||||
- ложные события вида `HOLD 37с завершён сигналом HOLD`
|
||||
|
||||
Этап 07.4.4.1.1 устраняет эти проблемы и делает аналитику рынка пригодной для ежедневного наблюдения.
|
||||
|
||||
---
|
||||
|
||||
## Что изменено
|
||||
|
||||
### 1. Market State Engine переведён в human-readable UI
|
||||
|
||||
Техническое отображение рынка было заменено на короткий пользовательский формат.
|
||||
|
||||
Было:
|
||||
|
||||
- `Рынок · TREND_UP · trend=UP · volatility=NORMAL · 5m`
|
||||
- `Рынок · UNKNOWN · trend=UNKNOWN · volatility=UNKNOWN · 5m`
|
||||
|
||||
Стало:
|
||||
|
||||
- `📈 Рынок · Рост`
|
||||
- `📉 Рынок · Падение`
|
||||
- `🟰 Рынок · Флэт`
|
||||
- `⚠️ Рынок · Волатильность`
|
||||
- `⏳ Рынок · Анализ`
|
||||
|
||||
Это делает экран автоторговли понятным без знания внутренних enum-значений.
|
||||
|
||||
---
|
||||
|
||||
### 2. Из основного UI убран технический timeframe
|
||||
|
||||
Таймфрейм анализа, например `5m`, оставлен во внутреннем состоянии и payload, но убран из основного Telegram UI.
|
||||
|
||||
Причина:
|
||||
|
||||
- для стратегии timeframe важен
|
||||
- для пользователя в основном экране он перегружает интерфейс
|
||||
- новичку важнее понять итог: рынок растёт, падает, во флэте или опасен
|
||||
|
||||
Теперь основной Auto UI показывает торговый смысл, а не внутренние настройки движка.
|
||||
|
||||
---
|
||||
|
||||
### 3. Добавлена короткая интерпретация состояний рынка
|
||||
|
||||
Состояния Market State Engine теперь отображаются так:
|
||||
|
||||
| Внутреннее состояние | UI-отображение | Смысл |
|
||||
|---|---|---|
|
||||
| `TREND_UP` | `📈 Рынок · Рост` | Рынок находится в восходящем тренде |
|
||||
| `TREND_DOWN` | `📉 Рынок · Падение` | Рынок находится в нисходящем тренде |
|
||||
| `RANGE` | `🟰 Рынок · Флэт` | Рынок движется боком, тренда нет |
|
||||
| `HIGH_VOLATILITY` | `⚠️ Рынок · Волатильность` | Рынок слишком резкий и опасный для входа |
|
||||
| `LOW_VOLATILITY` | `🟰 Рынок · Спокойный` | Рынок слишком спокойный, импульса мало |
|
||||
| `UNKNOWN` | `⏳ Рынок · Анализ` | Данных ещё мало или анализ временно не определён |
|
||||
|
||||
---
|
||||
|
||||
## Что было сделано в части аналитики
|
||||
|
||||
### 1. REST-свечи стали основой анализа рынка
|
||||
|
||||
До этого стратегия TREND работала в основном по короткому live-окну цен.
|
||||
|
||||
Теперь аналитический слой использует свечи биржи:
|
||||
|
||||
- open
|
||||
- high
|
||||
- low
|
||||
- close
|
||||
- volume
|
||||
|
||||
Простыми словами, свеча показывает, как цена вела себя за выбранный период: где открылась, куда поднималась, куда падала, где закрылась и какой был объём торгов.
|
||||
|
||||
Для начального анализа используются:
|
||||
|
||||
- `1m`
|
||||
- `5m`
|
||||
- `15m`
|
||||
|
||||
В текущей стратегии основным рабочим таймфреймом выбран `5m`.
|
||||
|
||||
---
|
||||
|
||||
### 2. Добавлен расчёт EMA
|
||||
|
||||
EMA — это средняя цена, которая сильнее учитывает последние значения.
|
||||
|
||||
В системе используются:
|
||||
|
||||
- `EMA20` — более быстрая средняя
|
||||
- `EMA50` — более медленная средняя
|
||||
|
||||
Логика простая:
|
||||
|
||||
- если EMA20 выше EMA50 — рынок склоняется к росту
|
||||
- если EMA20 ниже EMA50 — рынок склоняется к падению
|
||||
- если расстояние между EMA маленькое — рынок во флэте
|
||||
|
||||
EMA помогает отличать настоящий тренд от случайного движения цены.
|
||||
|
||||
---
|
||||
|
||||
### 3. Добавлен расчёт ATR
|
||||
|
||||
ATR — это показатель волатильности.
|
||||
|
||||
Простыми словами, ATR показывает, насколько сильно рынок обычно двигается за свечу.
|
||||
|
||||
Если ATR высокий:
|
||||
|
||||
- рынок может резко прыгать
|
||||
- входы становятся опаснее
|
||||
- стопы может выбивать случайным шумом
|
||||
|
||||
Если ATR слишком низкий:
|
||||
|
||||
- рынок почти не движется
|
||||
- сигнал может быть слабым
|
||||
- сделка может долго стоять без результата
|
||||
|
||||
На основе ATR система определяет:
|
||||
|
||||
- нормальную волатильность
|
||||
- слишком высокую волатильность
|
||||
- слишком низкую волатильность
|
||||
|
||||
---
|
||||
|
||||
### 4. Добавлен расчёт RSI
|
||||
|
||||
RSI — это индикатор силы движения.
|
||||
|
||||
Простыми словами, он помогает понять, не перегрет ли рынок.
|
||||
|
||||
RSI пока используется как часть аналитического payload и объяснения, но не является главным фильтром входа.
|
||||
|
||||
Это подготовка к следующим версиям стратегии, где RSI можно будет использовать для:
|
||||
|
||||
- фильтрации поздних входов
|
||||
- защиты от покупки на перегретом росте
|
||||
- защиты от продажи после слишком сильного падения
|
||||
|
||||
---
|
||||
|
||||
### 5. Добавлена классификация состояния рынка
|
||||
|
||||
Market State Engine теперь классифицирует рынок в понятные состояния:
|
||||
|
||||
- `TREND_UP`
|
||||
- `TREND_DOWN`
|
||||
- `RANGE`
|
||||
- `HIGH_VOLATILITY`
|
||||
- `LOW_VOLATILITY`
|
||||
- `UNKNOWN`
|
||||
|
||||
Это важный переход от простой реакции на цену к анализу структуры рынка.
|
||||
|
||||
Раньше стратегия могла видеть только:
|
||||
|
||||
- цена немного выросла
|
||||
- цена немного упала
|
||||
|
||||
Теперь стратегия получает контекст:
|
||||
|
||||
- рынок действительно растёт
|
||||
- рынок действительно падает
|
||||
- рынок во флэте
|
||||
- рынок слишком резкий
|
||||
- рынок слишком спокойный
|
||||
- данных пока недостаточно
|
||||
|
||||
---
|
||||
|
||||
### 6. TREND-стратегия стала market-aware
|
||||
|
||||
TREND теперь использует Market State Engine как фильтр.
|
||||
|
||||
Сигнал BUY возможен только если:
|
||||
|
||||
- Market State Engine видит `TREND_UP`
|
||||
- live-импульс подтверждает движение вверх
|
||||
|
||||
Сигнал SELL возможен только если:
|
||||
|
||||
- Market State Engine видит `TREND_DOWN`
|
||||
- live-импульс подтверждает движение вниз
|
||||
|
||||
Если рынок:
|
||||
|
||||
- `RANGE`
|
||||
- `HIGH_VOLATILITY`
|
||||
- `LOW_VOLATILITY`
|
||||
- `UNKNOWN`
|
||||
|
||||
стратегия возвращает HOLD.
|
||||
|
||||
Это снижает количество случайных входов.
|
||||
|
||||
---
|
||||
|
||||
### 7. Market analysis сохраняется в AutoTradeState
|
||||
|
||||
В состояние автоторговли добавлены поля:
|
||||
|
||||
- `market_state`
|
||||
- `market_trend`
|
||||
- `market_volatility`
|
||||
- `market_analysis_interval`
|
||||
- `market_analysis_reason`
|
||||
|
||||
Теперь UI, журнал и будущие стратегии могут использовать последнее рассчитанное состояние рынка.
|
||||
|
||||
---
|
||||
|
||||
## Исправление HOLD lifecycle bug
|
||||
|
||||
### Проблема
|
||||
|
||||
В журнал попадали события вида:
|
||||
|
||||
- `[DEMO] 🟡 HOLD 37с завершён сигналом HOLD.`
|
||||
|
||||
Это было некорректно.
|
||||
|
||||
Если сигнал был HOLD и следующим сигналом снова стал HOLD, это не завершение серии.
|
||||
|
||||
Правильное завершение должно быть только при реальной смене:
|
||||
|
||||
- `HOLD → BUY`
|
||||
- `HOLD → SELL`
|
||||
- `BUY → HOLD`
|
||||
- `SELL → HOLD`
|
||||
- `BUY → SELL`
|
||||
- `SELL → BUY`
|
||||
|
||||
Но не:
|
||||
|
||||
- `HOLD → HOLD`
|
||||
|
||||
---
|
||||
|
||||
### Причина
|
||||
|
||||
Внутренний `signal_key` включал не только сам сигнал, но и `reason`.
|
||||
|
||||
Из-за этого один и тот же HOLD мог считаться новым сигналом, если изменилась причина.
|
||||
|
||||
Было логически так:
|
||||
|
||||
- HOLD с причиной A
|
||||
- HOLD с причиной B
|
||||
|
||||
Система воспринимала это как смену сигнала, хотя направление не изменилось.
|
||||
|
||||
---
|
||||
|
||||
### Исправление
|
||||
|
||||
`signal_key` был упрощён до устойчивой идентичности сигнала:
|
||||
|
||||
- status
|
||||
- symbol
|
||||
- strategy
|
||||
- signal
|
||||
|
||||
Причина сигнала теперь обновляется внутри текущей серии, но не разрывает её.
|
||||
|
||||
Дополнительно добавлена проверка:
|
||||
|
||||
- summary пишется только если `previous_signal != signal`
|
||||
|
||||
Теперь `HOLD → HOLD` не создаёт ложную запись в журнале.
|
||||
|
||||
---
|
||||
|
||||
## Что больше не должно появляться
|
||||
|
||||
После этапа в журнале больше не должно быть:
|
||||
|
||||
- `HOLD завершён сигналом HOLD`
|
||||
- ложных HOLD summary при изменении причины
|
||||
- технических строк `trend=UNKNOWN`
|
||||
- технических строк `volatility=UNKNOWN`
|
||||
- длинного market-state формата в основном Auto UI
|
||||
|
||||
---
|
||||
|
||||
## Что остаётся в системе
|
||||
|
||||
Market State Engine продолжает сохранять технические данные внутри payload:
|
||||
|
||||
- market_state
|
||||
- trend
|
||||
- volatility
|
||||
- interval
|
||||
- EMA20
|
||||
- EMA50
|
||||
- ATR
|
||||
- ATR percent
|
||||
- RSI
|
||||
- candles count
|
||||
- reason
|
||||
|
||||
Но в основном UI показывается только короткий человекочитаемый итог.
|
||||
|
||||
---
|
||||
|
||||
## Основные изменённые файлы
|
||||
|
||||
- app/src/telegram/handlers/auto/ui.py
|
||||
- app/src/trading/auto/service.py
|
||||
- app/src/trading/auto/state.py
|
||||
- app/src/trading/strategies/trend.py
|
||||
- app/src/trading/market_analysis/models.py
|
||||
- app/src/trading/market_analysis/indicators.py
|
||||
- app/src/trading/market_analysis/service.py
|
||||
- app/src/integrations/exchange/models.py
|
||||
- app/src/integrations/exchange/service.py
|
||||
- app/src/integrations/exchange/rest_client.py
|
||||
|
||||
---
|
||||
|
||||
## Проверка
|
||||
|
||||
После правок необходимо выполнить:
|
||||
|
||||
python -m compileall src
|
||||
python -m src.main
|
||||
|
||||
После запуска проверить:
|
||||
|
||||
1. Автоторговля запускается без ошибок.
|
||||
2. В Auto UI отображается короткая строка рынка:
|
||||
- `📈 Рынок · Рост`
|
||||
- `📉 Рынок · Падение`
|
||||
- `🟰 Рынок · Флэт`
|
||||
- `⚠️ Рынок · Волатильность`
|
||||
- `⏳ Рынок · Анализ`
|
||||
3. В UI больше нет технических строк `trend=...` и `volatility=...`.
|
||||
4. В UI больше не показывается `5m` как техническая деталь.
|
||||
5. При `TREND_UP` стратегия может готовить BUY только после live-подтверждения.
|
||||
6. При `TREND_DOWN` стратегия может готовить SELL только после live-подтверждения.
|
||||
7. При `RANGE`, `HIGH_VOLATILITY`, `LOW_VOLATILITY`, `UNKNOWN` стратегия остаётся в HOLD.
|
||||
8. В журнале больше не появляются события `HOLD завершён сигналом HOLD`.
|
||||
9. HOLD-серия логируется только при переходе к другому сигналу.
|
||||
10. Execution logic не менялась и продолжает работать как раньше.
|
||||
|
||||
---
|
||||
|
||||
## Итог
|
||||
|
||||
Этап 07.4.4.1.1 завершил первичную пользовательскую доводку Market State Engine.
|
||||
|
||||
Система получила:
|
||||
|
||||
- понятное отображение состояния рынка
|
||||
- скрытие технических деталей из основного UI
|
||||
- стабильный lifecycle HOLD-сигналов
|
||||
- исправление ложного журналирования HOLD-серий
|
||||
- полноценную базу аналитики на свечах
|
||||
- подготовку к следующему этапу market-state journal events и дальнейшей стратегии BTC/ETH.
|
||||
|
||||
Это важный переход от простого signal bot к market-aware trading system.
|
||||
Reference in New Issue
Block a user