Files
dzentra_bot/docs/migrations/build_059_5.md

11 KiB
Raw Blame History

Build 059.5 — Internal Candle Close Event Model

Проект: Dzentra
Подсистема: Market Data Acquisition
Этап: 059.5
Статус: Completed


Цель

Добавить внутреннюю immutable-модель уведомления о закрытии OHLC-свечи.

Модель должна представлять уже проверенное WebSocket-событие внутри Dzentra, но не должна заменять каноническую модель:

Candle

Причина разделения заключается в том, что фактическое событие Dzengi WebSocket:

ohlc.event

содержит:

symbol
interval
type
t
o
h
l
c

но не содержит:

volume

Поэтому WebSocket OHLC-событие не является полноценной OHLCV-свечой.


Причина изменения

После Build 059.4 проект умеет:

  1. структурно проверять входящее WebSocket-сообщение;
  2. преобразовывать его в transport-модель;
  3. проверять предметную допустимость значений.

Подготовленная цепочка выглядит так:

Raw WebSocket message
        ↓
ValidatedWebSocketOhlcDocument
        ↓
DzengiWebSocketOhlcEvent
        ↓
Value Validation

Однако transport-модель:

DzengiWebSocketOhlcEvent

принадлежит адаптеру конкретного внешнего источника Dzengi.

Перед дальнейшим использованием в runtime требуется источник-независимая внутренняя модель Dzentra.


Реализовано

Создан файл:

src/market_data/acquisition/models/candle_close.py

Добавлена модель:

CandleCloseEvent

Структура модели

Модель содержит следующие поля:

symbol
interval
candle_type

open_time
received_at

open_price
high_price
low_price
close_price

source

Полное назначение модели:

внутреннее уведомление Dzentra
о завершении OHLC-свечи,
требующее последующего REST reconciliation
для получения полной OHLCV-свечи

Контракт модели

Модель объявлена как:

frozen=True
slots=True

Это обеспечивает:

  • неизменяемость;
  • отсутствие динамического __dict__;
  • уменьшение вероятности случайного изменения события;
  • компактное представление в памяти;
  • предсказуемый runtime-контракт.

Отличие от transport-модели

Transport-модель:

DzengiWebSocketOhlcEvent

отражает внешний контракт Dzengi.

Она содержит:

open_time: int
OHLC: str | int | float

Внутренняя модель:

CandleCloseEvent

содержит:

open_time: datetime
received_at: datetime
OHLC: Decimal
source: str

Таким образом transport-особенности внешнего API не распространяются на внутренние слои Dzentra.


Отличие от канонической Candle

Каноническая модель:

Candle

представляет полноценную OHLCV-свечу.

Она содержит:

volume: Decimal

Модель:

CandleCloseEvent

не содержит volume.

Это преднамеренное архитектурное решение.

WebSocket-событие не должно:

  • подставлять фиктивный нулевой объём;
  • использовать nullable volume;
  • притворяться полной OHLCV-свечой;
  • наследоваться от Candle;
  • передаваться потребителям, ожидающим каноническую свечу.

Полная Candle будет получена только после REST reconciliation.


Поля времени

open_time

Поле:

open_time

представляет время открытия завершённой свечи.

Для минутной свечи это начало минутного интервала, к которому относится событие.

Тип:

datetime

Ожидаемая timezone:

UTC

received_at

Поле:

received_at

представляет момент получения события системой Dzentra.

Оно не равно open_time.

Разделение двух времён необходимо для:

  • измерения задержки WebSocket;
  • диагностики запоздавших сообщений;
  • определения порядка фактической обработки;
  • runtime-метрик;
  • журналирования;
  • анализа качества источника данных.

Поля OHLC

Внутренняя модель использует:

Decimal

для:

open_price
high_price
low_price
close_price

Это исключает дальнейшее распространение внешних типов:

str
int
float

Преобразование transport-значений в Decimal будет реализовано в следующем этапе:

Build 059.6 — Mapper

Поле candle_type

Поле:

candle_type

сохраняет тип серии свечей.

Подтверждённые runtime-значения:

classic
heikin-ashi

Для production-интеграции Candles Feed основной интерес представляет:

classic

Поскольку именно классические свечи будут использоваться для REST reconciliation с каноническими OHLCV-свечами.

heikin-ashi остаётся поддерживаемым внутренним типом события, но не должен автоматически преобразовываться в обычную каноническую Candle.


Поле source

Поле:

source

фиксирует происхождение внутреннего события.

Пример:

dzengi_websocket_ohlc

Это позволит в дальнейшем:

  • различать источники;
  • поддерживать несколько адаптеров;
  • вести диагностику;
  • применять источник-зависимую политику reconciliation;
  • не встраивать имя Dzengi в общую доменную модель.

Новый внутренний конвейер

После Build 059.5 архитектура выглядит так:

Raw WebSocket message
        ↓
Schema Validation
        ↓
ValidatedWebSocketOhlcDocument
        ↓
Parser
        ↓
DzengiWebSocketOhlcEvent
        ↓
Value Validation
        ↓
Mapper
        ↓
CandleCloseEvent
        ↓
REST reconciliation
        ↓
Canonical Candle

На текущем этапе модель CandleCloseEvent уже существует, но mapper ещё не реализован.


Unit Tests

Создан файл:

tests/unit/market_data/acquisition/models/test_candle_close.py

Проверяются:

  • сохранение всех полей;
  • неизменяемость модели;
  • использование slots;
  • отсутствие __dict__;
  • отсутствие наследования от Candle;
  • отсутствие поля volume;
  • поддержка типа heikin-ashi;
  • раздельное хранение open_time и received_at.

Всего выполнено:

7 tests

Проверка синтаксиса

Выполнена команда:

python -m compileall \
  src/market_data/acquisition/models/candle_close.py \
  tests/unit/market_data/acquisition/models/test_candle_close.py

Результат:

успешно

Целевые тесты

Выполнена команда:

python -m pytest -q \
  tests/unit/market_data/acquisition/models/test_candle_close.py

Результат:

7 passed in 0.01s

Регрессия слоя моделей

Выполнена команда:

python -m pytest -q \
  tests/unit/market_data/acquisition/models

Результат:

42 passed in 0.02s

Проверка форматирования

Выполнена команда:

git diff --check

Ошибок форматирования не обнаружено.


Созданные файлы

src/market_data/acquisition/models/candle_close.py
tests/unit/market_data/acquisition/models/test_candle_close.py
docs/migrations/build_059_5.md

Совместимость

Изменение полностью обратно совместимо.

Не изменены:

  • каноническая модель Candle;
  • transport-модель Dzengi;
  • REST Candles Feed;
  • parser;
  • value validation;
  • WebSocket Adapter;
  • ExchangeService;
  • runtime;
  • Market Analysis;
  • Trading.

Новая модель пока не подключена к runtime и не влияет на работающий бот.


Ограничения этапа

Build 059.5 не выполняет:

  • преобразование transport-модели;
  • преобразование timestamp;
  • преобразование OHLC в Decimal;
  • установку реального received_at;
  • mapping;
  • WebSocket Adapter;
  • REST reconciliation;
  • проверку соответствия REST и WebSocket OHLC;
  • создание канонической Candle;
  • публикацию события в runtime.

Итог

Build 059.5 добавляет источник-независимую внутреннюю модель:

CandleCloseEvent

Она представляет подтверждённое уведомление о завершении OHLC-свечи без фиктивного объёма.

Модель создаёт архитектурную границу между:

внешним Dzengi WebSocket контрактом

и:

внутренним runtime Dzentra

Следующий этап:

Build 059.6 — Mapper