# Build 023 — Миграция runtime-потребителей на канонический Instrument Reference

**Статус:** ✅ Завершён  
**Дата:** 2026-07-12  
**Подсистема:** Exchange Integration  
**Этап:** Instrument Reference Migration

---

# Цель Build

Перевести runtime-компоненты получения рыночных данных на использование канонического справочника инструментов (`Instrument Reference`), полностью отказавшись от любых зависимостей от legacy-проекций `ExchangeSymbol`.

Build является логическим продолжением Build 022 и завершает миграцию всех runtime-потребителей ExchangeService.

---

# Причина изменений

После завершения Build 022 основная логика ExchangeService уже использовала новый механизм:

```
Instrument Store
        ↓
get_instruments()
        ↓
validate_symbol()
```

Однако требовалось убедиться, что runtime-компоненты также используют исключительно новый контракт и не имеют скрытых зависимостей от legacy-моделей.

Проверке подлежали:

- `market_stream.py`
- `market_data_runner.py`

---

# Выполненный анализ

Проведён аудит файлов:

```
src/integrations/exchange/market_stream.py
src/integrations/exchange/market_data_runner.py
```

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

- validate_symbol()
- normalized_symbol
- symbol_info
- get_exchange_symbols()
- ExchangeSymbol
- Instrument

---

# Результаты анализа

Установлено следующее.

## Market Stream

Используется:

```python
validation = service.validate_symbol(...)
```

После успешной проверки используется:

```python
validation.normalized_symbol
```

Объект `symbol_info` нигде не читается.

Модель `ExchangeSymbol` не используется.

Получение списка инструментов напрямую отсутствует.

---

## Market Data Runner

Используется:

```python
validation = ExchangeService().validate_symbol(...)
```

После успешной проверки используется:

```python
validation.normalized_symbol
```

При ошибке валидации сохраняется безопасный fallback:

```text
исходный symbol
```

Обращений к:

- symbol_info
- ExchangeSymbol
- get_exchange_symbols()

не обнаружено.

---

# Изменения Production-кода

Изменения Production-кода не потребовались.

Build подтвердил, что оба runtime-компонента уже полностью соответствуют новой архитектуре Instrument Reference.

---

# Добавлены Unit-тесты

Создан:

```
tests/unit/integrations/exchange/test_market_stream.py
```

Проверяются следующие сценарии.

### Использование normalized_symbol

Проверяется, что WebSocket запускается для канонического символа.

---

### Отсутствие зависимости от symbol_info

Проверяется отсутствие чтения:

```python
validation.symbol_info
```

---

### Обработка невалидного символа

Проверяется, что:

- WebSocket не создаётся;
- используется результат validate_symbol().

---

### Exchange Disabled

Проверяется, что при отключённой бирже:

- ExchangeService не создаётся;
- runtime сразу завершается.

---

Использованы синхронные тесты через:

```python
asyncio.run(...)
```

что позволило избежать зависимости проекта от `pytest-asyncio`.

---

# Проверка Market Data Runner

Подтверждены существующие тесты:

```
tests/unit/integrations/exchange/test_market_data_runner.py
```

Проверяется:

- использование validate_symbol();
- использование normalized_symbol;
- отсутствие зависимости от symbol_info;
- fallback при ошибке;
- fallback при invalid symbol.

---

# Проверка компиляции

Выполнено:

```bash
python -m py_compile \
  src/integrations/exchange/market_stream.py \
  src/integrations/exchange/market_data_runner.py \
  tests/unit/integrations/exchange/test_market_stream.py \
  tests/unit/integrations/exchange/test_market_data_runner.py
```

Результат:

```
Ошибок нет.
```

---

# Проверка целевого набора тестов

Выполнено:

```bash
python -m pytest \
  tests/unit/integrations/exchange/test_market_stream.py \
  tests/unit/integrations/exchange/test_market_data_runner.py \
  tests/unit/integrations/exchange/test_service_validate_symbol.py \
  tests/unit/integrations/exchange/test_service_symbol_runtime_status.py \
  -q
```

Результат:

```
61 passed
```

---

# Полный Regression Suite

Выполнено:

```bash
python -m pytest -q
```

Результат:

```
471 passed
```

---

# Финальный аудит зависимостей

Выполнено:

```bash
grep -RIn \
  --exclude-dir="__pycache__" \
  --exclude="*.pyc" \
  -E "validate_symbol|symbol_info|get_instruments|get_exchange_symbols|ExchangeSymbol|Instrument" \
  src/integrations/exchange/market_stream.py \
  src/integrations/exchange/market_data_runner.py \
  tests/unit/integrations/exchange/test_market_stream.py \
  tests/unit/integrations/exchange/test_market_data_runner.py
```

Подтверждено:

Production-код использует только:

```
validate_symbol()
```

через:

```
normalized_symbol
```

Прямых зависимостей от:

- ExchangeSymbol
- get_exchange_symbols()
- symbol_info
- Instrument

не обнаружено.

---

# Архитектурный итог

После Build 023 runtime-компоненты полностью используют канонический путь работы с инструментами:

```text
Instrument Reference
        │
        ▼
Instrument Store
        │
        ▼
get_instruments()
        │
        ▼
validate_symbol()
        │
        ▼
normalized_symbol
        │
        ▼
Market Stream
Market Data Runner
```

Legacy-проекция `ExchangeSymbol` больше не участвует в работе runtime-компонентов.

---

# Итог Build

Build 023 полностью завершён.

Подтверждено:

- runtime-компоненты используют канонический Instrument Reference;
- используется единая точка валидации символов через `validate_symbol()`;
- используется только `normalized_symbol`;
- отсутствуют зависимости от `ExchangeSymbol` и `symbol_info`;
- Production-код соответствует новой архитектуре без дополнительных изменений;
- добавлены Unit-тесты для `market_stream.py`;
- подтверждена корректность `market_data_runner.py`;
- полный Regression Suite успешно пройден (**471 passed**).

**Статус Build:** ✅ Завершён.