1102 lines
36 KiB
Markdown
1102 lines
36 KiB
Markdown
# Build 060.12 — WebSocket Trade Value Validation
|
||
|
||
**Engineering Migration Report**
|
||
|
||
---
|
||
|
||
# Контроль документа
|
||
|
||
| Свойство | Значение |
|
||
|----------|----------|
|
||
| Build | 060.12 |
|
||
| Название | WebSocket Trade Value Validation |
|
||
| Статус | Completed |
|
||
| Проект | Dzentra |
|
||
| Подсистема | Market Data Acquisition |
|
||
| Компонент | Trades Feed |
|
||
| Версия | 1.0 |
|
||
|
||
---
|
||
|
||
# Цель Build
|
||
|
||
После завершения Build 060.11 система получила полностью реализованный уровень **WebSocket Trade Parser**, преобразующий структурно корректный документ
|
||
|
||
```text
|
||
ValidatedWebSocketTradeDocument
|
||
```
|
||
|
||
в транспортную модель
|
||
|
||
```text
|
||
DzengiWebSocketTradeEvent
|
||
```
|
||
|
||
Parser гарантирует корректное построение транспортного объекта и минимальную проверку типов, необходимую для создания модели.
|
||
|
||
Однако после завершения Parsing транспортная модель ещё не может считаться пригодной для дальнейшего использования в системе.
|
||
|
||
Несмотря на корректность структуры и типов, отдельные значения транспортной модели могут оставаться недопустимыми с точки зрения предметной области.
|
||
|
||
Например:
|
||
|
||
- цена сделки может быть равна нулю;
|
||
- объём сделки может быть отрицательным;
|
||
- timestamp может иметь недопустимое значение;
|
||
- идентификатор сделки может отсутствовать либо быть неположительным;
|
||
- строковые поля могут содержать только пробельные символы;
|
||
- числовые значения могут содержать `NaN` или бесконечность.
|
||
|
||
Подобные ошибки уже не относятся к структуре документа и не должны обрабатываться Parser.
|
||
|
||
Для их обработки в архитектуре Dzentra предусмотрен отдельный уровень Pipeline — **Value Validation**.
|
||
|
||
Build 060.12 реализует данный уровень для WebSocket Trade.
|
||
|
||
Основная задача Build — проверить корректность содержимого транспортной модели без выполнения каких-либо преобразований данных и без создания новых объектов.
|
||
|
||
Данный Build ограничивается исключительно проверкой значений транспортной модели и не затрагивает:
|
||
|
||
- Schema Validation;
|
||
- Parser;
|
||
- Mapper;
|
||
- Runtime;
|
||
- Routing;
|
||
- Trades Feed.
|
||
|
||
---
|
||
|
||
# Предпосылки
|
||
|
||
К началу Build архитектура подсистемы Market Data Acquisition уже содержала полноценный конвейер обработки транспортных моделей Quote, OHLC и REST Trade.
|
||
|
||
Для каждого из них использовалось одинаковое разделение ответственности между уровнями Pipeline.
|
||
|
||
Общая последовательность обработки выглядела следующим образом.
|
||
|
||
```text
|
||
Raw Source
|
||
│
|
||
▼
|
||
Schema Validation
|
||
│
|
||
▼
|
||
Transport Model
|
||
│
|
||
▼
|
||
Value Validation
|
||
│
|
||
▼
|
||
Mapper
|
||
│
|
||
▼
|
||
Domain Model
|
||
```
|
||
|
||
После завершения Build 060.11 аналогичный транспортный уровень появился и для WebSocket Trade.
|
||
|
||
```text
|
||
ValidatedWebSocketTradeDocument
|
||
│
|
||
▼
|
||
Trade Parser
|
||
│
|
||
▼
|
||
DzengiWebSocketTradeEvent
|
||
```
|
||
|
||
Однако следующий обязательный этап — проверка корректности самих значений транспортной модели — ещё отсутствовал.
|
||
|
||
Таким образом WebSocket-конвейер обработки сделок оставался архитектурно незавершённым.
|
||
|
||
---
|
||
|
||
# Архитектурное основание
|
||
|
||
Одним из базовых принципов архитектуры Dzentra является строгое разделение ответственности между последовательными уровнями Pipeline.
|
||
|
||
Каждый уровень отвечает только за одну категорию задач.
|
||
|
||
Для WebSocket Trade это разделение выглядит следующим образом.
|
||
|
||
```text
|
||
Schema Validation
|
||
```
|
||
|
||
отвечает исключительно за проверку структуры документа.
|
||
|
||
Она гарантирует:
|
||
|
||
- наличие транспортной оболочки;
|
||
- наличие объекта `payload`;
|
||
- присутствие обязательных полей;
|
||
- соответствие ожидаемым типам транспортного документа.
|
||
|
||
Следующий уровень —
|
||
|
||
```text
|
||
Parser
|
||
```
|
||
|
||
выполняет транспортное преобразование.
|
||
|
||
Он:
|
||
|
||
- извлекает значения из `payload`;
|
||
- переименовывает транспортные поля;
|
||
- создаёт immutable transport model.
|
||
|
||
После этого ответственность Parser полностью заканчивается.
|
||
|
||
Проверка корректности самих значений транспортной модели относится уже к следующему уровню —
|
||
|
||
```text
|
||
Value Validation
|
||
```
|
||
|
||
Именно Value Validation отвечает за проверку предметной допустимости данных.
|
||
|
||
На данном уровне анализируются:
|
||
|
||
- допустимость числовых значений;
|
||
- диапазоны значений;
|
||
- корректность строковых идентификаторов;
|
||
- невозможность использования специальных числовых значений (`NaN`, `Infinity`);
|
||
- другие ограничения транспортного контракта.
|
||
|
||
При этом Value Validation принципиально **не выполняет**:
|
||
|
||
- преобразование типов;
|
||
- Mapping;
|
||
- создание модели `Trade`;
|
||
- бизнес-логику;
|
||
- обработку Runtime.
|
||
|
||
Такое разделение позволяет каждому уровню Pipeline оставаться независимым и легко тестируемым.
|
||
|
||
---
|
||
|
||
# Результаты архитектурного аудита
|
||
|
||
Перед реализацией Build был выполнен аудит существующей подсистемы проверки значений.
|
||
|
||
В ходе анализа подтверждено наличие следующих компонентов.
|
||
|
||
Для Quote уже реализованы:
|
||
|
||
```text
|
||
validate_dzengi_websocket_quote_values(...)
|
||
```
|
||
|
||
Для OHLC реализованы:
|
||
|
||
```text
|
||
validate_dzengi_websocket_ohlc_values(...)
|
||
```
|
||
|
||
Для REST Trade реализованы:
|
||
|
||
```text
|
||
validate_rest_agg_trade_values(...)
|
||
```
|
||
|
||
Также подтверждено существование общего набора вспомогательных функций проверки:
|
||
|
||
```text
|
||
_trade_positive_int(...)
|
||
|
||
_trade_positive_decimal(...)
|
||
```
|
||
|
||
Указанные helper-функции уже используются существующей реализацией REST Trade и полностью соответствуют требованиям нового Build.
|
||
|
||
Одновременно аудит подтвердил отсутствие отдельной проверки значений транспортной модели
|
||
|
||
```text
|
||
DzengiWebSocketTradeEvent
|
||
```
|
||
|
||
Таким образом единственным отсутствующим элементом архитектурной цепочки являлся собственный уровень Value Validation для WebSocket Trade.
|
||
|
||
Build 060.12 полностью закрывает данный пробел и завершает ещё один архитектурный уровень серии Build 060.
|
||
|
||
---
|
||
|
||
# Архитектурное решение
|
||
|
||
По итогам проведённого аудита было принято решение не создавать новую модель данных и не вводить дополнительный слой между Parser и Mapper.
|
||
|
||
Вместо этого реализован тот же архитектурный шаблон, который уже используется для Quote, OHLC и REST Trade.
|
||
|
||
В систему добавлена функция
|
||
|
||
```text
|
||
validate_dzengi_websocket_trade_values(...)
|
||
```
|
||
|
||
которая принимает
|
||
|
||
```text
|
||
DzengiWebSocketTradeEvent
|
||
```
|
||
|
||
и выполняет проверку корректности значений транспортной модели.
|
||
|
||
При успешном завершении проверки объект не изменяется и продолжает использоваться последующими этапами Pipeline.
|
||
|
||
Таким образом транспортная модель проходит дополнительный уровень контроля без создания промежуточных объектов и без нарушения существующей архитектуры.
|
||
|
||
Конвейер WebSocket Trade принимает следующий вид.
|
||
|
||
```text
|
||
Raw WebSocket Object
|
||
│
|
||
▼
|
||
WebSocket Trade Schema Validation
|
||
│
|
||
▼
|
||
ValidatedWebSocketTradeDocument
|
||
│
|
||
▼
|
||
WebSocket Trade Parser
|
||
│
|
||
▼
|
||
DzengiWebSocketTradeEvent
|
||
│
|
||
▼
|
||
WebSocket Trade Value Validation
|
||
│
|
||
▼
|
||
DzengiWebSocketTradeEvent
|
||
```
|
||
|
||
Build 060.12 не изменяет архитектуру ранее реализованных компонентов и лишь завершает следующий обязательный уровень транспортного Pipeline.
|
||
|
||
# Реализованный уровень Value Validation
|
||
|
||
В файл
|
||
|
||
```text
|
||
src/market_data/acquisition/validation/values.py
|
||
```
|
||
|
||
добавлена новая функция
|
||
|
||
```text
|
||
validate_dzengi_websocket_trade_values(...)
|
||
```
|
||
|
||
Функция получает транспортную модель
|
||
|
||
```text
|
||
DzengiWebSocketTradeEvent
|
||
```
|
||
|
||
и подтверждает корректность всех значений, необходимых для последующего Mapping.
|
||
|
||
После успешного завершения проверки функция не изменяет объект и не создаёт новую транспортную модель.
|
||
|
||
Таким образом следующий уровень Pipeline получает тот же экземпляр
|
||
|
||
```text
|
||
DzengiWebSocketTradeEvent
|
||
```
|
||
|
||
который ранее был создан Parser.
|
||
|
||
---
|
||
|
||
# Почему Value Validation не создаёт новую модель
|
||
|
||
Во время архитектурного проектирования отдельно рассматривался вопрос о необходимости введения дополнительной модели
|
||
|
||
```text
|
||
ValidatedTradeTransportEvent
|
||
```
|
||
|
||
которая могла бы использоваться после проверки значений.
|
||
|
||
По результатам анализа было принято решение отказаться от подобного решения.
|
||
|
||
Основные причины:
|
||
|
||
- транспортная модель уже является immutable;
|
||
- проверка значений не изменяет содержимое объекта;
|
||
- повторное создание объекта не приносит дополнительных архитектурных преимуществ;
|
||
- аналогичный подход уже используется для Quote, OHLC и REST Trade.
|
||
|
||
В результате Value Validation подтверждает корректность существующего объекта и не создаёт новый экземпляр.
|
||
|
||
Подобное решение уменьшает количество транспортных моделей в системе и делает Pipeline более простым без потери архитектурной строгости.
|
||
|
||
---
|
||
|
||
# Проверяемая транспортная модель
|
||
|
||
Проверка выполняется над объектом
|
||
|
||
```python
|
||
@dataclass(frozen=True, slots=True)
|
||
class DzengiWebSocketTradeEvent:
|
||
trade_id: int
|
||
price: DzengiRawNumeric
|
||
size: DzengiRawNumeric
|
||
timestamp: int
|
||
symbol: str
|
||
buyer: bool
|
||
order_id: str
|
||
```
|
||
|
||
Value Validation рассматривает данный объект исключительно как транспортную модель.
|
||
|
||
Никаких преобразований типов при этом не выполняется.
|
||
|
||
---
|
||
|
||
# Проверка идентификатора сделки
|
||
|
||
Поле
|
||
|
||
```text
|
||
trade_id
|
||
```
|
||
|
||
обязательно должно содержать положительный целочисленный идентификатор сделки.
|
||
|
||
Во время проверки подтверждается:
|
||
|
||
- значение является целым числом;
|
||
- значение больше нуля.
|
||
|
||
При нарушении любого условия генерируется
|
||
|
||
```text
|
||
TradeValueError
|
||
```
|
||
|
||
с указанием пути
|
||
|
||
```text
|
||
$.payload.id
|
||
```
|
||
|
||
---
|
||
|
||
# Проверка цены сделки
|
||
|
||
Поле
|
||
|
||
```text
|
||
price
|
||
```
|
||
|
||
может поступать в различных транспортных представлениях.
|
||
|
||
Например:
|
||
|
||
```text
|
||
"63992.50"
|
||
|
||
63992
|
||
|
||
63992.50
|
||
```
|
||
|
||
Во время проверки подтверждается:
|
||
|
||
- возможность корректного преобразования в Decimal;
|
||
- отсутствие NaN;
|
||
- отсутствие Infinity;
|
||
- значение больше нуля.
|
||
|
||
При этом сама транспортная модель не изменяется.
|
||
|
||
Строковое значение остаётся строковым.
|
||
|
||
Преобразование в Decimal будет выполняться только на этапе Mapper.
|
||
|
||
---
|
||
|
||
# Проверка объёма сделки
|
||
|
||
Поле
|
||
|
||
```text
|
||
size
|
||
```
|
||
|
||
проверяется аналогично цене.
|
||
|
||
Подтверждается:
|
||
|
||
- корректность числового представления;
|
||
- отсутствие специальных значений;
|
||
- положительное значение.
|
||
|
||
При нарушении любого ограничения генерируется
|
||
|
||
```text
|
||
TradeValueError
|
||
```
|
||
|
||
с указанием пути
|
||
|
||
```text
|
||
$.payload.size
|
||
```
|
||
|
||
---
|
||
|
||
# Проверка временной метки
|
||
|
||
Поле
|
||
|
||
```text
|
||
timestamp
|
||
```
|
||
|
||
должно содержать положительное целое число.
|
||
|
||
Value Validation подтверждает:
|
||
|
||
- корректность типа;
|
||
- значение больше нуля.
|
||
|
||
Следует отметить, что Build 060.12 **не анализирует**, соответствует ли timestamp реальному времени.
|
||
|
||
Подобные проверки относятся уже к предметной области и могут появиться на более высоких уровнях системы.
|
||
|
||
---
|
||
|
||
# Проверка символа
|
||
|
||
Поле
|
||
|
||
```text
|
||
symbol
|
||
```
|
||
|
||
обязательно должно содержать непустую строку.
|
||
|
||
Проверяется результат после применения
|
||
|
||
```python
|
||
strip()
|
||
```
|
||
|
||
Таким образом значения
|
||
|
||
```text
|
||
""
|
||
|
||
" "
|
||
|
||
"\t"
|
||
|
||
"\n"
|
||
```
|
||
|
||
считаются недопустимыми.
|
||
|
||
---
|
||
|
||
# Проверка идентификатора ордера
|
||
|
||
Аналогичная проверка выполняется для поля
|
||
|
||
```text
|
||
order_id
|
||
```
|
||
|
||
После удаления пробельных символов строка должна оставаться непустой.
|
||
|
||
В противном случае генерируется
|
||
|
||
```text
|
||
TradeValueError
|
||
```
|
||
|
||
---
|
||
|
||
# Почему поле buyer не проверяется
|
||
|
||
Во время архитектурного аудита отдельно анализировался вопрос дополнительной проверки поля
|
||
|
||
```text
|
||
buyer
|
||
```
|
||
|
||
Было принято решение не выполнять каких-либо дополнительных ограничений.
|
||
|
||
Причины следующие.
|
||
|
||
Parser уже гарантирует:
|
||
|
||
```text
|
||
bool
|
||
```
|
||
|
||
В транспортном контракте биржи оба значения
|
||
|
||
```text
|
||
True
|
||
|
||
False
|
||
```
|
||
|
||
являются допустимыми.
|
||
|
||
Следовательно Value Validation не содержит никакой дополнительной логики для данного поля.
|
||
|
||
Это полностью соответствует принципу разделения ответственности между Parser и Value Validation.
|
||
|
||
---
|
||
|
||
# Повторное использование существующих helper-функций
|
||
|
||
Build 060.12 не вводит новых механизмов проверки числовых значений.
|
||
|
||
Вместо этого используются уже существующие функции проекта.
|
||
|
||
```text
|
||
_trade_positive_int(...)
|
||
```
|
||
|
||
используется для проверки:
|
||
|
||
- trade_id;
|
||
- timestamp.
|
||
|
||
---
|
||
|
||
```text
|
||
_trade_positive_decimal(...)
|
||
```
|
||
|
||
используется для проверки:
|
||
|
||
- price;
|
||
- size.
|
||
|
||
Подобный подход обеспечивает единое поведение всех механизмов проверки Trade независимо от источника получения данных.
|
||
|
||
---
|
||
|
||
# Использование TradeValueError
|
||
|
||
Все ошибки проверки значений используют существующее исключение
|
||
|
||
```text
|
||
TradeValueError
|
||
```
|
||
|
||
Build не вводит новых типов исключений.
|
||
|
||
Это сохраняет единую архитектуру обработки ошибок Trade.
|
||
|
||
Parser продолжает использовать
|
||
|
||
```text
|
||
TradeParseError
|
||
```
|
||
|
||
а Value Validation использует исключительно
|
||
|
||
```text
|
||
TradeValueError
|
||
```
|
||
|
||
Тем самым достигается чёткое разделение транспортных ошибок и ошибок корректности данных.
|
||
|
||
---
|
||
|
||
# Изменённые файлы
|
||
|
||
В рамках Build были изменены только два файла.
|
||
|
||
## Value Validation
|
||
|
||
```text
|
||
src/market_data/acquisition/validation/values.py
|
||
```
|
||
|
||
Добавлена функция
|
||
|
||
```text
|
||
validate_dzengi_websocket_trade_values(...)
|
||
```
|
||
|
||
Существующая логика проверки Quote, OHLC и REST Trade не изменялась.
|
||
|
||
---
|
||
|
||
## Unit-тесты
|
||
|
||
```text
|
||
tests/unit/market_data/acquisition/validation/test_websocket_trade_values.py
|
||
```
|
||
|
||
Добавлен полный набор unit-тестов нового уровня Value Validation.
|
||
|
||
---
|
||
|
||
# Добавленные тесты
|
||
|
||
В рамках Build реализовано сорок семь unit-тестов, полностью покрывающих новую функциональность.
|
||
|
||
## Проверка корректных событий
|
||
|
||
Подтверждается успешное прохождение проверки полностью корректной транспортной модели.
|
||
|
||
---
|
||
|
||
## Проверка buyer
|
||
|
||
Подтверждается корректная работа для обоих допустимых значений:
|
||
|
||
- `True`;
|
||
- `False`.
|
||
|
||
---
|
||
|
||
## Проверка различных представлений чисел
|
||
|
||
Отдельная серия тестов подтверждает корректную обработку:
|
||
|
||
- строк;
|
||
- целых чисел;
|
||
- чисел с плавающей точкой.
|
||
|
||
для полей:
|
||
|
||
- price;
|
||
- size.
|
||
|
||
---
|
||
|
||
## Проверка неположительных значений
|
||
|
||
Реализованы параметризованные тесты для:
|
||
|
||
- trade_id;
|
||
- timestamp;
|
||
- price;
|
||
- size.
|
||
|
||
Подтверждается генерация
|
||
|
||
```text
|
||
TradeValueError
|
||
```
|
||
|
||
при попытке использования нуля либо отрицательных значений.
|
||
|
||
---
|
||
|
||
## Проверка специальных числовых значений
|
||
|
||
Отдельная группа тестов подтверждает отклонение:
|
||
|
||
```text
|
||
NaN
|
||
|
||
Infinity
|
||
|
||
-Infinity
|
||
```
|
||
|
||
как в строковом виде, так и после передачи соответствующих значений типа float.
|
||
|
||
---
|
||
|
||
## Проверка некорректных строк
|
||
|
||
Реализованы проверки для значений:
|
||
|
||
```text
|
||
""
|
||
|
||
"invalid"
|
||
|
||
"--1"
|
||
```
|
||
|
||
Подтверждается корректная генерация исключений.
|
||
|
||
---
|
||
|
||
## Проверка строковых полей
|
||
|
||
Отдельные тесты подтверждают отклонение пустых либо содержащих только пробельные символы значений:
|
||
|
||
- symbol;
|
||
- order_id.
|
||
|
||
---
|
||
|
||
## Проверка неизменяемости транспортной модели
|
||
|
||
Отдельный тест подтверждает, что после успешной проверки объект
|
||
|
||
```text
|
||
DzengiWebSocketTradeEvent
|
||
```
|
||
|
||
остаётся полностью неизменным.
|
||
|
||
Value Validation не модифицирует транспортную модель.
|
||
|
||
# Результаты тестирования
|
||
|
||
После завершения реализации выполнен целевой запуск нового набора unit-тестов.
|
||
|
||
```bash
|
||
python -m pytest \
|
||
tests/unit/market_data/acquisition/validation/test_websocket_trade_values.py \
|
||
-q
|
||
```
|
||
|
||
Результат:
|
||
|
||
```text
|
||
47 passed in 0.05s
|
||
```
|
||
|
||
Все проверки новой функциональности успешно завершены.
|
||
|
||
Новый набор тестов полностью покрывает:
|
||
|
||
- успешную проверку корректной транспортной модели;
|
||
- обработку допустимых представлений числовых значений;
|
||
- генерацию исключений для всех типов некорректных данных;
|
||
- неизменяемость транспортной модели после успешной проверки.
|
||
|
||
Параметризованные тесты позволили существенно сократить объём тестового кода без уменьшения покрытия и обеспечили единообразную проверку всех допустимых и недопустимых вариантов входных данных.
|
||
|
||
---
|
||
|
||
# Регрессионное тестирование
|
||
|
||
После завершения реализации выполнен полный запуск набора unit-тестов проекта.
|
||
|
||
```bash
|
||
python -m pytest -q
|
||
```
|
||
|
||
Результат:
|
||
|
||
```text
|
||
1208 passed in 2.70s
|
||
```
|
||
|
||
Регрессий существующей функциональности не обнаружено.
|
||
|
||
Все ранее реализованные Build продолжают работать без каких-либо изменений.
|
||
|
||
Это подтверждает, что добавленная функциональность полностью изолирована и не влияет на существующие конвейеры обработки Quote, OHLC, REST Trade и остальные подсистемы проекта.
|
||
|
||
---
|
||
|
||
# Проверка компиляции
|
||
|
||
После завершения реализации выполнена полная проверка компиляции проекта.
|
||
|
||
```bash
|
||
python -m compileall src tests
|
||
```
|
||
|
||
Компиляция завершилась успешно.
|
||
|
||
Ошибок синтаксиса не обнаружено.
|
||
|
||
Все изменённые файлы успешно компилируются и не нарушают целостность проекта.
|
||
|
||
---
|
||
|
||
# Проверка Git diff
|
||
|
||
После устранения замечаний форматирования выполнена финальная проверка изменений.
|
||
|
||
```bash
|
||
git diff --check
|
||
```
|
||
|
||
Результат:
|
||
|
||
```text
|
||
без замечаний
|
||
```
|
||
|
||
Проверка подтвердила отсутствие:
|
||
|
||
- trailing whitespace;
|
||
- ошибок окончания строк;
|
||
- конфликтов diff;
|
||
- нарушений форматирования.
|
||
|
||
---
|
||
|
||
# Scope Build 060.12
|
||
|
||
В рамках данного Build реализован исключительно уровень
|
||
|
||
```text
|
||
WebSocket Trade Value Validation
|
||
```
|
||
|
||
Build **не включает**:
|
||
|
||
- WebSocket Trade Schema Validation;
|
||
- WebSocket Trade Parser;
|
||
- WebSocket Trade Mapper;
|
||
- WebSocket Trade Adapter;
|
||
- Runtime Integration;
|
||
- Unified Routing;
|
||
- Trades Feed.
|
||
|
||
Подобное ограничение полностью соответствует принятому принципу атомарной реализации Build.
|
||
|
||
Каждый этап дорожной карты реализует только один архитектурный уровень Pipeline.
|
||
|
||
---
|
||
|
||
# Архитектурный результат
|
||
|
||
После завершения Build система содержит полностью реализованные уровни транспортной обработки WebSocket Trade вплоть до проверки значений.
|
||
|
||
Конвейер обработки принимает следующий вид.
|
||
|
||
```text
|
||
Raw WebSocket Trade
|
||
│
|
||
▼
|
||
WebSocket Trade Schema Validation
|
||
│
|
||
▼
|
||
ValidatedWebSocketTradeDocument
|
||
│
|
||
▼
|
||
WebSocket Trade Parser
|
||
│
|
||
▼
|
||
DzengiWebSocketTradeEvent
|
||
│
|
||
▼
|
||
WebSocket Trade Value Validation
|
||
│
|
||
▼
|
||
DzengiWebSocketTradeEvent
|
||
```
|
||
|
||
Таким образом архитектура WebSocket Trade полностью повторяет ранее реализованные конвейеры Quote и OHLC.
|
||
|
||
Каждый уровень Pipeline выполняет исключительно собственную задачу.
|
||
|
||
---
|
||
|
||
# Состояние WebSocket Trade Pipeline
|
||
|
||
После завершения Build 060.12 конвейер имеет следующий вид.
|
||
|
||
```text
|
||
Raw WebSocket Trade
|
||
│
|
||
▼
|
||
ValidatedWebSocketTradeDocument
|
||
│
|
||
▼
|
||
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 | ✔ Completed |
|
||
| WebSocket Trade Parser | 060.11 | ✔ Completed |
|
||
| WebSocket Trade Value Validation | 060.12 | ✔ Completed |
|
||
| WebSocket Trade Mapper | 060.13 | Pending |
|
||
| WebSocket Trade Adapter | 060.14 | Pending |
|
||
| Unified WebSocket Routing | 060.15 | Pending |
|
||
|
||
---
|
||
|
||
# Соблюдение архитектурных принципов
|
||
|
||
В рамках Build полностью сохранены архитектурные инварианты Dzentra.
|
||
|
||
## Локальность изменений
|
||
|
||
Изменены только:
|
||
|
||
- `validation/values.py`;
|
||
- unit-тесты нового уровня Value Validation.
|
||
|
||
Существующая логика Quote, OHLC и REST Trade не изменялась.
|
||
|
||
---
|
||
|
||
## Повторное использование архитектуры
|
||
|
||
Новая реализация полностью повторяет существующий архитектурный шаблон проверки значений.
|
||
|
||
Новая архитектура не проектировалась.
|
||
|
||
Использован уже существующий подход, применяемый для остальных типов рыночных данных.
|
||
|
||
---
|
||
|
||
## Повторное использование инфраструктуры
|
||
|
||
Для проверки числовых значений повторно использованы существующие helper-функции проекта.
|
||
|
||
Build не вводит новых механизмов проверки и не дублирует уже реализованную функциональность.
|
||
|
||
Это обеспечивает единообразие поведения всех уровней Value Validation.
|
||
|
||
---
|
||
|
||
## Разделение ответственности
|
||
|
||
Value Validation отвечает исключительно за проверку корректности значений транспортной модели.
|
||
|
||
Build не выполняет:
|
||
|
||
- преобразование транспортных данных;
|
||
- Mapping;
|
||
- создание модели Trade;
|
||
- Runtime Integration;
|
||
- бизнес-логику.
|
||
|
||
Все перечисленные задачи остаются ответственностью последующих Build.
|
||
|
||
---
|
||
|
||
## Обратная совместимость
|
||
|
||
Существующая обработка:
|
||
|
||
- Quote;
|
||
- OHLC;
|
||
- REST Trade;
|
||
|
||
не изменилась.
|
||
|
||
Добавленная функциональность полностью изолирована и не оказывает влияния на ранее реализованные компоненты системы.
|
||
|
||
---
|
||
|
||
# Архитектурные решения Build (ADR)
|
||
|
||
## ADR-060.12-001
|
||
|
||
**Value Validation не создаёт новую транспортную модель.**
|
||
|
||
После успешной проверки используется тот же экземпляр `DzengiWebSocketTradeEvent`, который ранее был создан Parser.
|
||
|
||
Создание дополнительной модели признано избыточным и не дающим архитектурных преимуществ.
|
||
|
||
---
|
||
|
||
## ADR-060.12-002
|
||
|
||
**Value Validation не выполняет преобразование типов.**
|
||
|
||
Проверка подтверждает только допустимость значений.
|
||
|
||
Преобразование транспортных представлений (`str`, `int`, `float`) во внутренние типы (`Decimal`, `datetime` и другие) остаётся ответственностью Mapper.
|
||
|
||
---
|
||
|
||
## ADR-060.12-003
|
||
|
||
**Повторное использование существующих helper-функций является обязательным архитектурным принципом.**
|
||
|
||
Для проверки числовых значений используются существующие функции:
|
||
|
||
```text
|
||
_trade_positive_int()
|
||
|
||
_trade_positive_decimal()
|
||
```
|
||
|
||
Создание новых helper-функций признано необоснованным.
|
||
|
||
---
|
||
|
||
## ADR-060.12-004
|
||
|
||
**Parser и Value Validation используют разные классы исключений.**
|
||
|
||
Parser отвечает за транспортное преобразование и использует:
|
||
|
||
```text
|
||
TradeParseError
|
||
```
|
||
|
||
Value Validation отвечает исключительно за корректность значений и использует:
|
||
|
||
```text
|
||
TradeValueError
|
||
```
|
||
|
||
Подобное разделение обеспечивает прозрачную классификацию ошибок Pipeline.
|
||
|
||
---
|
||
|
||
# Критерии завершения Build
|
||
|
||
Build 060.12 считается завершённым, поскольку выполнены все поставленные задачи.
|
||
|
||
- ✔ реализована функция `validate_dzengi_websocket_trade_values()`;
|
||
- ✔ реализована проверка всех обязательных полей транспортной модели;
|
||
- ✔ реализована проверка положительных числовых значений;
|
||
- ✔ реализована проверка конечности числовых значений;
|
||
- ✔ реализована проверка строковых идентификаторов;
|
||
- ✔ повторно использованы существующие helper-функции;
|
||
- ✔ используются существующие исключения `TradeValueError`;
|
||
- ✔ транспортная модель остаётся неизменяемой;
|
||
- ✔ реализовано 47 unit-тестов;
|
||
- ✔ целевой набор тестов успешно проходит;
|
||
- ✔ полное регрессионное тестирование успешно завершено;
|
||
- ✔ проект успешно компилируется;
|
||
- ✔ `git diff --check` не выявил замечаний;
|
||
- ✔ изменения полностью укладываются в согласованный scope Build.
|
||
|
||
---
|
||
|
||
# Следующий этап
|
||
|
||
Следующим этапом дорожной карты является
|
||
|
||
```text
|
||
Build 060.13 — WebSocket Trade Mapper
|
||
```
|
||
|
||
Цель следующего Build:
|
||
|
||
- преобразование `DzengiWebSocketTradeEvent` в каноническую модель `Trade`;
|
||
- преобразование транспортных числовых значений во внутренние типы;
|
||
- формирование окончательной модели предметной области;
|
||
- завершение транспортного конвейера обработки WebSocket Trade.
|
||
|
||
---
|
||
|
||
# Итог
|
||
|
||
Build 060.12 завершил реализацию уровня **Value Validation** для WebSocket Trade и сделал архитектуру транспортной обработки сделок полностью симметричной существующим конвейерам Quote, OHLC и REST Trade.
|
||
|
||
Новая реализация основана на уже существующих архитектурных принципах Dzentra, повторно использует существующую инфраструктуру проверки значений, не создаёт дополнительных транспортных моделей и сохраняет строгое разделение ответственности между уровнями Pipeline.
|
||
|
||
Build ограничен согласованным scope, успешно прошёл целевое и полное регрессионное тестирование, подтвердил отсутствие регрессий и создаёт необходимую основу для следующего этапа дорожной карты — **Build 060.13 — WebSocket Trade Mapper**. |