tickstreamdocs

DOCS

Level 2 depth

Subscribe to the full order book with order-flow fields.

requiresRealtime + L2 or above

The book channel streams the full Level 2 order book — every price level with aggregated size on both sides — plus derived order-flow fields. It's included on the packages that include the book.

Subscribe to the book

Every frame carries the whole ladder the exchange gives us — on ES and NQ up to 400 price levels per side, contiguous and with no padding. There is no depth parameter; slice the arrays yourself if you only want the top n.

from tickstream import Tickstream

ts = Tickstream("sk_live_…")
for book in ts.stream("ES", channel="book"):
    price, size = book["bids"][0]
    print(price, size, book["imbalance"])
import { Tickstream } from "@tickstream/client";

const ts = new Tickstream("sk_live_…");
for await (const book of ts.stream("ES", { channel: "book" })) {
  const [price, size] = book.bids[0];
  console.log(price, size, book.imbalance);
}
{ "op": "subscribe", "channel": "book", "symbols": ["ES"] }

The book message

{
  "type": "book",
  "symbol": "ES",
  "bids": [[5283.00, 42], [5282.75, 88]],
  "asks": [[5283.25, 37], [5283.50, 61]],
  "imbalance": 0.18,
  "ts": 1749556800
}
FieldTypeDescription
bids[price, size][]Bid levels, best first, descending price.
asks[price, size][]Ask levels, best first, ascending price.
imbalancenumberTop-of-book order-flow imbalance in [-1, 1] (positive = bid-heavy).
tsintegerExchange timestamp in Unix seconds.

Snapshots & updates

Every message is a full snapshot of the ladder (not a delta), so you never have to reconstruct the book yourself — just read the latest frame. Frames are coalesced per symbol: you receive the latest state at most ~7 times per second, not every intermediate change.

need individual orders?

These frames are aggregated — 42 contracts at a price, not the seven orders that make it up. For per-order depth with exchange order ids and queue priority, see L3 / market-by-order.

plan

Subscribing to book without L2 returns an error frame, {"type":"error","error":{"code":"plan_required",…}}, and the socket stays open for your other channels. See pricing or auth errors.