Live streaming
/v2/stream is a WebSocket endpoint for the trading day under way. It carries
new rows and live bars, with history-to-live handoff.
wss://data.cyberun.cloud/v2/stream
Sec-WebSocket-Protocol: veinmesh.v2
Authorization: Bearer vmk_...
The key needs the live permission, the book_snapshot kind and a book depth.
See API keys for permissions.
Subscribe
Send a JSON message:
{"op": "subscribe", "id": "rb", "symbols": ["SHFE.rb2701"], "dataset": "book.snapshot"}
idis yours; it identifies the subscription on this connection.symbolsare public symbols orinstrument_ids.datasetisbook.snapshot.- Add
barsto receive bars instead of rows; its keys are the same as/v2/bars(type,interval,anchor,adjust,transform). - Add
fromfor history-to-live handoff: the lastresume_token, or an RFC 3339 instant on the current day. fieldslimits row fields; the common fields are always sent.numbersisstring(default) orfloat.
The server answers:
{"type": "subscribed", "id": "rb", "catalog_version": "..."}
Send {"op":"unsubscribe","id":"rb"} to stop one subscription, or
{"op":"ping"} to check that the connection is alive.
A subscription belongs to one market. Its trading day, zone and calendar are that market's. If you need symbols from two markets, open two subscriptions.
Messages
Rows. Every new row arrives with the same shape as /v2/data:
{"type": "data", "id": "rb", "rows": [{"ts": "...", "last": "3061", "...": "..."}],
"resume_token": "..."}
With from, the rows you missed are sent first, then live rows.
Bars. With bars, the server sends every bar of the day so far, then the
current bar on each change with complete: false, and once more with
complete: true when it closes. A continuous contract follows the contract of
the day; live bars are not back-adjusted. The contract field says which
contract the bar used.
Heartbeat. {"type":"heartbeat","ts":"..."} arrives periodically.
Error. {"type":"error","id":"rb","problem":{...}}, with the same problem
shape as HTTP. A slow client whose bounded queue overflows receives
resync_required and the connection closes; rows are never dropped silently.
Resume and reconnect
Each row or bar message carries a resume_token. After a disconnect, subscribe
again with "from": "<resume_token>"; the server sends what you missed, then
live messages, without duplicates.
- A token is valid for a limited time; older tokens answer
version_unavailable(410); use an RFC 3339 instant instead. - Reconnect with the last token you processed, not the last one you received, so your processing stays at-least-once.
- If a key is revoked, the connection receives an error and closes.
Limits
One connection holds a limited number of subscriptions and symbols; exceeding
either answers 429 resource_exhausted. The numbers are in
Limits.
Python
for message in client.stream("SHFE.rb2701"):
for row in message.rows:
print(row["ts"], row["last"])
client.stream(..., bars={"interval": 60}) yields bars. The SDK reconnects
after a disconnect and continues from the last row it received. It needs the
websockets extra. See Python SDK.