Orderbooks is one of the most important things for quantitive trading. It gives you not only the best bid/ask prices and their corresponding quantities but also the depth of the whole market, i.e. the quantity that people want to buy or sell at every price level. Traders watch orderbooks closely to determine how to place orders. Numerous quantitative models were developed to track and predict the dynamics of orderbooks to help predict market price and make profit. In this article, we demonstrate how to obtain orderbooks of our cryptocurrency trading pairs through APIs and maintain them efficiently.

The simplest way to obtain the orderbook of a trading pair is to use our REST API. For example, through the following code, we can get the orderbook of BTC/USDT (inst_id  490589, if you do not know the inst_id of a pair, you can check https://api.coinut.com/spot).

The above method is simple and convenient but not efficient because whenever we need to update the orderbook, we have to obtain the entire orderbook, in which most entries are actually unchanged, wasting network bandwidth and CPU cycles. If your trading strategy is sensitive to latencies, e.g. the arbitrage strategies introduced before: triangular arbitrage and four-point arbitrage, this inefficient way may break your system.

A much more efficient way is to use our WebSocket API. The basic idea is to get a snapshot of the entire orderbook first, and then apply only the incremental updates of changed entries streamed from our server to the client. Because the updated entries are much less than the entire orderbook, the amount of data needs to be streamed will be minimised, making the updating process much more efficient.

The following gives you the code for obtaining the snapshot and incremental updates.

It first gives you the entire orderbook (reply is inst_order_book), including the market depth of the buy side and sell side. And then, a stream of updates will be received, which describes the continuous changes of the orderbook. Each update contains the price level (price), quantity at the price level (qty), the number of orders at the level (count), and whether the update is from the buy side or sell side (side).

{
  "nonce": 704114,
  "sell": [
    {
      "count": 2,
      "price": "4138.39",
      "qty": "0.31700000"
    },
    {
      "count": 3,
      "price": "4139.84",
      "qty": "0.48700000"
    },
    ...
  ],
  "buy": [
    {
      "count": 5,
      "price": "4074.11",
      "qty": "0.01212000"
    },
    {
      "count": 1,
      "price": "4061.77",
      "qty": "0.00700000"
    },
    {
      "count": 1,
      "price": "4054.15",
      "qty": "0.00439606"
    },
    ...
  ],
  "total_buy": "11315.21872610",
  "inst_id": 490589,
  "status": [
    "OK"
  ],
  "reply": "inst_order_book",
  "total_sell": "115.27628133",
  "trans_id": 10557032449
}
{
  "count": 5,
  "total_buy": "11315.07625448",
  "price": "4074.11",
  "qty": "0.01208503",
  "reply": "inst_order_book_update",
  "inst_id": 490589,
  "prev_trans_id": 10557032449,
  "trans_id": 10557032866,
  "side": "BUY"
}
{
  "count": 0,
  "total_buy": "11304.40033728",
  "price": "1549.48",
  "qty": "0.00000000",
  "reply": "inst_order_book_update",
  "inst_id": 490589,
  "prev_trans_id": 10557032866,
  "trans_id": 10557032904,
  "side": "BUY"
}

Based on the data above, we use Python's dict to represent the orderbook: orderbook = {'buy': {}, 'sell': {}}, which contains the the buy side and sell side, which are also represented as dicts respectively, where the key is the price, and the value the quantity. The following code shows how to do it, and you can directly run it or modify it.

If you need more information on our API, please check https://github.com/coinut/api/wiki