325 lines
6.9 KiB
Markdown
325 lines
6.9 KiB
Markdown
# 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 по-прежнему изменяться не будет. |