# 07.4.4.1.4 — Entry Decision Diagnostics Layer

## Цель этапа

Добавить диагностический слой, который объясняет, почему автоторговля не входит в позицию, даже если рынок движется.

До этого этапа пользователь видел в интерфейсе в основном `HOLD`, но не всегда понимал причину:

- рынок не подходит для входа
- live-импульс слишком слабый
- недостаточно live-данных
- сигнал ещё не подтверждён
- execution не готов открыть позицию
- размер позиции ограничен настройками защиты

Этап сделал поведение автоторговли более прозрачным и подготовил систему к дальнейшей настройке стратегии.

---

# Что было реализовано

## 1. Добавлен Entry Decision Diagnostics Layer

В систему добавлен отдельный слой диагностики входа в позицию.

Теперь стратегия не просто возвращает `HOLD`, а дополнительно передаёт причину, почему вход не выполнен.

Это важно, потому что `HOLD` может означать разные ситуации:

- безопасное ожидание
- рынок без выраженного направления
- слабый импульс
- недостаточно live-данных
- неподходящая волатильность
- техническая ошибка получения рыночных данных

После этапа эти причины стали видимыми в runtime state, UI и журнале.

---

# 2. Добавлены поля диагностики входа в AutoTradeState

В `AutoTradeState` добавлены новые поля:

- `entry_block_reason`
- `entry_block_message`

`entry_block_reason` хранит технический код причины.

Примеры:

- `MARKET_FILTER_BLOCKED`
- `LIVE_DATA_WAITING`
- `WEAK_UP_IMPULSE`
- `WEAK_DOWN_IMPULSE`
- `INVALID_PRICE`
- `SNAPSHOT_ERROR`

`entry_block_message` хранит человекочитаемое объяснение.

Примеры:

- «рынок сейчас не подходит для входа»
- «недостаточно live-данных для подтверждения»
- «слабый импульс вверх»
- «слабый импульс вниз»

---

# 3. TrendStrategy начала отдавать причины отказа от входа

В `TrendStrategy` причины HOLD были расширены диагностическими payload-полями.

Теперь, когда стратегия не даёт BUY или SELL, она передаёт:

- почему вход не разрешён
- какой market state был в момент решения
- какой live-импульс был рассчитан
- сколько live-цен накоплено
- какой threshold не был пройден
- какой direction ratio был получен

Это особенно важно для анализа ситуаций, когда визуально рынок движется, но бот всё равно не входит в позицию.

Например, рынок может расти последние несколько свечей, но стратегия всё ещё может не входить, если:

- общий market state не подтверждает тренд
- live-импульс ниже порога
- движение недостаточно устойчивое
- подтверждение сигнала ещё не накоплено

---

# 4. AutoTradeService синхронизирует entry diagnostics

`AutoTradeService` теперь забирает `entry_block_reason` и `entry_block_message` из payload стратегии и сохраняет их в текущем состоянии автоторговли.

Это позволило использовать одну и ту же диагностику сразу в нескольких местах:

- Auto UI
- журнал
- future analytics layer
- future filters/search layer
- future AI explanation layer

---

# 5. Добавлено журналирование причин не входа

Добавлено событие:

- `entry_blocked`

Журнал теперь фиксирует не только готовые сигналы и открытие позиций, но и важные причины, почему позиция не была открыта.

Формат сообщения:

```text
[DEMO] Вход в позицию не выполнен: слабый импульс вверх.
```

или:

```text
[DEMO] Вход в позицию не выполнен: рынок сейчас не подходит для входа.
```

Это позволяет оставить автоторговлю работать долго и потом понять, почему за период не было сделок.

---

# 6. Добавлена защита от spam logging

Причины не входа не пишутся в журнал на каждом цикле.

Система пишет событие только тогда, когда причина изменилась.

Например, если бот 30 минут подряд не входит из-за слабого импульса, журнал не будет получать одинаковые записи каждые 5 секунд.

Если причина изменилась, например:

- было: слабый импульс вверх
- стало: рынок без выраженного направления

тогда будет записано новое событие.

Это сохраняет журнал полезным и не превращает его в поток повторяющихся HOLD-сообщений.

---

# 7. Auto UI начал показывать причину не входа

На экране автоторговли добавлена строка диагностики:

```text
Вход в позицию · слабый импульс вверх
```

или:

```text
Вход в позицию · рынок сейчас не подходит для входа
```

Теперь пользователь видит не просто `HOLD`, а понимает, почему бот ждёт.

---

# 8. Strategy diagnostics отделены от execution diagnostics

В UI теперь логически разделены два разных типа причин.

## Entry diagnostics

Отвечает на вопрос:

```text
Почему стратегия не хочет входить в позицию?
```

Примеры:

- рынок не подходит
- слабый импульс
- недостаточно данных

## Execution diagnostics

Отвечает на вопрос:

```text
Почему позиция не может быть технически открыта?
```

Примеры:

- ограничение Max Reserved
- execution block
- невозможность рассчитать размер позиции

Это разделение важно, потому что раньше разные причины могли восприниматься как одна проблема.

---

# 9. UI-тексты приведены к единому human-readable стилю

Устаревшие технические строки были приведены к более понятному виду.

Например:

- `Blocked · ...` заменено на `Исполнение · ...`
- `Size adjusted by Max Reserved` заменено на `Позиция ограничена настройкой Max Reserved.`
- `Вход не выполнен` уточнено до `Вход в позицию не выполнен`

Это делает интерфейс понятнее для пользователя, который не обязан знать внутреннюю архитектуру execution layer.

---

# 10. Добавлен event title для entry diagnostics

В общий mapping заголовков событий добавлен event title:

```python
"entry_blocked": "Вход"
```

Так журнал сохраняет короткую структуру:

```text
Вход | [DEMO] Вход в позицию не выполнен: слабый импульс вверх.
```

Заголовок остаётся коротким, а смысл раскрывается в сообщении.

---

# Изменения в архитектуре

## Strategy Layer

`TrendStrategy` теперь не только формирует торговый сигнал, но и объясняет причины отказа от входа.

Добавлены диагностические payload-поля:

- `entry_block_reason`
- `entry_block_message`

---

## Auto Runtime Layer

`AutoTradeService` теперь синхронизирует entry diagnostics в runtime state и журнал.

Добавлено антиспам-логирование причин не входа.

---

## Auto State Layer

`AutoTradeState` расширен полями диагностики входа:

- `entry_block_reason`
- `entry_block_message`

---

## Auto UI Layer

На экран автоторговли добавлено отображение причины не входа.

Также execution diagnostics приведён к более понятному стилю.

---

## Journal Layer

Добавлено событие:

- `entry_blocked`

Событие пишет только изменение причины отказа от входа, а не каждый HOLD-цикл.

---

# Что изменилось для пользователя

Пользователь теперь видит не просто:

```text
Сигнал HOLD
```

А получает объяснение:

```text
Сигнал HOLD
Вход в позицию · слабый импульс вверх
```

или:

```text
Сигнал HOLD
Вход в позицию · рынок сейчас не подходит для входа
```

Также пользователь может открыть журнал и увидеть, почему бот не входил в позицию в течение длительного времени.

Это особенно важно для paper trading и подготовки к реальной торговле.

---

# Почему это важно для стратегии

До этого этапа было трудно отличить нормальное ожидание от проблемы.

Теперь можно понять:

- стратегия слишком строгая
- market filter слишком часто блокирует вход
- live threshold слишком высокий
- direction ratio слишком требовательный
- не хватает накопленных live-данных
- execution layer блокирует уже готовый сигнал

Это создаёт основу для дальнейшей настройки торговой стратегии не на ощущениях, а по фактическим причинам отказа от входа.

---

# Что подготовлено дальше

Этап подготовил основу для следующих работ:

- анализ частоты причин отказа от входа
- adaptive thresholds
- настройка чувствительности TrendStrategy
- очистка `_price_window` при смене актива
- signal aging / signal reset
- multi-symbol runtime isolation
- entry diagnostics filters в журнале
- статистика HOLD-причин
- AI-комментарии по причинам не входа
