# Stage 07.4.3.2 — Price Polling + EventBus + UI Throttling

## 🎯 Цель этапа

Разделить три независимых процесса автоторговли:

- частое получение рыночной цены;
- анализ стратегии;
- обновление Telegram UI.

Главная цель — убрать постоянное обновление Telegram на каждом цикле анализа и подготовить архитектуру к реальному execution.

---

## 🧱 Что было до этапа

Ранее один runner фактически связывал всё вместе:

```text
run_cycle()
↓
strategy.analyze()
↓
update state
↓
edit Telegram message
```

Из-за этого:

- Telegram мог получать слишком частые `edit_message_text`;
- появлялся риск `Flood control exceeded`;
- частота анализа зависела от UI;
- цена не была выделена в отдельный polling-процесс.

---

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

## 1. MarketDataRunner

Добавлен отдельный runner для быстрого обновления рыночной цены.

Файл:

```text
app/src/integrations/exchange/market_data_runner.py
```

Задача:

```text
каждую 1 секунду:
    получить актуальную цену
    сохранить её в MarketPriceCache
```

Runner работает отдельно от Telegram UI и отдельно от анализа стратегии.

---

## 2. MarketPriceCache

Обновлён кэш рыночных цен.

Файл:

```text
app/src/integrations/exchange/market_cache.py
```

Теперь cache хранит:

- symbol;
- price;
- bid_price;
- ask_price;
- updated_at;
- source.

Кэш становится единым источником актуальной цены для:

- экрана автоторговли;
- стратегии;
- будущего execution engine.

---

## 3. ExchangeService.refresh_price_cache()

В `ExchangeService` добавлен метод:

```python
refresh_price_cache(symbol)
```

Назначение:

- получить цену через REST;
- записать цену в `MarketPriceCache`;
- вернуть `TickerPrice`.

Это позволяет отдельно обновлять цену без прямого обновления Telegram UI.

---

## 4. Кэширование exchangeInfo

В `ExchangeService` добавлен class-level cache:

```python
_exchange_symbols_cache
```

Это нужно, чтобы быстрый price polling не вызывал `exchangeInfo` слишком часто.

Используется class-level доступ:

```python
type(self)._exchange_symbols_cache
```

---

## 5. EventBus

Добавлен простой in-memory EventBus.

Файл:

```text
app/src/core/event_bus.py
```

EventBus хранит:

- текущую версию событий;
- последний тип события;
- последний payload.

Используется для важных изменений:

```text
auto_status_changed
auto_signal_changed
auto_decision_changed
```

---

## 6. AutoTradeService emits events

`AutoTradeService` теперь отправляет события при изменениях:

### Смена статуса автоторговли

```text
OFF → OBSERVING
OBSERVING → RUNNING
RUNNING → OFF
```

Событие:

```text
auto_status_changed
```

### Смена сигнала

```text
HOLD → BUY
BUY → SELL
SELL → HOLD
```

Событие:

```text
auto_signal_changed
```

### Смена decision state

```text
WAITING → CONFIRMING
CONFIRMING → READY
READY → BLOCKED
```

Событие:

```text
auto_decision_changed
```

---

## 7. AutoTradeRunner decoupling

`AutoTradeRunner` теперь разделяет процессы:

```text
MarketDataRunner: 1 сек
Strategy analysis: 5 сек
Telegram UI: 60 сек или событие
```

### Telegram обновляется:

- сразу при важном событии;
- либо раз в 60 секунд;
- только если текст реально изменился;
- с учётом `TelegramRetryAfter`.

---

## 8. UI throttling

Добавлена защита от Telegram flood control:

- не отправлять update, если текст не изменился;
- не обновлять UI чаще заданного интервала;
- учитывать `TelegramRetryAfter`;
- снимать регистрацию, если сообщение удалено.

---

## 🧠 Итоговая архитектура

```text
MarketDataRunner
    ↓
ExchangeService.refresh_price_cache()
    ↓
MarketPriceCache
    ↓
TrendStrategy / Auto UI
    ↓
AutoTradeService
    ↓
EventBus
    ↓
AutoTradeRunner
    ↓
Telegram UI
```

---

## 📂 Изменённые / добавленные файлы

### Добавлены

```text
app/src/core/event_bus.py
app/src/integrations/exchange/market_data_runner.py
```

### Изменены

```text
app/src/trading/auto/runner.py
app/src/trading/auto/service.py
app/src/integrations/exchange/service.py
app/src/integrations/exchange/market_cache.py
app/src/telegram/handlers/auto.py
```

---

## ✅ Проверка

Проверено:

- бот запускается без ошибок;
- цена отображается на экране автоторговли;
- `MarketDataRunner` обновляет цену отдельно;
- Telegram UI не обновляется каждую секунду;
- кнопки не ловят flood control;
- сигнал и decision state обновляются через EventBus;
- экран обновляется сразу при важных изменениях;
- `exchangeInfo` не дергается на каждом price polling.

---

## ⚠️ Ограничения текущего этапа

EventBus пока:

- in-memory;
- без подписчиков;
- без persistence;
- без приоритетов событий.

Это нормально для текущего этапа. Для будущего execution можно расширить EventBus или заменить на более полноценную event-модель.

---

## 🔜 Следующий этап

Рекомендуемый следующий этап:

```text
Stage 07.4.3.3 — Position / Execution Skeleton
```

Возможные задачи:

- модель позиции;
- entry price;
- position size;
- unrealized PnL;
- execution readiness;
- безопасный skeleton исполнения ордеров без реальной отправки.

---

## ✅ Итог

Stage 07.4.3.2 завершает важный архитектурный переход:

```text
от UI-driven автоторговли
к event-driven trading engine
```

Теперь система готова к дальнейшему развитию execution layer.
