Перейти до вмісту

WebSocket-стрім

Одне з’єднання для ринкових даних, рахунку, розкладки вікон і налаштувань.

Адреса: ws://127.0.0.1:48180/v1/stream · Файл AsyncAPI

З’єднання

  • Адреса: ws://127.0.0.1:48180/v1/stream.
  • Токен передається в заголовку Authorization: Bearer <token> рукостискання. Рукостискання потребує права market:read. Воно відхиляється за тими самими правилами, що й HTTP-запит, з 401 або 403.
  • Сервер надсилає WebSocket ping кожні 20 с. Якщо pong не приходить 50 с, сервер закриває з’єднання.
  • Коли клієнт закриває з’єднання, сервер відповідає кадром закриття з кодом клієнта.
  • Закриття сокета знімає всі підписки з’єднання. Явний unsubscribe знімає підписку одразу.
  • Пара без підписників звільняється на біржі через 30 с.

Коди закриття

КодЗначення
1001API вимкнено або токен перевипущено
4008клієнт надто повільний і не встигав довше ніж 5 с
4029ліміт з’єднань стріму на токен

Ліміти

GET /v1/meta повертає ліміти. Відмова — це кадр error з rate_limited у відповідь на запит або закриття з кодом 4029.

ЛімітЗначення
з’єднань стріму на токен8
підписок на з’єднання100
інструментів, відкритих лише для API50, не рахуючи відкритих у вікні
нових підписок на біржах на секунду5

Повільні клієнти

Клієнт, який не читає, не сповільнює ні термінал, ні інших клієнтів. Кадри, які він не забрав вчасно, відкидаються. Для trades кадр gap називає втрачені номери. Для інших топіків наступний кадр просто новіший.

Порядкові номери

seq нумерує події підписки. Для trades він зростає на одиницю. Для топіків, де надсилається лише останнє значення, пропуски в номерах — це нормально.

Запити клієнта

Що програма надсилає терміналу.

subscribe

Запит на топік.

Що потрібно топіку, залежить від його сімейства:

  • Ринкові топіки — це trades, ticker, mark_price, book.top і clusters. instrument обов’язковий. connection_id вибирається за загальним правилом. Право — market:read.
  • Топіки рахунку — це account.*. connection_id обов’язковий. instrument не використовується. Право — account:read.
  • workspace і settings не приймають ні того, ні іншого. Права — workspace:read і settings:read.

Лише book.top використовує params. Інші топіки їх ігнорують.

ПолеТипОпис
typeобов’язкове"subscribe"
request_idstringНеобов’язковий. Повертається у відповіді без змін.
topicобов’язковеTopic
instrumentstringАдреса інструмента, exchange:market:symbol. Обов’язкова для ринкових топіків.
connection_idintegerОбов’язковий для топіків рахунку. Необов’язковий для ринкових топіків.
paramsobjectПараметри book.top.
params.depthintegerРівнів з кожного боку. Range: 1–200. За замовчуванням: 50.
params.interval_msintegerНайменший час між двома кадрами, мілісекунди. Range: ≥ 50. За замовчуванням: 100.
Trades of a pair
{
  "type": "subscribe",
  "request_id": "r1",
  "topic": "trades",
  "instrument": "binance:futures:BTCUSDT",
  "connection_id": 12
}
Top of the book, 10 levels every 250 ms
{
  "type": "subscribe",
  "request_id": "r2",
  "topic": "book.top",
  "instrument": "binance:futures:BTCUSDT",
  "params": {
    "depth": 10,
    "interval_ms": 250
  }
}
Fills of a connection
{
  "type": "subscribe",
  "request_id": "r3",
  "topic": "account.fills",
  "connection_id": 12
}
The layout of the windows
{
  "type": "subscribe",
  "request_id": "r4",
  "topic": "workspace"
}

unsubscribe

Зняти підписку.

Приймає лише sub, повернутий у subscribed.

ПолеТипОпис
typeобов’язкове"unsubscribe"
request_idstring
subобов’язковеstringІдентифікатор із subscribed.
Приклад
{
  "type": "unsubscribe",
  "request_id": "r5",
  "sub": "7:trades"
}

Кадри сервера

Що термінал відповідає й надсилає сам, окрім подій.

subscribed

Підписку встановлено.

sub ідентифікує підписку в кожному наступному кадрі. Це "{stream}:{topic}" для ринкових топіків, "{connection}:account.<topic>" для топіків рахунку і "workspace" або "settings" для двох інших. Кожен клієнт, підписаний на ту саму пару й топік, отримує той самий sub. connection_id присутній для ринкових топіків і топіків рахунку. Для workspace і settings його немає.

ПолеТипОпис
typeобов’язкове"subscribed"
request_idstring
subобов’язковеstring
connection_idintegerВибране підключення. Відсутнє для workspace і settings.
Приклад
{
  "type": "subscribed",
  "request_id": "r1",
  "sub": "7:trades",
  "connection_id": 12
}

unsubscribed

Підписку знято.

ПолеТипОпис
typeобов’язкове"unsubscribed"
request_idstring
subобов’язковеstring
Приклад
{
  "type": "unsubscribed",
  "request_id": "r5",
  "sub": "7:trades"
}

error

Запит відхилено або підписку знято сервером.

З request_id кадр відповідає на запит клієнта. З sub і без request_id — сервер зняв підписку. Коди — це коди HTTP-операцій.

ПолеТипОпис
typeобов’язкове"error"
request_idstringПрисутній, коли кадр відповідає на запит.
substringПрисутній, коли кадр стосується підписки.
codeобов’язковеErrorCode
messageобов’язковеstringТекст для людини.
A refused request
{
  "type": "error",
  "request_id": "r1",
  "code": "not_found",
  "message": "no connection for the instrument"
}
A subscription removed by the server
{
  "type": "error",
  "sub": "7:trades",
  "code": "unavailable",
  "message": "the exchange refused the subscription"
}

gap

Угоди, які втратив клієнт.

Надсилається лише для trades, перед першим кадром після втрати. Клієнт не читав, і події від from_seq до to_seq втрачено. Прочитайте їх ще раз через GET /v1/market/trades із since_ts.

ПолеТипОпис
typeобов’язкове"gap"
subобов’язковеstring
from_seqобов’язковеinteger
to_seqобов’язковеinteger
reasonобов’язковеstringslow_consumer.
Приклад
{
  "type": "gap",
  "sub": "7:trades",
  "from_seq": 42,
  "to_seq": 57,
  "reason": "slow_consumer"
}

Топіки

Усі події мають один конверт; data залежить від топіка.

ПолеТипОпис
typeобов’язкове"event"
subобов’язковеstringПідписка, до якої належить подія.
seqобов’язковеintegerНомер події в підписці.
tsобов’язковеintegerМомент, коли зібрано кадр, мілісекунди UTC.
dataобов’язковеanyДані події. Їхня форма залежить від топіка.
ТопікПотребуєПравоДоставка
tradesinstrumentmarket:readза порядком, про пропуски повідомляється
tickerinstrumentmarket:readлише останнє значення
mark_priceinstrumentmarket:readлише останнє значення
book.topinstrumentmarket:readлише останнє значення
clustersinstrumentmarket:readлише останнє значення
account.ordersconnection_idaccount:readлише останнє значення
account.positionsconnection_idaccount:readлише останнє значення
account.balancesconnection_idaccount:readлише останнє значення
account.fillsconnection_idaccount:readкадр на кожну подію
workspaceнічогоworkspace:readлише останнє значення
settingsнічогоsettings:readкадр на кожну подію

trades

Угоди пари, по порядку.

data — це масив угод, як у GET /v1/market/trades. Угоди надходять по порядку. Якщо клієнт відстає, кадр gap називає втрачене.

Дані: Trade[]

Приклад
{
  "type": "event",
  "sub": "7:trades",
  "seq": 41,
  "ts": 1730294400130,
  "data": [
    {
      "id": null,
      "price": "67000.1",
      "qty": "0.012",
      "side": "buy",
      "ts": 1730294400125,
      "exchange_ts": 1730294400119
    }
  ]
}

ticker

24-годинний тікер пари.

data — це тікер, як ticker у GET /v1/market/snapshot. Надсилається лише останнє значення.

Дані: Ticker

Приклад
{
  "type": "event",
  "sub": "7:ticker",
  "seq": 12,
  "ts": 1730294400130,
  "data": {
    "price": "67000.1",
    "change_24h_pct": "1.25",
    "volume_24h": "81234.5",
    "high_24h": null,
    "low_24h": null,
    "best_bid": null,
    "best_ask": null,
    "ts": 1730294400120
  }
}

mark_price

Ціна маркування (mark) пари.

Надсилається лише останнє значення.

Дані: MarkPrice

Приклад
{
  "type": "event",
  "sub": "7:mark_price",
  "seq": 5,
  "ts": 1730294400130,
  "data": {
    "mark_price": "67001.0",
    "ts": 1730294400120
  }
}

book.top

Верх стакана пари.

Кожен підписник задає власні depth і interval_ms. Значення поза межами відхиляються з invalid_request. Перший кадр надходить, щойно стакан готовий. Далі надходить не більше одного кадру за interval_ms, з найновішим стаканом. seq — це версія стакана.

Дані: BookTop

Приклад
{
  "type": "event",
  "sub": "7:book.top",
  "seq": 9031,
  "ts": 1730294400130,
  "data": {
    "ts": 1730294400123,
    "depth": 10,
    "bids": [
      [
        "67000.1",
        "1.25"
      ]
    ],
    "asks": [
      [
        "67000.2",
        "0.40"
      ]
    ]
  }
}

clusters

Кластери обсягу інструмента.

data — це один бакет, як елемент data у GET /v1/market/clusters. Кадр надходить для кожного бакета, що змінився, не частіше ніж раз на 16 мс, з його останнім станом. Зміну інтервалу в терміналі видно в interval.

Дані: ClusterBucket

account.orders

Заявки й тригерні заявки одного інструмента після зміни.

Надсилається лише останній стан інструмента. Підписка не звертається до біржі, а події надходять відтоді, як їх надсилає підключення. Кадру зі знімком під час підписки немає. Поточний стан читайте через GET /v1/account/orders.

Дані: InstrumentOrders

account.positions

Позиція одного інструмента після зміни.

Надсилається лише останній стан. Закрита позиція надходить як "position": null. Кадру зі знімком під час підписки немає.

Дані: InstrumentPosition

account.balances

Баланс однієї валюти.

data — це один баланс, як елемент data у GET /v1/account/balances. Надсилається лише останнє значення. Кадру зі знімком під час підписки немає.

Дані: Balance

account.fills

Одне виконання.

Один кадр на виконання. Якщо клієнт відстає, кадр втрачається, а seq показує пропуск. Прочитайте виконання ще раз через GET /v1/account/fills із since_ts.

Дані: Fill

workspace

Уся розкладка вікон.

data — це розкладка, як data у GET /v1/workspace. Перший кадр — це поточна розкладка, надіслана одразу під час підписки. Далі кадр надходить на кожну зміну. Надсилається лише останній стан.

Дані: WorkspaceSnapshot

settings

Один записаний рядок налаштувань.

Один кадр на кожен запис у таблицю налаштувань: з API, із Settings App і з самого вікна. Знімка під час підписки немає. Поточні значення читайте через GET /v1/settings. Якщо клієнт відстає, кадр втрачається, а seq показує пропуск.

Дані: SettingWritten

Приклад
{
  "type": "event",
  "sub": "settings",
  "seq": 3,
  "ts": 1730294400130,
  "data": {
    "scope": "global",
    "scope_id": "default",
    "connection_id": null,
    "category": "multiview",
    "key": "stack_width_px",
    "value": 300
  }
}

Типи даних

Об’єкти, які несуть події. Ті самі об’єкти повертають операції HTTP.

Topic

tradestickermark_pricebook.topclustersaccount.ordersaccount.positionsaccount.balancesaccount.fillsworkspacesettings

ErrorCode

unauthorizedforbiddenforbidden_scopenot_foundinvalid_requestunsupportednot_activenot_tradablerate_limitedunavailable

Стабільний код, частина контракту. Можуть додаватися нові коди.

КодHTTPКоли
unauthorized401токен неправильний або API вимкнено
forbidden403заголовок Origin або чужий Host
forbidden_scope403токен не має права операції
not_found404такої операції чи підключення немає, або для інструмента немає підключення
invalid_request400неправильний параметр: інструмент, інтервал, глибина, чужий connection_id
unsupported501біржа — MOEX, термінал зібрано без ринкових даних, або налаштування не записується через API
not_active409кластери інструмента ще не обчислено, або його плече ще не завантажено
not_tradable409підключення не може торгувати: воно вимкнене, лише для читання або не має облікових даних
rate_limited429перевищено ліміт: з’єднань, підписок, інструментів, нових підписок на секунду, торгових команд, команд робочого простору або записів налаштувань
unavailable503сховище, біржа або вікно не відповіли, термінал зайнятий, або даних ще немає

Trade

ПолеТипОпис
idобов’язковеstring | nullУ v1 завжди null.
priceобов’язковеstring
qtyобов’язковеstring
sideобов’язкове"buy" | "sell"
tsобов’язковеintegerКоли термінал отримав угоду, мілісекунди UTC.
exchange_tsобов’язковеintegerЧас біржі.

Ticker

24-годинний тікер.

ПолеТипОпис
priceобов’язковеstring
change_24h_pctобов’язковеstring | null
volume_24hобов’язковеstring
high_24hобов’язковеstring | null
low_24hобов’язковеstring | null
best_bidобов’язковеstring | null
best_askобов’язковеstring | null
tsобов’язковеinteger

MarkPrice

ПолеТипОпис
mark_priceобов’язковеstring
tsобов’язковеinteger

BookTop

Верх стакана: біди від найкращої ціни вниз, аски від найкращої ціни вгору.

ПолеТипОпис
tsобов’язковеinteger
depthобов’язковеinteger
bidsобов’язковеPriceLevel[]
asksобов’язковеPriceLevel[]

ClusterBucket

ПолеТипОпис
intervalобов’язковеstring
tsобов’язковеintegerПочаток бакета, мілісекунди UTC.
end_tsобов’язковеinteger
volumeобов’язковеstring
buy_volumeобов’язковеstring
sell_volumeобов’язковеstring
tradesобов’язковеinteger
vwapобов’язковеstring | null
min_priceобов’язковеstring | null
max_priceобов’язковеstring | null
completedобов’язковеboolean
last_trade_tsобов’язковеintegerЧас останньої угоди бакета. 0 для бакета з історії, який такого часу не має.
levelsобов’язковеClusterLevel[]Усі цінові рівні бакета, від найнижчої ціни до найвищої.

InstrumentOrders

ПолеТипОпис
instrumentобов’язковеstring
ordersобов’язковеOrder[]
triggersобов’язковеTrigger[]

InstrumentPosition

ПолеТипОпис
instrumentобов’язковеstring
positionобов’язковеPosition | null

Balance

ПолеТипОпис
currencyобов’язковеstring
totalобов’язковеstring
availableобов’язковеstring | null
lockedобов’язковеstring | null
tsобов’язковеinteger

Fill

ПолеТипОпис
trade_idобов’язковеstring
order_idобов’язковеstringІдентифікатор заявки на біржі.
instrumentобов’язковеstring
sideобов’язковеstringbuy або sell.
priceобов’язковеstring
qtyобов’язковеstring
feeобов’язковеstring
fee_currencyобов’язковеstring
position_sideобов’язковеstring | nulllong або short на біржах із режимом хеджування, інакше — null.
tsобов’язковеintegerЧас біржі.

WorkspaceSnapshot

ПолеТипОпис
windowsобов’язковеWindow[]За зростанням id.

SettingWritten

Рядок налаштувань, як його записано, без writable.

ПолеТипОпис
scopeобов’язковеstring
scope_idобов’язковеstring | null
connection_idобов’язковеinteger | null
categoryобов’язковеstring
keyобов’язковеstring
valueобов’язковеanyБудь-яке значення JSON.

PriceLevel

string[]

[price, size], обидва — десяткові рядки.

ClusterLevel

ПолеТипОпис
priceобов’язковеstring
volumeобов’язковеstring
buy_volumeобов’язковеstring
sell_volumeобов’язковеstring
buy_tradesобов’язковеinteger
sell_tradesобов’язковеinteger

Order

ПолеТипОпис
keyобов’язковеstring | nullКлюч заявки в терміналі, t-…. null, поки він невідомий.
exchange_idобов’язковеstring | nullІдентифікатор заявки на біржі. null, поки біржа не прийме заявку.
instrumentобов’язковеstring
sideобов’язкове"buy" | "sell"
typeобов’язкове"limit" | "market"
priceобов’язковеstring
sizeобов’язковеstringУ базовій монеті.
filledобов’язковеstring
remainingобов’язковеstring
notionalобов’язковеstring | nullСума у валюті котирування, яку ввів трейдер. null для заявки зі знімка біржі.
statusобов’язкове"pending" | "open" | "partially_filled"
created_tsобов’язковеinteger | nullnull для заявки зі знімка біржі, яка не має часу.

Trigger

ПолеТипОпис
idобов’язковеstringЧисловий id, за яким тригер скасовують і змінюють.
instrumentобов’язковеstring
typeобов’язковеTriggerKind
trigger_priceобов’язковеstring
ruleобов’язковеTriggerRule
sizeобов’язковеstring | nullУ базовій монеті.
notionalобов’язковеstring | nullУ валюті котирування.
statusобов’язкове"open" | "finished" | "inactive" | "invalid"
order_typeобов’язковеstring | nullТип заявки на біржі, як він надійшов.
client_idобов’язковеstring | nullКлюч, повернутий під час постановки тригера.
created_tsобов’язковеinteger | null

Position

ПолеТипОпис
instrumentобов’язковеstring
sideобов’язкове"long" | "short"
sizeобов’язковеstringУ базовій монеті.
lot_sizeобов’язковеstringБазових одиниць в одному лоті.
entry_priceобов’язковеstring
notionalобов’язковеstringУ валюті котирування.
unrealized_pnlобов’язковеstringЯк рахує термінал.
mark_priceобов’язковеstring | nullНайкращий bid для лонга, найкращий ask для шорта. null до першого тика стакана.

Window

ПолеТипОпис
idобов’язковеinteger
mainобов’язковеbooleanГоловне вікно. Його закриття завершує роботу термінала.
chart_windowобов’язковеbooleanОкреме вікно графіків.
focusedобов’язковеbooleanВікно у фокусі ОС.
geometryобов’язковеobjectПоложення і розмір у логічних пікселях екрана.
geometry.xобов’язковеinteger
geometry.yобов’язковеinteger
geometry.widthобов’язковеinteger
geometry.heightобов’язковеinteger
geometry.maximizedобов’язковеboolean
monitorобов’язковеstring | nullНазва монітора, як її повідомляє ОС.
tabsобов’язковеTab[]

TriggerKind

stop_losstake_profitstop

TriggerRule

price_above_or_equalprice_below_or_equal

Tab

ПолеТипОпис
idобов’язковеintegerНумерується в кожному вікні з одиниці.
nameобов’язковеstring
activeобов’язковеbooleanАктивна рівно одна вкладка вікна.
stacksобов’язковеStack[]
chartsобов’язковеChart[]

Stack

Стакан зі стрічкою угод і кластерами.

ПолеТипОпис
widget_idобов’язковеinteger
instrumentобов’язковеstring | nullnull, поки стек порожній.
connection_idобов’язковеinteger | null
emptyобов’язковеboolean
frozenобов’язковеbooleanСтек заморожено.
positionобов’язковеCell | null

Chart

ПолеТипОпис
widget_idобов’язковеinteger
instrumentобов’язковеstring | null
connection_idобов’язковеinteger | null
intervalобов’язковеstringІнтервал свічок: 1m, 5m, …
owner_widget_idобов’язковеinteger | nullСтек, за яким іде графік. null для самостійного графіка.
positionобов’язковеCell | null

Cell

Комірка сітки вкладки: колонка зліва, рядок згори, комірка в рядку.

ПолеТипОпис
columnобов’язковеinteger
rowобов’язковеinteger
cellобов’язковеinteger

На цій сторінці