335 lines
7.7 KiB
Markdown
335 lines
7.7 KiB
Markdown
# 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:** ✅ Завершён. |