Стриминг
Сделки, цены, стакан, счёт, раскладка и настройки в реальном времени через один WebSocket.
Стрим — это одно соединение WebSocket, которое несёт все живые обновления.
Чтобы его открыть, нужно право market:read.
Подключиться и читать события
import asyncio
from spectre_terminal import Event, Gap, SubscriptionError, Terminal
async def main():
terminal = Terminal.discover()
async with terminal.stream() as stream:
trades = await stream.subscribe("trades", "binance:futures:BTCUSDT")
async for frame in stream:
match frame:
case Event(sub=trades.sub):
for trade in frame.data:
print(trade.side, trade.price, trade.qty)
case Gap():
print("lost trades", frame.from_seq, frame.to_seq)
case SubscriptionError():
print("subscription removed", frame.code)
asyncio.run(main())Цикл отдаёт события, пропуски и ошибки подписок. Событие несёт sub, seq,
ts и data. sub — идентификатор подписки, а форма data зависит от
топика. Все кадры и поля есть в справочнике стрима.
Подписаться на топик
trades = await stream.subscribe("trades", "binance:futures:BTCUSDT")
book = await stream.subscribe("book.top", "binance:futures:BTCUSDT", depth=5, interval_ms=200)
fills = await stream.subscribe("account.fills", connection_id=12)| Топик | Что несёт событие | Что нужно |
|---|---|---|
trades | Новые сделки, по порядку | Инструмент, market:read |
ticker | Суточный тикер | Инструмент, market:read |
mark_price | Цена маркировки | Инструмент, market:read |
book.top | Верх стакана | Инструмент, market:read |
clusters | Бакет кластеров объёма, который изменился | Инструмент, market:read |
account.orders | Заявки и триггерные заявки одного инструмента | Идентификатор подключения, account:read |
account.positions | Позиция по одному инструменту | Идентификатор подключения, account:read |
account.balances | Баланс одной валюты | Идентификатор подключения, account:read |
account.fills | Одно исполнение | Идентификатор подключения, account:read |
workspace | Вся раскладка окон | workspace:read |
settings | Одна записанная строка настроек | settings:read |
Отклонённый запрос выбрасывает StreamRequestError с кодом из раздела
Ошибки. Данные Московской биржи (MOEX) не отдаются.
book.top принимает два необязательных параметра. depth — число уровней с
каждой стороны: от 1 до 200, по умолчанию 50. interval_ms — наименьшее
время между двумя кадрами: от 50, по умолчанию 100. Значения вне диапазона
отклоняются с invalid_request.
workspace присылает текущую раскладку первым кадром. Топики счёта и
settings присылают только изменения, поэтому сначала прочитайте текущее
состояние. См. Счёт и
Настройки.
Обработать пропуск
Когда ваша программа читает медленнее, чем приходят данные, терминал отбрасывает кадры, которые не помещаются.
| Топик | Признак потери | Что делать |
|---|---|---|
trades | Кадр пропуска перед следующим событием | Прочитать сделки ещё раз с since_ts |
account.fills | seq пропускает номер | Прочитать исполнения ещё раз с since_ts |
settings | seq пропускает номер | Прочитать настройки ещё раз |
| Все остальные | Нет | Ничего. Следующий кадр — самое новое состояние, а пропущенные номера seq — это нормально |
Передайте время последней сделки или последнего исполнения, которые у вас
есть. Аргумент называется since_ts в Python и sinceTs в TypeScript.
Обработать снятую подписку
Терминал снимает подписку, когда биржа её отклоняет или когда её
подключение выключают. Тогда цикл отдаёт ошибку подписки с sub, code и
message. Подпишитесь снова, когда причина устранена.
Переподключиться
import asyncio
from spectre_terminal import StreamClosed, Terminal
async def main():
terminal = Terminal.discover()
while True:
try:
async with terminal.stream() as stream:
await stream.subscribe("trades", "binance:futures:BTCUSDT")
async for frame in stream:
print(frame)
except StreamClosed as closed:
print("stream closed", closed.code)
await asyncio.sleep(1)
asyncio.run(main())Когда терминал закрывает стрим, цикл выбрасывает StreamClosed в Python и
StreamClosedError в TypeScript. Подписки не сохраняются, поэтому после
переподключения подпишитесь заново.
Код закрытия говорит, почему стрим закрыт, см. Коды закрытия стрима.
Отписаться и закрыть
await stream.unsubscribe(trades)
await stream.close()unsubscribe сразу снимает одну подписку. Закрытие стрима снимает все
подписки и завершает цикл без ошибки.
Лимиты
Один токен может держать 8 соединений стрима, а одно соединение — 100 подписок. API может открыть 50 инструментов, которые не открыты в окне терминала, и не больше 5 новых в секунду.
Сверх лимита subscribe завершается ошибкой rate_limited. Немного
подождите и попробуйте снова. См. Лимиты.