feat: add market data architecture and complete migration through build 039
This commit is contained in:
325
docs/migrations/build_001.md
Normal file
325
docs/migrations/build_001.md
Normal file
@@ -0,0 +1,325 @@
|
||||
# Build 001 — Внутренняя модель Instrument Reference Data
|
||||
|
||||
**Проект:** Dzentra
|
||||
**Подсистема:** Market Data Acquisition
|
||||
**Миграция:** Instrument Reference Data
|
||||
**Статус:** ✅ Завершён
|
||||
**Дата:** 2026-07-10
|
||||
|
||||
---
|
||||
|
||||
# Цель Build
|
||||
|
||||
Создать независимую внутреннюю модель Instrument Reference Data.
|
||||
|
||||
На данном этапе запрещается:
|
||||
|
||||
- изменять ExchangeService;
|
||||
- изменять существующий runtime;
|
||||
- менять Telegram UI;
|
||||
- менять Symbol Validation;
|
||||
- подключать новую модель к production-коду.
|
||||
|
||||
Build создаёт исключительно новую внутреннюю модель, которая станет целевой моделью для последующего mapper.
|
||||
|
||||
---
|
||||
|
||||
# Причина выполнения Build
|
||||
|
||||
В утверждённой архитектуре Dzentra модель предметной области должна существовать отдельно от:
|
||||
|
||||
- REST API Dzengi;
|
||||
- parser;
|
||||
- mapper;
|
||||
- ExchangeService;
|
||||
- Telegram UI;
|
||||
- runtime.
|
||||
|
||||
Поэтому сначала создаётся независимая модель Instrument, а только затем будут строиться parser и mapper.
|
||||
|
||||
---
|
||||
|
||||
# Проанализированные файлы
|
||||
|
||||
В ходе Build были полностью проанализированы:
|
||||
|
||||
```text
|
||||
app/src/integrations/exchange/service.py
|
||||
app/src/integrations/exchange/models.py
|
||||
app/src/integrations/exchange/symbol_utils.py
|
||||
app/src/integrations/exchange/rest_client.py
|
||||
app/src/integrations/exchange/status.py
|
||||
|
||||
app/src/telegram/ui/currency_ui.py
|
||||
|
||||
docs/stages/stage-03_3-exchange_info.md
|
||||
docs/decisions/0007-symbol-validation.md
|
||||
```
|
||||
|
||||
Также были проанализированы:
|
||||
|
||||
- сохранённый runtime-ответ `/exchangeInfo`;
|
||||
- OpenAPI Dzengi;
|
||||
- все текущие потребители ExchangeSymbol;
|
||||
- результаты grep по всему проекту.
|
||||
|
||||
---
|
||||
|
||||
# Основные выводы анализа
|
||||
|
||||
Установлено:
|
||||
|
||||
- ExchangeSymbol создаётся только в одном месте;
|
||||
- parser и mapper сейчас объединены внутри ExchangeService;
|
||||
- SymbolValidationResult используется только ExchangeService;
|
||||
- normalize_symbol() и symbol_candidates() централизованы;
|
||||
- отдельного parser ещё не существует;
|
||||
- отдельного mapper ещё не существует;
|
||||
- кэш справочника представляет собой неуправляемый singleton без TTL.
|
||||
|
||||
Также подтверждено:
|
||||
|
||||
- новый Build не должен менять существующий ExchangeService;
|
||||
- новая модель не должна зависеть от Telegram UI;
|
||||
- runtime-статусы не являются частью Instrument Reference Data.
|
||||
|
||||
---
|
||||
|
||||
# Анализ реального ответа exchangeInfo
|
||||
|
||||
Подтверждено наличие следующих полей:
|
||||
|
||||
Обязательные:
|
||||
|
||||
- symbol
|
||||
- name
|
||||
- status
|
||||
- baseAsset
|
||||
- quoteAsset
|
||||
- marketModes
|
||||
- marketType
|
||||
- tickSize
|
||||
|
||||
Через filters:
|
||||
|
||||
- stepSize
|
||||
- minQty
|
||||
- maxQty
|
||||
- minNotional
|
||||
|
||||
Также обнаружены дополнительные справочные поля:
|
||||
|
||||
- assetType
|
||||
- orderTypes
|
||||
- baseAssetPrecision
|
||||
- quotePrecision
|
||||
- tickValue
|
||||
- country
|
||||
- sector
|
||||
- industry
|
||||
- tradingHours
|
||||
|
||||
---
|
||||
|
||||
# Принятые архитектурные решения
|
||||
|
||||
## Новая модель не копирует ExchangeSymbol
|
||||
|
||||
Новая модель является самостоятельной внутренней моделью предметной области.
|
||||
|
||||
---
|
||||
|
||||
## Runtime не входит в Instrument
|
||||
|
||||
Из модели исключены:
|
||||
|
||||
- title
|
||||
- message
|
||||
- ui_line
|
||||
- reason
|
||||
- is_open
|
||||
- is_available
|
||||
- is_auth_ok
|
||||
|
||||
Эти поля относятся к Runtime Status.
|
||||
|
||||
---
|
||||
|
||||
## Использование Decimal
|
||||
|
||||
Для следующих значений принято использовать Decimal:
|
||||
|
||||
- tick_size
|
||||
- tick_value
|
||||
- step_size
|
||||
- min_qty
|
||||
- max_qty
|
||||
- min_notional
|
||||
|
||||
Причина:
|
||||
|
||||
данные используются при нормализации цен и количества и не должны терять точность.
|
||||
|
||||
Поскольку модель пока нигде не используется, изменение не влияет на работающего бота.
|
||||
|
||||
Классификация:
|
||||
|
||||
**Улучшение надёжности.**
|
||||
|
||||
---
|
||||
|
||||
## Не включены в Instrument
|
||||
|
||||
Сознательно исключены:
|
||||
|
||||
- trading_fee
|
||||
- long_rate
|
||||
- short_rate
|
||||
- swap_charge_interval
|
||||
- min_sl_gap
|
||||
- max_sl_gap
|
||||
- min_tp_gap
|
||||
- max_tp_gap
|
||||
|
||||
Причина:
|
||||
|
||||
данные относятся к другим предметным подсистемам.
|
||||
|
||||
---
|
||||
|
||||
# Созданные файлы
|
||||
|
||||
Создан:
|
||||
|
||||
```text
|
||||
app/src/market_data/acquisition/models/instrument.py
|
||||
```
|
||||
|
||||
Создан:
|
||||
|
||||
```text
|
||||
app/tests/unit/market_data/acquisition/models/test_instrument.py
|
||||
```
|
||||
|
||||
Другие production-файлы не изменялись.
|
||||
|
||||
---
|
||||
|
||||
# Проверки
|
||||
|
||||
Выполнены проверки.
|
||||
|
||||
## Unit Test новой модели
|
||||
|
||||
Статус:
|
||||
|
||||
✅ Passed
|
||||
|
||||
```
|
||||
4 passed
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Импорт модели
|
||||
|
||||
Проверено:
|
||||
|
||||
- импорт проходит;
|
||||
- dataclass создаётся;
|
||||
- Decimal работает;
|
||||
- tuple работают.
|
||||
|
||||
Статус:
|
||||
|
||||
✅ Passed
|
||||
|
||||
---
|
||||
|
||||
## Компиляция
|
||||
|
||||
Проверено:
|
||||
|
||||
```
|
||||
python -m py_compile
|
||||
```
|
||||
|
||||
Статус:
|
||||
|
||||
✅ Passed
|
||||
|
||||
---
|
||||
|
||||
## Legacy Compatibility
|
||||
|
||||
Проверено:
|
||||
|
||||
- ExchangeSymbol
|
||||
- SymbolValidationResult
|
||||
- ExchangeService
|
||||
- normalize_symbol()
|
||||
- symbol_candidates()
|
||||
|
||||
Статус:
|
||||
|
||||
✅ Полностью совместимо.
|
||||
|
||||
---
|
||||
|
||||
## Проверка отсутствия подключения новой модели
|
||||
|
||||
Подтверждено:
|
||||
|
||||
новая модель используется исключительно в unit-тестах.
|
||||
|
||||
Production-код её не импортирует.
|
||||
|
||||
Статус:
|
||||
|
||||
✅ Passed
|
||||
|
||||
---
|
||||
|
||||
## Полный набор тестов
|
||||
|
||||
Выполнено:
|
||||
|
||||
```
|
||||
python -m pytest -q
|
||||
```
|
||||
|
||||
Результат:
|
||||
|
||||
```
|
||||
5 passed
|
||||
```
|
||||
|
||||
Статус:
|
||||
|
||||
✅ Passed
|
||||
|
||||
---
|
||||
|
||||
# Итог Build
|
||||
|
||||
Build 001 завершён успешно.
|
||||
|
||||
Подтверждено:
|
||||
|
||||
- создана независимая модель Instrument;
|
||||
- модель не зависит от legacy-кода;
|
||||
- обратная совместимость полностью сохранена;
|
||||
- работающий бот не изменён;
|
||||
- новая архитектура готова к реализации Build 002.
|
||||
|
||||
---
|
||||
|
||||
# Следующий Build
|
||||
|
||||
Build 002
|
||||
|
||||
**Dzengi Raw Models**
|
||||
|
||||
Следующий этап создаст модели сырого ответа REST API Dzengi.
|
||||
|
||||
На этом этапе ExchangeService по-прежнему изменяться не будет.
|
||||
Reference in New Issue
Block a user