14 KiB
Build 059.4 — WebSocket OHLC Value Validation
Проект: Dzentra Подсистема: Market Data Acquisition Этап: 059.4 Статус: Completed
Цель
Добавить предметную проверку значений транспортной модели:
DzengiWebSocketOhlcEvent
После выполнения Build 059.3 проект умеет преобразовывать структурно проверенный WebSocket-документ в transport-модель адаптера.
Build 059.4 проверяет, что значения этой модели допустимы для дальнейшей обработки.
На данном этапе не выполняются:
- преобразование timestamp в
datetime; - преобразование цен в
Decimalдля внутренней модели; - создание внутреннего события закрытия свечи;
- mapping;
- REST reconciliation;
- создание канонической
Candle; - runtime-интеграция.
Причина изменения
Parser проверяет только базовые транспортные типы.
Например, он допускает следующие значения:
symbol = ""
interval = "unsupported"
candle_type = "unknown"
open_time = -1
open_price = "NaN"
high_price = -10
low_price = 100
close_price = 0
Они корректны с точки зрения базовых Python-типов, но недопустимы с точки зрения предметного контракта OHLC.
Поэтому необходим отдельный слой Value Validation.
Реализованные изменения
Изменён файл:
src/market_data/acquisition/validation/values.py
Добавлена функция:
validate_dzengi_websocket_ohlc_values()
Она принимает:
DzengiWebSocketOhlcEvent
и проверяет предметную допустимость всех его полей.
Новое исключение
В файл:
src/market_data/acquisition/exceptions.py
добавлено специализированное исключение:
CandleWebSocketValueError
Оно используется только для ошибок значений WebSocket OHLC-событий.
Ошибки WebSocket OHLC теперь разделены по слоям:
CandleWebSocketSchemaError
CandleWebSocketParseError
CandleWebSocketValueError
Это сохраняет явное разделение ответственности:
Schema Validation
↓
проверка структуры JSON
Parser
↓
проверка транспортных типов
Value Validation
↓
проверка предметной допустимости
Поддерживаемые интервалы
В Value Validation зафиксирован набор интервалов, который уже поддерживается действующим Candles Feed:
1m
5m
15m
1h
Допустимые значения хранятся в immutable-наборе:
_SUPPORTED_WEBSOCKET_OHLC_INTERVALS
Значения сравниваются без автоматической нормализации.
Поэтому отклоняются:
""
"1s"
"4h"
"1M"
" 1m "
Это преднамеренное поведение.
Parser и validator не должны незаметно исправлять внешний контракт.
Поддерживаемые типы свечей
По результатам runtime-исследования Build 058 подтверждены два допустимых значения:
classic
heikin-ashi
Они зафиксированы в immutable-наборе:
_SUPPORTED_WEBSOCKET_OHLC_TYPES
Отклоняются:
""
"bid"
"ask"
"Classic"
"unknown"
" classic "
REST-параметр:
priceType = bid | ask
не является WebSocket-параметром типа свечи.
WebSocket использует:
type = classic | heikin-ashi
Проверка символа
Поле:
symbol
должно содержать хотя бы один непробельный символ.
Отклоняются:
""
" "
"\t"
"\n"
Value Validation не выполняет:
- нормализацию символа;
- проверку существования инструмента;
- преобразование alias;
- обращение к Instrument Registry.
На этом слое проверяется только непустое значение.
Проверка timestamp
Поле:
open_time
должно быть больше нуля.
Отклоняются:
0
-1
-1784224740000
Проверка базового типа int уже была выполнена parser-слоем в Build 059.3.
Value Validation не преобразует timestamp в datetime.
Проверка OHLC
Поля:
open_price
high_price
low_price
close_price
принимают транспортный тип:
DzengiRawNumeric
То есть могут быть представлены как:
str
int
float
На этапе Value Validation каждое значение временно преобразуется в Decimal только для проверки.
Transport-модель при этом не изменяется.
Проверка корректности числовых значений
Каждое поле OHLC должно быть корректным числом.
Отклоняются:
""
"invalid"
"--1"
Для таких значений выбрасывается:
CandleWebSocketValueError
с указанием точного JSON-пути.
Пример:
$.payload.o должно быть корректным числом
Проверка конечности
Каждая цена должна быть конечным числом.
Отклоняются:
"NaN"
"Infinity"
"-Infinity"
float("nan")
float("inf")
float("-inf")
Это предотвращает проникновение специальных значений в mapping и downstream-анализ.
Проверка положительности
Все цены OHLC должны быть строго больше нуля.
Отклоняются:
0
-1
"-0.01"
Проверка выполняется отдельно для:
$.payload.o
$.payload.h
$.payload.l
$.payload.c
OHLC-инварианты
После преобразования цен во временные Decimal проверяются стандартные инварианты свечи.
High не меньше Low
Должно выполняться:
high >= low
Иначе:
$.payload.h не должно быть меньше $.payload.l
High не меньше Open
Должно выполняться:
high >= open
Иначе:
$.payload.h не должно быть меньше $.payload.o
High не меньше Close
Должно выполняться:
high >= close
Иначе:
$.payload.h не должно быть меньше $.payload.c
Low не выше Open
Должно выполняться:
low <= open
Иначе:
$.payload.l не должно превышать $.payload.o
Low не выше Close
Должно выполняться:
low <= close
Иначе:
$.payload.l не должно превышать $.payload.c
Поддержка плоской свечи
Допускается свеча, у которой:
open = high = low = close
Например:
64000
64000
64000
64000
Такая свеча удовлетворяет всем OHLC-инвариантам и является допустимой.
Отсутствие изменения transport-модели
Value Validation использует Decimal только как временный тип проверки.
Исходный объект:
DzengiWebSocketOhlcEvent
не изменяется.
Сохраняются исходные значения и их транспортные типы:
str
int
float
Постоянное преобразование во внутренние типы будет выполнено позже на mapping-этапе.
Новый конвейер
После Build 059.4 подготовленная часть конвейера выглядит так:
Raw WebSocket message
↓
validate_dzengi_websocket_ohlc_schema()
↓
ValidatedWebSocketOhlcDocument
↓
parse_dzengi_websocket_ohlc()
↓
DzengiWebSocketOhlcEvent
↓
validate_dzengi_websocket_ohlc_values()
↓
проверенная transport-модель
↓
Internal Close Event Model
↓
Mapper
↓
REST reconciliation
↓
Canonical Candle
Unit Tests
Создан файл:
tests/unit/market_data/acquisition/validation/test_websocket_ohlc_values.py
Проверяются:
- все поддерживаемые интервалы;
- оба поддерживаемых типа свечей;
- строковые, целые и вещественные представления цен;
- пустые символы;
- неподдерживаемые интервалы;
- неподдерживаемые типы свечей;
- неположительный timestamp;
- нулевые цены;
- отрицательные цены;
NaN;- положительная и отрицательная бесконечность;
- некорректные числовые строки;
high < low;high < open;high < close;low > open;low > close;- плоская свеча.
Всего выполнено:
84 tests
Проверка синтаксиса
Выполнена команда:
python -m compileall \
src/market_data/acquisition/exceptions.py \
src/market_data/acquisition/validation/values.py \
tests/unit/market_data/acquisition/validation/test_websocket_ohlc_values.py
Результат:
успешно
Целевые тесты
Выполнена команда:
python -m pytest -q \
tests/unit/market_data/acquisition/validation/test_websocket_ohlc_values.py
Результат:
84 passed in 0.03s
Регрессия value-validation слоя
Выполнена команда:
python -m pytest -q \
tests/unit/market_data/acquisition/validation/test_values.py \
tests/unit/market_data/acquisition/validation/test_quote_values.py \
tests/unit/market_data/acquisition/validation/test_websocket_quote_values.py \
tests/unit/market_data/acquisition/validation/test_candle_values.py \
tests/unit/market_data/acquisition/validation/test_websocket_ohlc_values.py
Результат:
150 passed in 0.05s
Проверка форматирования
Выполнена команда:
git diff --check
Ошибок форматирования не обнаружено.
Изменённые файлы
src/market_data/acquisition/exceptions.py
src/market_data/acquisition/validation/values.py
Создан файл:
tests/unit/market_data/acquisition/validation/test_websocket_ohlc_values.py
Документация этапа:
docs/migrations/build_059_4.md
Совместимость
Изменение полностью обратно совместимо.
Не изменены:
- REST Candles Feed;
- REST Candle validation;
- Quote Feed;
- WebSocket Quote validation;
- parser WebSocket OHLC;
- ExchangeService;
- runtime;
- Market Analysis;
- Trading.
Новая функция пока не подключена к рабочему WebSocket Adapter и не влияет на работающий бот.
Ограничения этапа
Build 059.4 не выполняет:
- преобразование timestamp в UTC
datetime; - преобразование цен в постоянные
Decimal; - создание внутреннего события закрытия свечи;
- добавление
source; - mapping;
- WebSocket Adapter;
- WebSocket subscription;
- REST reconciliation;
- проверку совпадения WebSocket и REST OHLC;
- создание канонической
Candle; - runtime-интеграцию.
Итог
Build 059.4 завершает слой предметной проверки значений Dzengi WebSocket OHLC.
Проект теперь умеет безопасно проверять:
DzengiWebSocketOhlcEvent
на:
- допустимость символа;
- допустимость интервала;
- допустимость типа свечи;
- корректность timestamp;
- корректность чисел;
- конечность цен;
- положительность цен;
- соблюдение OHLC-инвариантов.
Следующий этап:
Build 059.5 — Internal Close Event Model