feat: add market data architecture and complete migration through build 039
This commit is contained in:
335
docs/migrations/build_023.md
Normal file
335
docs/migrations/build_023.md
Normal file
@@ -0,0 +1,335 @@
|
||||
# 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:** ✅ Завершён.
|
||||
Reference in New Issue
Block a user