1268 lines
21 KiB
Markdown
1268 lines
21 KiB
Markdown
# Build 058 — Runtime исследование Dzengi WebSocket OHLC Market Data
|
||
|
||
---
|
||
|
||
# Контроль документа
|
||
|
||
| Свойство | Значение |
|
||
|----------|-----------|
|
||
| Build | 058 |
|
||
| Название | Runtime исследование Dzengi WebSocket OHLC Market Data |
|
||
| Статус | Completed |
|
||
| Проект | Dzentra |
|
||
| Подсистема | Market Data Acquisition |
|
||
| Источник | Dzengi Exchange |
|
||
| Дата | 2026-07-16 |
|
||
|
||
---
|
||
|
||
# Цель Build
|
||
|
||
Провести полное runtime-исследование контракта WebSocket
|
||
|
||
```
|
||
OHLCMarketData.subscribe
|
||
```
|
||
|
||
и определить возможность его использования в качестве
|
||
канонического источника Candles Feed.
|
||
|
||
Необходимо было подтвердить:
|
||
|
||
- соответствие Swagger реальному API;
|
||
- формат подписки;
|
||
- формат ACK;
|
||
- формат событий;
|
||
- поддерживаемые параметры;
|
||
- поддержку нескольких символов;
|
||
- поддержку нескольких интервалов;
|
||
- наличие или отсутствие Volume;
|
||
- соответствие REST API;
|
||
- возможность использования в Build 059.
|
||
|
||
---
|
||
|
||
# Исходные материалы
|
||
|
||
Были исследованы:
|
||
|
||
REST
|
||
|
||
```
|
||
GET /api/v1/klines
|
||
```
|
||
|
||
WebSocket
|
||
|
||
```
|
||
OHLCMarketData.subscribe
|
||
```
|
||
|
||
Swagger WebSocket
|
||
|
||
```
|
||
wss://.../connect
|
||
```
|
||
|
||
Также были выполнены реальные подключения к:
|
||
|
||
```
|
||
demo-api-adapter.dzengi.com
|
||
```
|
||
|
||
и
|
||
|
||
```
|
||
api-adapter.dzengi.com
|
||
```
|
||
|
||
---
|
||
|
||
# Вывод по Demo
|
||
|
||
Во время исследования обнаружено:
|
||
|
||
Demo WebSocket корректно принимает подписку:
|
||
|
||
```
|
||
OHLCMarketData.subscribe
|
||
```
|
||
|
||
но поток данных практически отсутствует.
|
||
|
||
Поэтому дальнейшее исследование проводилось исключительно
|
||
на Production API.
|
||
|
||
---
|
||
|
||
# Production WebSocket
|
||
|
||
Используемый URL
|
||
|
||
```
|
||
wss://api-adapter.dzengi.com/connect
|
||
```
|
||
|
||
Подписка выполняется сообщением
|
||
|
||
```json
|
||
{
|
||
"correlationId": "<uuid>",
|
||
"destination": "OHLCMarketData.subscribe",
|
||
"payload": {
|
||
"intervals": [
|
||
"1m"
|
||
],
|
||
"symbols": [
|
||
"BTC/USD_LEVERAGE"
|
||
],
|
||
"type": "classic"
|
||
}
|
||
}
|
||
```
|
||
|
||
После отправки сервер возвращает ACK.
|
||
|
||
---
|
||
|
||
# ACK
|
||
|
||
Фактический ответ сервера
|
||
|
||
```json
|
||
{
|
||
"correlationId": "...",
|
||
"destination": "OHLCMarketData.subscribe",
|
||
"payload": {
|
||
"subscriptions": {
|
||
"BTC/USD_LEVERAGE:1m": "PROCESSED"
|
||
}
|
||
},
|
||
"status": "OK"
|
||
}
|
||
```
|
||
|
||
Подтверждено:
|
||
|
||
- destination совпадает со Swagger;
|
||
- status = OK;
|
||
- подписки перечислены внутри payload.subscriptions;
|
||
- ключ имеет вид
|
||
|
||
```
|
||
symbol:interval
|
||
```
|
||
|
||
например
|
||
|
||
```
|
||
BTC/USD_LEVERAGE:1m
|
||
```
|
||
|
||
---
|
||
|
||
# Поддержка нескольких интервалов
|
||
|
||
Проверена подписка
|
||
|
||
```json
|
||
{
|
||
"payload": {
|
||
"symbols":[
|
||
"BTC/USD_LEVERAGE"
|
||
],
|
||
"intervals":[
|
||
"1m",
|
||
"5m"
|
||
],
|
||
"type":"classic"
|
||
}
|
||
}
|
||
```
|
||
|
||
Полученный ACK
|
||
|
||
```json
|
||
{
|
||
"subscriptions": {
|
||
"BTC/USD_LEVERAGE:1m":"PROCESSED",
|
||
"BTC/USD_LEVERAGE:5m":"PROCESSED"
|
||
}
|
||
}
|
||
```
|
||
|
||
Таким образом подтверждено,
|
||
что одна подписка может одновременно обслуживать
|
||
несколько таймфреймов.
|
||
|
||
Каждая комбинация
|
||
|
||
```
|
||
symbol + interval
|
||
```
|
||
|
||
имеет собственный статус.
|
||
|
||
---
|
||
|
||
# Формат события
|
||
|
||
После закрытия свечи сервер публикует
|
||
|
||
```json
|
||
{
|
||
"destination":"ohlc.event",
|
||
"payload":{
|
||
"symbol":"BTC/USD_LEVERAGE",
|
||
"interval":"1m",
|
||
"type":"classic",
|
||
|
||
"t":1784224740000,
|
||
|
||
"o":63992.0,
|
||
"h":64032.55,
|
||
"l":63984.0,
|
||
"c":64032.55
|
||
},
|
||
"status":"OK"
|
||
}
|
||
```
|
||
|
||
Полученные поля
|
||
|
||
| Поле | Значение |
|
||
|------|----------|
|
||
| symbol | инструмент |
|
||
| interval | таймфрейм |
|
||
| type | тип свечи |
|
||
| t | open time |
|
||
| o | Open |
|
||
| h | High |
|
||
| l | Low |
|
||
| c | Close |
|
||
|
||
Volume отсутствует.
|
||
|
||
Это подтверждено всеми полученными событиями.
|
||
|
||
---
|
||
|
||
# Исследование типа свечей
|
||
|
||
Swagger указывает,
|
||
что поле
|
||
|
||
```
|
||
type
|
||
```
|
||
|
||
используется для выбора разновидности свечей.
|
||
|
||
Во время runtime-исследования были проверены все возможные значения.
|
||
|
||
---
|
||
|
||
# Попытка использовать bid
|
||
|
||
Подписка
|
||
|
||
```json
|
||
{
|
||
"payload":{
|
||
"symbols":[
|
||
"BTC/USD_LEVERAGE"
|
||
],
|
||
"intervals":[
|
||
"1m"
|
||
],
|
||
"type":"bid"
|
||
}
|
||
}
|
||
```
|
||
|
||
Ответ сервера
|
||
|
||
```json
|
||
{
|
||
"subscriptions":{
|
||
"bid":"ERROR: Invalid type. Valid: classic, heikin-ashi"
|
||
}
|
||
}
|
||
```
|
||
|
||
Таким образом подтверждено,
|
||
что WebSocket не использует параметр
|
||
|
||
```
|
||
priceType
|
||
```
|
||
|
||
аналогичный REST.
|
||
|
||
---
|
||
|
||
# Поддерживаемые значения type
|
||
|
||
Во время исследования подтверждены два допустимых значения
|
||
|
||
```
|
||
classic
|
||
```
|
||
|
||
и
|
||
|
||
```
|
||
heikin-ashi
|
||
```
|
||
|
||
Других поддерживаемых вариантов обнаружено не было.
|
||
|
||
---
|
||
|
||
# Исследование classic
|
||
|
||
Подписка
|
||
|
||
```json
|
||
{
|
||
"payload":{
|
||
"symbols":[
|
||
"BTC/USD_LEVERAGE"
|
||
],
|
||
"intervals":[
|
||
"1m"
|
||
],
|
||
"type":"classic"
|
||
}
|
||
}
|
||
```
|
||
|
||
События поступают регулярно
|
||
после закрытия каждой минутной свечи.
|
||
|
||
Пример
|
||
|
||
```json
|
||
{
|
||
"destination":"ohlc.event",
|
||
"payload":{
|
||
"symbol":"BTC/USD_LEVERAGE",
|
||
"interval":"1m",
|
||
"type":"classic",
|
||
"t":1784224860000,
|
||
"o":64047.45,
|
||
"h":64099.10,
|
||
"l":64042.25,
|
||
"c":64098.00
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
# Сравнение с REST
|
||
|
||
Для той же свечи был выполнен запрос
|
||
|
||
```
|
||
GET /api/v1/klines
|
||
```
|
||
|
||
```
|
||
priceType=bid
|
||
```
|
||
|
||
Получен ответ
|
||
|
||
```json
|
||
[
|
||
[
|
||
1784224860000,
|
||
"64047.45",
|
||
"64099.10",
|
||
"64042.25",
|
||
"64098.00",
|
||
165
|
||
]
|
||
]
|
||
```
|
||
|
||
Полное сравнение
|
||
|
||
| Поле | REST | WebSocket |
|
||
|------|------|-----------|
|
||
| Open Time | ✔ | ✔ |
|
||
| Open | ✔ | ✔ |
|
||
| High | ✔ | ✔ |
|
||
| Low | ✔ | ✔ |
|
||
| Close | ✔ | ✔ |
|
||
| Volume | ✔ | ✖ |
|
||
|
||
OHLC совпадают полностью.
|
||
|
||
---
|
||
|
||
# Вывод
|
||
|
||
Runtime подтвердил,
|
||
что
|
||
|
||
```
|
||
classic
|
||
```
|
||
|
||
представляет собой классические рыночные свечи,
|
||
идентичные
|
||
|
||
```
|
||
REST /klines
|
||
priceType=bid
|
||
```
|
||
|
||
за исключением отсутствующего объёма.
|
||
|
||
---
|
||
|
||
# Исследование Heikin-Ashi
|
||
|
||
Подписка
|
||
|
||
```json
|
||
{
|
||
"payload":{
|
||
"symbols":[
|
||
"BTC/USD_LEVERAGE"
|
||
],
|
||
"intervals":[
|
||
"1m"
|
||
],
|
||
"type":"heikin-ashi"
|
||
}
|
||
}
|
||
```
|
||
|
||
Получен ACK
|
||
|
||
```json
|
||
{
|
||
"subscriptions":{
|
||
"BTC/USD_LEVERAGE:1m":"PROCESSED"
|
||
}
|
||
}
|
||
```
|
||
|
||
После этого сервер начал публиковать события
|
||
|
||
```json
|
||
{
|
||
"destination":"ohlc.event",
|
||
"payload":{
|
||
"symbol":"BTC/USD_LEVERAGE",
|
||
"interval":"1m",
|
||
"type":"heikin-ashi",
|
||
|
||
"t":1784225280000,
|
||
|
||
"o":64068.18,
|
||
"h":64128.80,
|
||
"l":64068.18,
|
||
"c":64100.85
|
||
}
|
||
}
|
||
```
|
||
|
||
Получены несколько последовательных свечей.
|
||
|
||
---
|
||
|
||
# Вывод по Heikin-Ashi
|
||
|
||
Контракт полностью совпадает
|
||
с форматом
|
||
|
||
```
|
||
classic
|
||
```
|
||
|
||
Изменяется только способ расчёта OHLC.
|
||
|
||
Следовательно
|
||
|
||
```
|
||
classic
|
||
```
|
||
|
||
и
|
||
|
||
```
|
||
heikin-ashi
|
||
```
|
||
|
||
представляют две различные серии свечей,
|
||
имеющие одинаковый транспортный контракт.
|
||
|
||
---
|
||
|
||
# Исследование времени публикации
|
||
|
||
Во время наблюдения было подтверждено,
|
||
что событие публикуется только после завершения интервала.
|
||
|
||
Например
|
||
|
||
```
|
||
t = 1784224860000
|
||
```
|
||
|
||
соответствует времени открытия свечи.
|
||
|
||
Само событие было получено примерно через одну минуту,
|
||
после её закрытия.
|
||
|
||
Таким образом
|
||
|
||
```
|
||
t
|
||
```
|
||
|
||
является временем открытия свечи,
|
||
а не временем публикации события.
|
||
|
||
---
|
||
|
||
# Исследование нескольких интервалов
|
||
|
||
Одновременно были подписаны
|
||
|
||
```
|
||
1m
|
||
```
|
||
|
||
и
|
||
|
||
```
|
||
5m
|
||
```
|
||
|
||
После закрытия пятиминутного интервала
|
||
сервер практически одновременно прислал
|
||
|
||
```
|
||
1m
|
||
```
|
||
|
||
и
|
||
|
||
```
|
||
5m
|
||
```
|
||
|
||
события.
|
||
|
||
Полученное пятиминутное событие
|
||
|
||
```json
|
||
{
|
||
"payload":{
|
||
"interval":"5m",
|
||
"type":"classic",
|
||
|
||
"t":1784225400000,
|
||
|
||
"o":64130.80,
|
||
"h":64184.70,
|
||
"l":64118.20,
|
||
"c":64151.00
|
||
}
|
||
}
|
||
```
|
||
|
||
Тем самым подтверждено,
|
||
что сервер самостоятельно агрегирует свечи
|
||
для всех запрошенных интервалов.
|
||
|
||
Клиенту не требуется самостоятельно строить
|
||
5m, 15m или другие свечи
|
||
из минутных данных.
|
||
|
||
---
|
||
|
||
# Сравнение REST и WebSocket
|
||
|
||
Во время исследования одновременно выполнялись:
|
||
|
||
- периодические запросы REST;
|
||
- постоянная подписка WebSocket.
|
||
|
||
Это позволило определить различия поведения.
|
||
|
||
---
|
||
|
||
# Поведение REST
|
||
|
||
Запрос
|
||
|
||
```
|
||
GET /api/v1/klines
|
||
```
|
||
|
||
возвращает последние свечи.
|
||
|
||
Последняя свеча является текущей,
|
||
поэтому её значения изменяются
|
||
по мере поступления новых сделок.
|
||
|
||
Например
|
||
|
||
21:01:41
|
||
|
||
```text
|
||
Open 64047.45
|
||
|
||
High 64074.90
|
||
|
||
Low 64042.25
|
||
|
||
Close 64074.90
|
||
|
||
Volume 111
|
||
```
|
||
|
||
Через некоторое время
|
||
|
||
21:01:56
|
||
|
||
```text
|
||
High 64095.45
|
||
|
||
Close 64095.45
|
||
|
||
Volume 153
|
||
```
|
||
|
||
Ещё позже
|
||
|
||
21:02:11
|
||
|
||
```text
|
||
High 64099.10
|
||
|
||
Close 64098.00
|
||
|
||
Volume 165
|
||
```
|
||
|
||
Таким образом REST показывает
|
||
формирующуюся свечу.
|
||
|
||
---
|
||
|
||
# Поведение WebSocket
|
||
|
||
Для этой же свечи был получен
|
||
|
||
```json
|
||
{
|
||
"t":1784224860000,
|
||
|
||
"o":64047.45,
|
||
"h":64099.10,
|
||
"l":64042.25,
|
||
"c":64098.00
|
||
}
|
||
```
|
||
|
||
WebSocket опубликовал событие
|
||
только после окончания интервала.
|
||
|
||
Таким образом опубликована
|
||
уже окончательная свеча.
|
||
|
||
---
|
||
|
||
# Главное различие
|
||
|
||
REST
|
||
|
||
```
|
||
может вернуть
|
||
ещё незавершённую свечу
|
||
```
|
||
|
||
WebSocket
|
||
|
||
```
|
||
публикует только
|
||
закрытую свечу
|
||
```
|
||
|
||
Именно это делает WebSocket
|
||
очень полезным источником событий.
|
||
|
||
---
|
||
|
||
# Исследование Volume
|
||
|
||
Во всех событиях WebSocket отсутствует
|
||
|
||
```
|
||
volume
|
||
```
|
||
|
||
Например
|
||
|
||
```json
|
||
{
|
||
"payload":{
|
||
"o":64096.20,
|
||
"h":64110.60,
|
||
"l":64045.45,
|
||
"c":64052.50
|
||
}
|
||
}
|
||
```
|
||
|
||
Поле
|
||
|
||
```
|
||
volume
|
||
```
|
||
|
||
не передаётся.
|
||
|
||
Однако REST возвращает
|
||
|
||
```text
|
||
389
|
||
```
|
||
|
||
для этой же свечи.
|
||
|
||
Следовательно
|
||
|
||
WebSocket публикует
|
||
|
||
```
|
||
OHLC
|
||
```
|
||
|
||
но не
|
||
|
||
```
|
||
OHLCV
|
||
```
|
||
|
||
---
|
||
|
||
# Ограничения использования
|
||
|
||
Текущая каноническая модель проекта
|
||
|
||
```
|
||
Candle
|
||
```
|
||
|
||
содержит
|
||
|
||
```python
|
||
volume: Decimal
|
||
```
|
||
|
||
Следовательно WebSocket-событие
|
||
не может напрямую быть преобразовано
|
||
в канонический Candle.
|
||
|
||
Заполнение
|
||
|
||
```
|
||
volume = 0
|
||
```
|
||
|
||
является архитектурно неверным,
|
||
поскольку означает
|
||
"объём равен нулю",
|
||
хотя на самом деле
|
||
объём неизвестен.
|
||
|
||
Поэтому WebSocket не должен
|
||
непосредственно создавать
|
||
канонический Candle.
|
||
|
||
---
|
||
|
||
# Архитектурное решение
|
||
|
||
На основании проведённого исследования
|
||
для Build 059 принято решение
|
||
использовать гибридную схему.
|
||
|
||
```
|
||
OHLCMarketData.subscribe
|
||
|
||
│
|
||
|
||
▼
|
||
|
||
получено событие закрытия свечи
|
||
|
||
│
|
||
|
||
▼
|
||
|
||
REST GET /klines
|
||
|
||
(symbol + interval + open_time)
|
||
|
||
│
|
||
|
||
▼
|
||
|
||
получена окончательная OHLCV свеча
|
||
|
||
│
|
||
|
||
▼
|
||
|
||
Validation
|
||
|
||
│
|
||
|
||
▼
|
||
|
||
Parser
|
||
|
||
│
|
||
|
||
▼
|
||
|
||
Mapper
|
||
|
||
│
|
||
|
||
▼
|
||
|
||
Canonical Candle
|
||
```
|
||
|
||
Таким образом
|
||
|
||
WebSocket становится
|
||
|
||
```
|
||
источником события
|
||
о закрытии свечи
|
||
```
|
||
|
||
а REST
|
||
|
||
остаётся
|
||
|
||
```
|
||
авторитетным источником
|
||
полной OHLCV модели.
|
||
```
|
||
|
||
---
|
||
|
||
# Новая транспортная модель
|
||
|
||
Для Build 059 рекомендуется
|
||
создать отдельную transport-модель
|
||
|
||
```
|
||
DzengiWebSocketOhlcEvent
|
||
```
|
||
|
||
например
|
||
|
||
```python
|
||
@dataclass(frozen=True, slots=True)
|
||
class DzengiWebSocketOhlcEvent:
|
||
|
||
symbol: str
|
||
|
||
interval: str
|
||
|
||
candle_type: str
|
||
|
||
open_time: int
|
||
|
||
open_price: DzengiRawNumeric
|
||
|
||
high_price: DzengiRawNumeric
|
||
|
||
low_price: DzengiRawNumeric
|
||
|
||
close_price: DzengiRawNumeric
|
||
```
|
||
|
||
Она не должна заменять
|
||
каноническую модель Candle.
|
||
|
||
Её назначение —
|
||
|
||
представление транспортного
|
||
WebSocket-события.
|
||
|
||
---
|
||
|
||
# Итоги исследования
|
||
|
||
Подтверждено
|
||
|
||
✓ WebSocket полностью работоспособен.
|
||
|
||
✓ Поддерживает несколько инструментов.
|
||
|
||
✓ Поддерживает несколько интервалов.
|
||
|
||
✓ Поддерживает
|
||
|
||
```
|
||
classic
|
||
```
|
||
|
||
и
|
||
|
||
```
|
||
heikin-ashi
|
||
```
|
||
|
||
✓ Публикует только завершённые свечи.
|
||
|
||
✓ Формат classic совпадает
|
||
с REST bid OHLC.
|
||
|
||
✓ Передаёт только OHLC.
|
||
|
||
✓ Не содержит Volume.
|
||
|
||
✓ Может использоваться
|
||
как триггер появления
|
||
новой закрытой свечи.
|
||
|
||
---
|
||
|
||
# Вывод Build 058
|
||
|
||
Исследование показало,
|
||
что
|
||
|
||
```
|
||
OHLCMarketData.subscribe
|
||
```
|
||
|
||
не является заменой REST Candles Feed.
|
||
|
||
Однако данный поток является
|
||
идеальным механизмом
|
||
для своевременного обнаружения
|
||
момента закрытия новой свечи.
|
||
|
||
Именно такая схема
|
||
будет реализована
|
||
в следующем этапе проекта.
|
||
|
||
---
|
||
|
||
# Следующий Build
|
||
|
||
```
|
||
Build 059
|
||
|
||
Интеграция WebSocket OHLC
|
||
в Candles Feed
|
||
```
|
||
|
||
Основные задачи Build 059
|
||
|
||
- создать транспортную модель
|
||
DzengiWebSocketOhlcEvent;
|
||
|
||
- реализовать schema validation;
|
||
|
||
- реализовать parser;
|
||
|
||
- реализовать value validation;
|
||
|
||
- реализовать mapper;
|
||
|
||
- добавить WebSocket Adapter;
|
||
|
||
- интегрировать новый источник
|
||
в Candles Feed;
|
||
|
||
- использовать WebSocket
|
||
как источник события
|
||
закрытия свечи;
|
||
|
||
- использовать REST
|
||
для получения окончательной
|
||
OHLCV свечи;
|
||
|
||
- сохранить существующую
|
||
каноническую модель Candle
|
||
без изменений.
|
||
|
||
---
|
||
|
||
# Работа с диагностическим скриптом
|
||
|
||
В рамках Build 058 был разработан отдельный диагностический инструмент
|
||
|
||
```
|
||
scripts/check_ohlc_websocket.py
|
||
```
|
||
|
||
Назначение скрипта:
|
||
|
||
- проверка доступности WebSocket;
|
||
- проверка подписки OHLCMarketData.subscribe;
|
||
- получение ACK;
|
||
- получение реальных OHLC-событий;
|
||
- проверка нескольких символов;
|
||
- проверка нескольких интервалов;
|
||
- проверка типа свечей;
|
||
- исследование поведения API после изменений на стороне биржи.
|
||
|
||
Скрипт не является частью Production-кода
|
||
и предназначен исключительно
|
||
для инженерной диагностики.
|
||
|
||
---
|
||
|
||
# Проверка синтаксиса
|
||
|
||
```bash
|
||
python -m compileall \
|
||
scripts/check_ohlc_websocket.py
|
||
```
|
||
|
||
---
|
||
|
||
# Проверка оформления
|
||
|
||
```bash
|
||
git diff --check
|
||
```
|
||
|
||
---
|
||
|
||
# Запуск
|
||
|
||
```bash
|
||
EXCHANGE_BASE_URL=https://api-adapter.dzengi.com \
|
||
EXCHANGE_WS_URL=wss://api-adapter.dzengi.com \
|
||
EXCHANGE_API_KEY="" \
|
||
PYTHONPATH=. \
|
||
python scripts/check_ohlc_websocket.py
|
||
```
|
||
|
||
---
|
||
|
||
# Настраиваемые параметры
|
||
|
||
В начале файла можно изменять
|
||
|
||
```python
|
||
SYMBOLS = (
|
||
"BTC/USD_LEVERAGE",
|
||
)
|
||
```
|
||
|
||
для исследования нескольких инструментов.
|
||
|
||
Например
|
||
|
||
```python
|
||
SYMBOLS = (
|
||
"BTC/USD_LEVERAGE",
|
||
"ETH/USD_LEVERAGE",
|
||
)
|
||
```
|
||
|
||
---
|
||
|
||
Можно изменять интервалы
|
||
|
||
```python
|
||
INTERVALS = (
|
||
"1m",
|
||
)
|
||
```
|
||
|
||
например
|
||
|
||
```python
|
||
INTERVALS = (
|
||
"1m",
|
||
"5m",
|
||
)
|
||
```
|
||
|
||
---
|
||
|
||
Можно выбирать тип свечей
|
||
|
||
```python
|
||
CANDLE_TYPE = "classic"
|
||
```
|
||
|
||
или
|
||
|
||
```python
|
||
CANDLE_TYPE = "heikin-ashi"
|
||
```
|
||
|
||
---
|
||
|
||
Также можно изменять
|
||
|
||
```python
|
||
MAX_MESSAGES
|
||
```
|
||
|
||
и
|
||
|
||
```python
|
||
TOTAL_TIMEOUT_SECONDS
|
||
```
|
||
|
||
для длительного наблюдения.
|
||
|
||
---
|
||
|
||
# Что выводит скрипт
|
||
|
||
После запуска отображаются
|
||
|
||
- URL подключения;
|
||
- список инструментов;
|
||
- интервалы;
|
||
- тип свечей;
|
||
- параметры исследования.
|
||
|
||
Затем выводится отправляемый JSON подписки.
|
||
|
||
После подключения отображается ACK.
|
||
|
||
Например
|
||
|
||
```json
|
||
{
|
||
"subscriptions": {
|
||
"BTC/USD_LEVERAGE:1m": "PROCESSED"
|
||
}
|
||
}
|
||
```
|
||
|
||
После этого выводятся все события
|
||
|
||
```
|
||
ohlc.event
|
||
```
|
||
|
||
с указанием
|
||
|
||
- номера сообщения;
|
||
- времени от начала подключения;
|
||
- полного JSON.
|
||
|
||
---
|
||
|
||
# Проверка нескольких интервалов
|
||
|
||
При использовании
|
||
|
||
```python
|
||
INTERVALS = (
|
||
"1m",
|
||
"5m",
|
||
)
|
||
```
|
||
|
||
ожидается ACK
|
||
|
||
```json
|
||
{
|
||
"subscriptions": {
|
||
"BTC/USD_LEVERAGE:1m": "PROCESSED",
|
||
"BTC/USD_LEVERAGE:5m": "PROCESSED"
|
||
}
|
||
}
|
||
```
|
||
|
||
и последующее получение событий
|
||
|
||
```text
|
||
interval = 1m
|
||
```
|
||
|
||
и
|
||
|
||
```text
|
||
interval = 5m
|
||
```
|
||
|
||
в одном WebSocket-соединении.
|
||
|
||
---
|
||
|
||
# Проверка Heikin-Ashi
|
||
|
||
Для исследования синтетических свечей достаточно изменить
|
||
|
||
```python
|
||
CANDLE_TYPE = "heikin-ashi"
|
||
```
|
||
|
||
После этого ожидаются события
|
||
|
||
```json
|
||
{
|
||
"type":"heikin-ashi"
|
||
}
|
||
```
|
||
|
||
Контракт полностью совпадает
|
||
с классическими свечами,
|
||
однако значения OHLC рассчитываются
|
||
по алгоритму Heikin-Ashi.
|
||
|
||
---
|
||
|
||
# Использование в дальнейшем
|
||
|
||
Скрипт рекомендуется сохранять
|
||
в репозитории проекта.
|
||
|
||
Он может использоваться
|
||
|
||
- после изменений API Dzengi;
|
||
- после обновления WebSocket;
|
||
- при регрессионном тестировании;
|
||
- при диагностике Production;
|
||
- при разработке новых адаптеров;
|
||
- при интеграции новых таймфреймов.
|
||
|
||
Наличие отдельного диагностического инструмента
|
||
значительно упрощает проверку реального контракта биржи
|
||
без запуска всего приложения Dzentra.
|
||
|
||
---
|
||
|
||
# Итог Build 058
|
||
|
||
Build 058 полностью подтвердил
|
||
контракт WebSocket OHLCMarketData.subscribe
|
||
на реальном Production API Dzengi.
|
||
|
||
Полученные результаты являются основанием
|
||
для перехода к следующему этапу проекта —
|
||
|
||
```
|
||
Build 059
|
||
|
||
Интеграция WebSocket OHLC
|
||
в канонический Candles Feed.
|
||
``` |