# 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.
