Orderbook Diff. Depth Stream

The OrderbookUpdate event available in the globalUpdates room (see WebSocket Rooms & Events) is a stream of state diffs at a 100ms interval (if existing). The payload contains the following data:

  symbol: string, // market symbol
  asks: string[][], // index 0 is price, index 1 is quantity at price bin
  bids: string[][], // index 0 is price, index 1 is quantity at price bin
  bestBidPrice: string, // the highest bid price on the orderbook
  bestBidQty: string, // the highest bid quantity on the orderbook
  bestAskPrice: string, // the lowest ask price on orderbook at the moment
  bestAskQty: string, // the lowest ask quantity on orderbook at the moment
  midPrice: string, // mid market price ((highest bid + lowest ask) / 2)
  lastUpdatedAt: number, // timestamp at which last change in orderbook state took place
  responseSentAt: number, // the time at which orderbook server sent the response
  orderbookUpdateId: number, // a count indicating the number of changes in ob state
  firstUpdateId: number, // first orderbook update ID aggregated in this ob state
  lastUpdateId: number, // last orderbook update ID aggregated in this ob state
  oraclePrice: string, // the oracle price 
  oraclePriceLastUpdateAt: string, // timestamp of the last time the oracle price was updated

How to manage a local orderbook:

  1. Open a stream to listen to the orderbook socket events, see guide here.
  2. Start by listening to the orderbook update events from this socket (note as we'll see in step 4, it's important to listen to these events first before taking a snapshot from the API).
  3. Get a depth snapshot from the GET /orderbook route
  4. Drop any event where lastUpdateId from sockets <= orderbookUpdateId in the snapshot.
  5. The first processed event should have lastUpdateId from sockets > orderbookUpdateId from the snapshot.
  6. Note that you must ensure your apply the very first orderbookUpdate after the orderbookUpdateId received from the snapshot (if you fail to do so, you risk missing updates yielding an inconsistent state). This is why it's recommended to open the socket connection first in step 1 before fetching the snapshot.
  7. While listening to the streams, each new event's firstUpdateId should be equal to the previous event's lastUpdateId + 1.
  8. OrderbookUpdateId will not be sequential since multiple updates are aggregated before being sent every n ms. It will however always be an increasing number.
  9. We send updates of only price bins whose data is updated (Diff Depth Streams) - i.e if you see a row in the list, the quantity at the price bin has been added or updated. If the quantity at a price bin is 0 , remove that price bin.
  10. The diff depth streams do not account for any limit. You may choose to snapshot only n levels (limit=n), but the diff depth stream will inform you of price updates beyond n as well. This can lead to inconsistency around or above the nth price bin as you may receive an update of the n + 10 price bin, resulting in you adding it to the local book but missing the bins between n and n + 10. Setting n to a sufficiently high limit will absolve this issue since the inconsistency will happen at an extreme that will be insignificant, can be ignored or reset via a snapshot at any time.