Build 060.9: add WebSocket Trade Transport Model
This commit is contained in:
957
docs/migrations/build_060_9.md
Normal file
957
docs/migrations/build_060_9.md
Normal file
@@ -0,0 +1,957 @@
|
||||
# Build 060.9 — WebSocket Trade Transport Model
|
||||
|
||||
**Engineering Migration Report**
|
||||
|
||||
---
|
||||
|
||||
# Контроль документа
|
||||
|
||||
| Свойство | Значение |
|
||||
|----------|----------|
|
||||
| Build | 060.9 |
|
||||
| Название | WebSocket Trade Transport Model |
|
||||
| Статус | Completed |
|
||||
| Проект | Dzentra |
|
||||
| Подсистема | Market Data Acquisition |
|
||||
| Компонент | Trades Feed |
|
||||
| Версия | 1.0 |
|
||||
|
||||
---
|
||||
|
||||
# Цель Build
|
||||
|
||||
После завершения Build 060.8 система получила источник получения сырых REST-документов Trade (`DzengiTradesDocumentSource`).
|
||||
|
||||
Следующим этапом развития является построение полного конвейера обработки сделок, поступающих по WebSocket.
|
||||
|
||||
Build 060.9 открывает вторую ветку реализации Trades Feed и вводит транспортную модель, описывающую одно WebSocket-событие биржи.
|
||||
|
||||
Данный Build ограничивается исключительно транспортным уровнем (Transport Layer) и не затрагивает Parser, Schema Validation, Value Validation, Mapper, Adapter, Routing и Runtime.
|
||||
|
||||
---
|
||||
|
||||
# Предпосылки
|
||||
|
||||
К моменту начала Build архитектура Dzentra уже содержала транспортные модели для остальных типов рыночных данных.
|
||||
|
||||
## REST Trades
|
||||
|
||||
```text
|
||||
REST Document
|
||||
│
|
||||
▼
|
||||
DzengiRestAggTrade
|
||||
│
|
||||
▼
|
||||
Trade
|
||||
```
|
||||
|
||||
## WebSocket Quote
|
||||
|
||||
```text
|
||||
WebSocket Quote Document
|
||||
│
|
||||
▼
|
||||
DzengiWebSocketQuoteResponse
|
||||
│
|
||||
▼
|
||||
Quote
|
||||
```
|
||||
|
||||
## WebSocket OHLC
|
||||
|
||||
```text
|
||||
WebSocket OHLC Document
|
||||
│
|
||||
▼
|
||||
DzengiWebSocketOhlcEvent
|
||||
│
|
||||
▼
|
||||
Candle
|
||||
```
|
||||
|
||||
Для WebSocket Trade аналогичная транспортная модель отсутствовала.
|
||||
|
||||
В результате архитектура обработки сделок оставалась неполной и асимметричной относительно остальных типов рыночных данных.
|
||||
|
||||
---
|
||||
|
||||
# Архитектурное основание
|
||||
|
||||
Build 060.9 не проектирует транспортный контракт самостоятельно.
|
||||
|
||||
В качестве первичного источника использованы результаты инженерного исследования, выполненного в рамках Build 057.
|
||||
|
||||
Во время исследования были изучены:
|
||||
|
||||
- REST `aggTrades`;
|
||||
- WebSocket `trades.subscribe`;
|
||||
- реальные Production-сообщения;
|
||||
- соответствие REST и WebSocket контрактов.
|
||||
|
||||
Исследование подтвердило фактический формат события:
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "OK",
|
||||
"destination": "internal.trade",
|
||||
"payload": {
|
||||
"buyer": false,
|
||||
"id": 2134846831,
|
||||
"orderId": "00a02503-0079-54c4-0000-000081e62b58",
|
||||
"price": 64555.55,
|
||||
"size": 0.002,
|
||||
"symbol": "BTC/USD_LEVERAGE",
|
||||
"ts": 1784218012030
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Именно этот контракт принят за основу реализации Build 060.9.
|
||||
|
||||
---
|
||||
|
||||
# Результаты архитектурного аудита
|
||||
|
||||
Перед началом реализации был выполнен аудит существующего адаптера Dzengi.
|
||||
|
||||
Подтверждено наличие транспортных моделей:
|
||||
|
||||
- `DzengiRestAggTrade`;
|
||||
- `DzengiWebSocketQuoteResponse`;
|
||||
- `DzengiWebSocketOhlcEvent`.
|
||||
|
||||
Также подтверждено существование полной иерархии ошибок обработки Trade:
|
||||
|
||||
- `TradeTransportError`;
|
||||
- `TradeSchemaError`;
|
||||
- `TradeParseError`;
|
||||
- `TradeValueError`;
|
||||
- `TradeMappingError`.
|
||||
|
||||
Одновременно подтверждено отсутствие следующих компонентов WebSocket Trade Pipeline:
|
||||
|
||||
- Transport Model;
|
||||
- Schema Validation;
|
||||
- Parser;
|
||||
- Value Validation;
|
||||
- Mapper;
|
||||
- Adapter.
|
||||
|
||||
Таким образом Build 060.9 полностью соответствует утверждённой дорожной карте серии 060 и закрывает первый этап WebSocket-ветки обработки сделок.
|
||||
|
||||
---
|
||||
|
||||
# Архитектурное решение
|
||||
|
||||
В транспортный слой адаптера введена новая модель
|
||||
|
||||
```text
|
||||
DzengiWebSocketTradeEvent
|
||||
```
|
||||
|
||||
Она представляет собой типизированное описание одного события
|
||||
|
||||
```text
|
||||
destination = internal.trade
|
||||
```
|
||||
|
||||
и относится исключительно к транспортному уровню адаптера.
|
||||
|
||||
Модель не является:
|
||||
|
||||
- внутренней моделью Dzentra;
|
||||
- бизнес-сущностью;
|
||||
- канонической моделью `Trade`.
|
||||
|
||||
Её единственная ответственность — хранение уже разобранных транспортных данных WebSocket-сообщения.
|
||||
|
||||
---
|
||||
|
||||
# Реализованная транспортная модель
|
||||
|
||||
В файл
|
||||
|
||||
```text
|
||||
src/market_data/acquisition/adapters/dzengi/models.py
|
||||
```
|
||||
|
||||
добавлена новая транспортная модель:
|
||||
|
||||
```python
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class DzengiWebSocketTradeEvent:
|
||||
trade_id: int
|
||||
price: DzengiRawNumeric
|
||||
size: DzengiRawNumeric
|
||||
timestamp: int
|
||||
symbol: str
|
||||
buyer: bool
|
||||
order_id: str
|
||||
```
|
||||
|
||||
Модель размещена рядом с существующими транспортными моделями адаптера.
|
||||
|
||||
Итоговая последовательность моделей выглядит следующим образом:
|
||||
|
||||
```text
|
||||
DzengiRestAggTrade
|
||||
DzengiWebSocketTradeEvent
|
||||
DzengiWebSocketOhlcEvent
|
||||
```
|
||||
|
||||
Такое расположение сохраняет логическую группировку транспортных сущностей по типам рыночных данных.
|
||||
|
||||
---
|
||||
|
||||
# Почему используется dataclass
|
||||
|
||||
`DzengiWebSocketTradeEvent` представляет собой неизменяемый контейнер транспортных данных.
|
||||
|
||||
Модель:
|
||||
|
||||
- не содержит бизнес-логики;
|
||||
- не выполняет преобразование типов;
|
||||
- не выполняет структурную проверку;
|
||||
- не выполняет Value Validation;
|
||||
- не выполняет Mapping;
|
||||
- не взаимодействует с сетью;
|
||||
- не содержит изменяемого состояния.
|
||||
|
||||
Поэтому используется конструкция
|
||||
|
||||
```python
|
||||
@dataclass(frozen=True, slots=True)
|
||||
```
|
||||
|
||||
что полностью соответствует архитектурному стилю остальных транспортных моделей проекта.
|
||||
|
||||
---
|
||||
|
||||
# Назначение полей
|
||||
|
||||
В модель включены только поля, подтверждённые реальными Production-сообщениями.
|
||||
|
||||
| Поле | Назначение |
|
||||
|------|------------|
|
||||
| `trade_id` | идентификатор сделки |
|
||||
| `price` | цена сделки |
|
||||
| `size` | объём сделки |
|
||||
| `timestamp` | время исполнения |
|
||||
| `symbol` | торговый инструмент |
|
||||
| `buyer` | сторона инициатора |
|
||||
| `order_id` | идентификатор ордера |
|
||||
|
||||
Каждое поле соответствует данным, полученным в ходе исследования Build 057.
|
||||
|
||||
---
|
||||
|
||||
# Нормализация имён полей
|
||||
|
||||
Во входящем WebSocket JSON используются ключи
|
||||
|
||||
```text
|
||||
id
|
||||
ts
|
||||
orderId
|
||||
```
|
||||
|
||||
Во внутренней транспортной модели используются нормализованные имена
|
||||
|
||||
```text
|
||||
trade_id
|
||||
timestamp
|
||||
order_id
|
||||
```
|
||||
|
||||
Подобная нормализация уже используется в остальных транспортных моделях Dzentra и обеспечивает единый стиль внутренних контрактов.
|
||||
|
||||
Преобразование JSON-ключей выполняется Parser.
|
||||
|
||||
Транспортная модель не зависит от формата сериализации входящего сообщения.
|
||||
|
||||
---
|
||||
|
||||
# Использование DzengiRawNumeric
|
||||
|
||||
Поля
|
||||
|
||||
```python
|
||||
price
|
||||
size
|
||||
```
|
||||
|
||||
имеют тип
|
||||
|
||||
```python
|
||||
DzengiRawNumeric
|
||||
```
|
||||
|
||||
Такое решение уже применяется в REST Trade и других транспортных моделях адаптера.
|
||||
|
||||
Использование `DzengiRawNumeric` означает, что транспортная модель сохраняет числовые значения в исходном виде без выполнения каких-либо преобразований.
|
||||
|
||||
Ответственность за интерпретацию числовых значений относится к последующим этапам конвейера.
|
||||
|
||||
Это позволяет полностью разделить:
|
||||
|
||||
- транспортное представление данных;
|
||||
- их синтаксическую корректность;
|
||||
- семантическую валидацию;
|
||||
- преобразование в каноническую модель.
|
||||
|
||||
# Неизменяемость модели
|
||||
|
||||
Параметр
|
||||
|
||||
```python
|
||||
frozen=True
|
||||
```
|
||||
|
||||
гарантирует, что после создания экземпляра его поля не могут быть изменены.
|
||||
|
||||
Это важно для транспортного слоя, поскольку модель представляет собой результат разбора одного входящего сообщения и после создания должна оставаться неизменной.
|
||||
|
||||
После формирования экземпляр проходит через последующие этапы конвейера:
|
||||
|
||||
```text
|
||||
Validated WebSocket Document
|
||||
│
|
||||
▼
|
||||
DzengiWebSocketTradeEvent
|
||||
│
|
||||
▼
|
||||
Value Validation
|
||||
│
|
||||
▼
|
||||
Mapper
|
||||
│
|
||||
▼
|
||||
Trade
|
||||
```
|
||||
|
||||
Неизменяемость транспортной модели обеспечивает воспроизводимость обработки сообщения и исключает случайную модификацию данных на последующих этапах.
|
||||
|
||||
---
|
||||
|
||||
# Использование slots
|
||||
|
||||
Параметр
|
||||
|
||||
```python
|
||||
slots=True
|
||||
```
|
||||
|
||||
используется для:
|
||||
|
||||
- фиксации структуры модели;
|
||||
- предотвращения динамического добавления атрибутов;
|
||||
- уменьшения накладных расходов на экземпляр;
|
||||
- сохранения единого архитектурного стиля транспортных моделей Dzentra.
|
||||
|
||||
Экземпляр `DzengiWebSocketTradeEvent` не содержит `__dict__`, что дополнительно подтверждает его роль как лёгкого транспортного контейнера.
|
||||
|
||||
---
|
||||
|
||||
# Граница ответственности модели
|
||||
|
||||
`DzengiWebSocketTradeEvent` отвечает исключительно за хранение уже разобранных транспортных данных.
|
||||
|
||||
В обязанности модели **не входит**:
|
||||
|
||||
- проверка структуры исходного JSON;
|
||||
- проверка значения `status`;
|
||||
- проверка `destination`;
|
||||
- проверка наличия обязательных полей;
|
||||
- проверка корректности цены;
|
||||
- проверка корректности объёма;
|
||||
- проверка корректности timestamp;
|
||||
- определение бизнес-семантики сделки;
|
||||
- преобразование в каноническую модель `Trade`.
|
||||
|
||||
Каждая из перечисленных задач относится к отдельному уровню архитектуры и будет реализована в соответствующих Build.
|
||||
|
||||
---
|
||||
|
||||
# Целевой конвейер обработки WebSocket Trade
|
||||
|
||||
После завершения Builds 060.9–060.14 полный конвейер обработки будет иметь следующий вид:
|
||||
|
||||
```text
|
||||
Raw WebSocket Object
|
||||
│
|
||||
▼
|
||||
WebSocket Trade Schema Validation
|
||||
│
|
||||
▼
|
||||
ValidatedWebSocketTradeDocument
|
||||
│
|
||||
▼
|
||||
WebSocket Trade Parser
|
||||
│
|
||||
▼
|
||||
DzengiWebSocketTradeEvent
|
||||
│
|
||||
▼
|
||||
WebSocket Trade Value Validation
|
||||
│
|
||||
▼
|
||||
WebSocket Trade Mapper
|
||||
│
|
||||
▼
|
||||
Trade
|
||||
```
|
||||
|
||||
Build 060.9 реализует только один компонент этого конвейера:
|
||||
|
||||
```text
|
||||
DzengiWebSocketTradeEvent
|
||||
```
|
||||
|
||||
Все остальные этапы будут реализованы последовательно в следующих Build.
|
||||
|
||||
---
|
||||
|
||||
# Соотношение с канонической моделью Trade
|
||||
|
||||
В Build 060.1 была реализована каноническая модель
|
||||
|
||||
```text
|
||||
Trade
|
||||
```
|
||||
|
||||
Она используется внутренними компонентами Dzentra и полностью независима от способа получения рыночных данных.
|
||||
|
||||
`DzengiWebSocketTradeEvent` не заменяет `Trade`.
|
||||
|
||||
Эти модели относятся к различным архитектурным уровням.
|
||||
|
||||
```text
|
||||
DzengiWebSocketTradeEvent
|
||||
```
|
||||
|
||||
— транспортное представление WebSocket-события конкретной биржи.
|
||||
|
||||
```text
|
||||
Trade
|
||||
```
|
||||
|
||||
— единая внутренняя модель сделки, используемая всеми компонентами Dzentra.
|
||||
|
||||
После реализации Mapper транспортная модель будет преобразовываться в каноническую.
|
||||
|
||||
---
|
||||
|
||||
# Соотношение REST и WebSocket транспортных моделей
|
||||
|
||||
REST и WebSocket описывают одну и ту же биржевую сделку, но используют различные транспортные контракты.
|
||||
|
||||
REST:
|
||||
|
||||
```json
|
||||
{
|
||||
"a": 2134846831,
|
||||
"p": "64555.55",
|
||||
"q": "0.002",
|
||||
"T": 1784218012030,
|
||||
"m": true
|
||||
}
|
||||
```
|
||||
|
||||
WebSocket:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 2134846831,
|
||||
"price": 64555.55,
|
||||
"size": 0.002,
|
||||
"symbol": "BTC/USD_LEVERAGE",
|
||||
"ts": 1784218012030,
|
||||
"buyer": false,
|
||||
"orderId": "00a02503-0079-54c4-0000-000081e62b58"
|
||||
}
|
||||
```
|
||||
|
||||
Несмотря на различие транспортных контрактов, обе модели описывают одну и ту же биржевую сущность и далее преобразуются в единую каноническую модель `Trade`.
|
||||
|
||||
---
|
||||
|
||||
# Сопоставление полей REST и WebSocket
|
||||
|
||||
| Каноническая семантика | REST | WebSocket |
|
||||
|------------------------|------|-----------|
|
||||
| идентификатор сделки | `a` | `id` |
|
||||
| цена | `p` | `price` |
|
||||
| объём | `q` | `size` |
|
||||
| timestamp | `T` | `ts` |
|
||||
| сторона инициатора | `m` | `buyer` |
|
||||
| торговый инструмент | отсутствует | `symbol` |
|
||||
| идентификатор ордера | отсутствует | `orderId` |
|
||||
|
||||
Согласно результатам исследования Build 057 выполняется соответствие:
|
||||
|
||||
```text
|
||||
buyer == !m
|
||||
```
|
||||
|
||||
Данная нормализация будет реализована WebSocket Trade Mapper в Build 060.13.
|
||||
|
||||
---
|
||||
|
||||
# Обработка транспортной оболочки сообщения
|
||||
|
||||
Фактическое WebSocket-сообщение имеет следующую структуру:
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "OK",
|
||||
"destination": "internal.trade",
|
||||
"payload": {
|
||||
"...": "..."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`DzengiWebSocketTradeEvent` представляет исключительно содержимое объекта `payload`.
|
||||
|
||||
Поля
|
||||
|
||||
```text
|
||||
status
|
||||
destination
|
||||
```
|
||||
|
||||
не входят в транспортную модель, поскольку относятся к внешней оболочке WebSocket-документа.
|
||||
|
||||
Их обработка будет реализована в Build 060.10 — WebSocket Trade Schema Validation.
|
||||
|
||||
---
|
||||
|
||||
# Решение по полю clientOrderId
|
||||
|
||||
Во время исследования было обнаружено, что Swagger содержит дополнительное поле
|
||||
|
||||
```text
|
||||
clientOrderId
|
||||
```
|
||||
|
||||
Однако анализ реальных Production-сообщений подтвердил обязательное наличие только поля
|
||||
|
||||
```text
|
||||
orderId
|
||||
```
|
||||
|
||||
Поэтому `clientOrderId` не включён в обязательный транспортный контракт Build 060.9.
|
||||
|
||||
Это исключает зависимость Parser от поля, которое отсутствует в фактических сообщениях биржи.
|
||||
|
||||
При реализации Schema Validation будут использоваться следующие принципы:
|
||||
|
||||
- обязательными считаются только поля, подтверждённые Production;
|
||||
- наличие дополнительных полей не должно приводить к ошибке;
|
||||
- неподтверждённые поля не становятся обязательными автоматически.
|
||||
|
||||
---
|
||||
|
||||
# Изменённые файлы
|
||||
|
||||
В рамках Build были изменены только два файла.
|
||||
|
||||
## Транспортная модель
|
||||
|
||||
```text
|
||||
src/market_data/acquisition/adapters/dzengi/models.py
|
||||
```
|
||||
|
||||
Добавлена новая модель
|
||||
|
||||
```text
|
||||
DzengiWebSocketTradeEvent
|
||||
```
|
||||
|
||||
При этом существующие модели, импорты и поведение файла не изменялись.
|
||||
|
||||
---
|
||||
|
||||
## Unit-тесты
|
||||
|
||||
```text
|
||||
tests/unit/market_data/acquisition/adapters/dzengi/test_models.py
|
||||
```
|
||||
|
||||
Добавлены три новых unit-теста транспортной модели.
|
||||
|
||||
---
|
||||
|
||||
# Добавленные тесты
|
||||
|
||||
## Проверка полного транспортного контракта
|
||||
|
||||
Тест
|
||||
|
||||
```text
|
||||
test_websocket_trade_event_stores_complete_transport_contract
|
||||
```
|
||||
|
||||
проверяет сохранение всех подтверждённых полей транспортной модели.
|
||||
|
||||
---
|
||||
|
||||
## Проверка сохранения исходных числовых значений
|
||||
|
||||
Тест
|
||||
|
||||
```text
|
||||
test_websocket_trade_event_preserves_raw_numeric_values
|
||||
```
|
||||
|
||||
подтверждает, что модель сохраняет цену и объём без преобразования типов.
|
||||
|
||||
---
|
||||
|
||||
## Проверка неизменяемости и slots
|
||||
|
||||
Тест
|
||||
|
||||
```text
|
||||
test_websocket_trade_event_is_immutable_and_uses_slots
|
||||
```
|
||||
|
||||
подтверждает:
|
||||
|
||||
- отсутствие `__dict__`;
|
||||
- невозможность изменения экземпляра после создания.
|
||||
|
||||
# Результаты тестирования
|
||||
|
||||
Выполнен целевой запуск unit-тестов транспортных моделей:
|
||||
|
||||
```bash
|
||||
python -m pytest \
|
||||
tests/unit/market_data/acquisition/adapters/dzengi/test_models.py \
|
||||
-q
|
||||
```
|
||||
|
||||
Результат выполнения:
|
||||
|
||||
```text
|
||||
12 passed in 0.03s
|
||||
```
|
||||
|
||||
До реализации Build 060.9 файл содержал девять тестов.
|
||||
|
||||
После добавления транспортной модели количество тестов увеличилось:
|
||||
|
||||
```text
|
||||
9 → 12
|
||||
```
|
||||
|
||||
что соответствует трём новым проверкам.
|
||||
|
||||
---
|
||||
|
||||
# Регрессионное тестирование
|
||||
|
||||
После завершения реализации был выполнен полный запуск тестов адаптера Dzengi.
|
||||
|
||||
```bash
|
||||
python -m pytest \
|
||||
tests/unit/market_data/acquisition/adapters/dzengi \
|
||||
-q
|
||||
```
|
||||
|
||||
Результат:
|
||||
|
||||
```text
|
||||
246 passed in 0.11s
|
||||
```
|
||||
|
||||
До реализации Build 060.9 набор содержал:
|
||||
|
||||
```text
|
||||
243 passed
|
||||
```
|
||||
|
||||
После добавления новой транспортной модели:
|
||||
|
||||
```text
|
||||
246 passed
|
||||
```
|
||||
|
||||
Регрессий не обнаружено.
|
||||
|
||||
---
|
||||
|
||||
# Проверка компиляции
|
||||
|
||||
Выполнена проверка компиляции изменённых файлов:
|
||||
|
||||
```bash
|
||||
python -m compileall \
|
||||
src/market_data/acquisition/adapters/dzengi/models.py \
|
||||
tests/unit/market_data/acquisition/adapters/dzengi/test_models.py
|
||||
```
|
||||
|
||||
Компиляция завершилась успешно.
|
||||
|
||||
Синтаксические ошибки отсутствуют.
|
||||
|
||||
---
|
||||
|
||||
# Проверка Git diff
|
||||
|
||||
Финальный анализ изменений подтвердил, что Build затронул только согласованный scope.
|
||||
|
||||
Добавлены:
|
||||
|
||||
- одна транспортная модель;
|
||||
- три unit-теста.
|
||||
|
||||
Не изменялись:
|
||||
|
||||
```text
|
||||
src/market_data/acquisition/adapters/dzengi/parser.py
|
||||
src/market_data/acquisition/adapters/dzengi/mapper.py
|
||||
src/market_data/acquisition/adapters/dzengi/websocket.py
|
||||
src/market_data/acquisition/validation/schema.py
|
||||
src/market_data/acquisition/validation/values.py
|
||||
src/market_data/acquisition/exceptions.py
|
||||
src/market_data/acquisition/runtime/
|
||||
src/market_data/acquisition/feeds/
|
||||
src/market_data/acquisition/handlers/
|
||||
```
|
||||
|
||||
Таким образом Build полностью соответствует принципу локальности изменений.
|
||||
|
||||
---
|
||||
|
||||
# Scope Build 060.9
|
||||
|
||||
В рамках данного Build реализовано только:
|
||||
|
||||
```text
|
||||
WebSocket Trade Transport Model
|
||||
```
|
||||
|
||||
В Build **не входят**:
|
||||
|
||||
- WebSocket Trade Schema Validation;
|
||||
- WebSocket Trade Parser;
|
||||
- WebSocket Trade Value Validation;
|
||||
- WebSocket Trade Mapper;
|
||||
- WebSocket Trade Adapter;
|
||||
- Unified WebSocket Routing;
|
||||
- Trade Subscription Layer;
|
||||
- Trades Feed Core;
|
||||
- Runtime Integration.
|
||||
|
||||
Такое разделение обеспечивает атомарность миграции и позволяет независимо проверять каждый архитектурный уровень.
|
||||
|
||||
---
|
||||
|
||||
# Архитектурный результат
|
||||
|
||||
После завершения Build система содержит транспортные представления обеих форм получения сделок.
|
||||
|
||||
REST:
|
||||
|
||||
```text
|
||||
REST Trade Document
|
||||
│
|
||||
▼
|
||||
DzengiRestAggTrade
|
||||
│
|
||||
▼
|
||||
Trade
|
||||
```
|
||||
|
||||
WebSocket:
|
||||
|
||||
```text
|
||||
WebSocket Trade Document
|
||||
│
|
||||
▼
|
||||
DzengiWebSocketTradeEvent
|
||||
│
|
||||
▼
|
||||
Trade
|
||||
```
|
||||
|
||||
На текущем этапе WebSocket-ветка содержит только транспортную модель.
|
||||
|
||||
Остальные уровни конвейера будут добавлены последовательно в следующих Build.
|
||||
|
||||
---
|
||||
|
||||
# Состояние WebSocket Trade Pipeline
|
||||
|
||||
После завершения Build 060.9 архитектура конвейера выглядит следующим образом:
|
||||
|
||||
```text
|
||||
Raw WebSocket Trade Document
|
||||
│
|
||||
▼
|
||||
Schema Validation
|
||||
│
|
||||
▼
|
||||
Parser
|
||||
│
|
||||
▼
|
||||
DzengiWebSocketTradeEvent
|
||||
│
|
||||
▼
|
||||
Value Validation
|
||||
│
|
||||
▼
|
||||
Mapper
|
||||
│
|
||||
▼
|
||||
Trade
|
||||
```
|
||||
|
||||
Статус реализации компонентов:
|
||||
|
||||
| Компонент | Build | Статус |
|
||||
|-----------|-------|--------|
|
||||
| Canonical Trade Model | 060.1 | ✔ Completed |
|
||||
| WebSocket Trade Transport Model | 060.9 | ✔ Completed |
|
||||
| WebSocket Trade Schema Validation | 060.10 | Pending |
|
||||
| WebSocket Trade Parser | 060.11 | Pending |
|
||||
| WebSocket Trade Value Validation | 060.12 | Pending |
|
||||
| WebSocket Trade Mapper | 060.13 | Pending |
|
||||
| WebSocket Trade Adapter | 060.14 | Pending |
|
||||
| Unified WebSocket Routing | 060.15 | Pending |
|
||||
|
||||
---
|
||||
|
||||
# Соблюдение архитектурных принципов
|
||||
|
||||
В рамках реализации Build сохранены все архитектурные инварианты проекта Dzentra.
|
||||
|
||||
## Локальность изменений
|
||||
|
||||
Изменены только транспортная модель и её unit-тесты.
|
||||
|
||||
---
|
||||
|
||||
## Отсутствие преждевременной интеграции
|
||||
|
||||
Новая модель не подключена к Adapter, Runtime и Trades Feed до появления всех промежуточных этапов обработки.
|
||||
|
||||
---
|
||||
|
||||
## Разделение транспортной и канонической моделей
|
||||
|
||||
`DzengiWebSocketTradeEvent` используется только внутри транспортного слоя адаптера.
|
||||
|
||||
Внутренние компоненты системы продолжают работать исключительно с канонической моделью `Trade`.
|
||||
|
||||
---
|
||||
|
||||
## Отсутствие бизнес-логики
|
||||
|
||||
Транспортная модель не выполняет:
|
||||
|
||||
- Parsing;
|
||||
- Schema Validation;
|
||||
- Value Validation;
|
||||
- Mapping;
|
||||
- Routing;
|
||||
- Subscription;
|
||||
- Network I/O.
|
||||
|
||||
Она представляет собой исключительно неизменяемый контейнер транспортных данных.
|
||||
|
||||
---
|
||||
|
||||
## Неизменность существующего поведения
|
||||
|
||||
Рабочая логика обработки Quote, OHLC и REST Trade не изменялась.
|
||||
|
||||
Build является полностью обратимо-совместимым с существующей архитектурой.
|
||||
|
||||
---
|
||||
|
||||
# Критерии завершения Build
|
||||
|
||||
Build 060.9 считается завершённым, поскольку выполнены все поставленные задачи.
|
||||
|
||||
- ✔ исследован Production-контракт WebSocket Trade;
|
||||
- ✔ использованы результаты Build 057;
|
||||
- ✔ реализована транспортная модель `DzengiWebSocketTradeEvent`;
|
||||
- ✔ модель содержит все подтверждённые поля события;
|
||||
- ✔ цена и объём сохраняются как `DzengiRawNumeric`;
|
||||
- ✔ модель является неизменяемой;
|
||||
- ✔ используется `slots`;
|
||||
- ✔ добавлены три unit-теста;
|
||||
- ✔ все целевые тесты успешно проходят;
|
||||
- ✔ регрессионное тестирование успешно завершено;
|
||||
- ✔ компиляция выполнена без ошибок;
|
||||
- ✔ изменения не выходят за пределы согласованного scope.
|
||||
|
||||
---
|
||||
|
||||
# Следующий этап
|
||||
|
||||
Следующим этапом дорожной карты является
|
||||
|
||||
```text
|
||||
Build 060.10 — WebSocket Trade Schema Validation
|
||||
```
|
||||
|
||||
Цель Build:
|
||||
|
||||
- реализовать структурную проверку WebSocket Trade-документа;
|
||||
- проверить транспортную оболочку сообщения;
|
||||
- проверить `status`;
|
||||
- проверить `destination = internal.trade`;
|
||||
- проверить наличие объекта `payload`;
|
||||
- проверить наличие обязательных ключей транспортного события;
|
||||
- сформировать `ValidatedWebSocketTradeDocument`;
|
||||
- использовать `TradeSchemaError` для ошибок структуры.
|
||||
|
||||
После завершения Build 060.10 конвейер примет следующий вид:
|
||||
|
||||
```text
|
||||
Raw WebSocket Object
|
||||
│
|
||||
▼
|
||||
validate_dzengi_websocket_trade_schema(...)
|
||||
│
|
||||
▼
|
||||
ValidatedWebSocketTradeDocument
|
||||
│
|
||||
▼
|
||||
Build 060.11 — WebSocket Trade Parser
|
||||
```
|
||||
|
||||
Build 060.10 по-прежнему не будет выполнять:
|
||||
|
||||
- преобразование значений;
|
||||
- семантическую валидацию;
|
||||
- Mapping в `Trade`;
|
||||
- WebSocket Routing;
|
||||
- Runtime Integration.
|
||||
|
||||
---
|
||||
|
||||
# Итог
|
||||
|
||||
Build 060.9 завершил формирование транспортного уровня обработки WebSocket Trade, добавив отсутствующую транспортную модель `DzengiWebSocketTradeEvent`.
|
||||
|
||||
Новая модель представляет собой типизированное описание события
|
||||
|
||||
```text
|
||||
destination = internal.trade
|
||||
```
|
||||
|
||||
и основана на фактическом Production-контракте, подтверждённом в ходе исследования Build 057.
|
||||
|
||||
Реализация полностью соответствует архитектурным принципам Dzentra:
|
||||
|
||||
- транспортный слой отделён от канонической модели;
|
||||
- Build ограничен согласованным scope;
|
||||
- существующее поведение системы не изменено;
|
||||
- создан фундамент для последующей реализации WebSocket Trade Schema Validation, Parser, Mapper и полного конвейера Trades Feed.
|
||||
|
||||
На этом Build 060.9 считается полностью завершённым.
|
||||
Reference in New Issue
Block a user