6.9 KiB
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 были полностью проанализированы:
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
Причина:
данные относятся к другим предметным подсистемам.
Созданные файлы
Создан:
app/src/market_data/acquisition/models/instrument.py
Создан:
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 по-прежнему изменяться не будет.