4

Below is a python script that subscribes order book information via Biance's Websocket API (Documentation Here).

In both requests(btcusdt@depth and btcusdt@depth@100ms), each json payload is streamed with a varying depth.
Please shed light on what might be the cause of this? Am I doing something wrong? Or might they have certain criteria as to how many depths of an order book to fetch?

import json
import websocket

socket='wss://stream.binance.com:9443/ws'

def on_open(self):
    print("opened")
    subscribe_message = {
        "method": "SUBSCRIBE",
        "params":
        [
         "btcusdt@depth@100ms"
         ],
        "id": 1
        }

    ws.send(json.dumps(subscribe_message))

def on_message(self, message):
    print("received a message")

    ###### depths of bid/ask ######
    d = json.loads(message)
    for k, v in d.items():
        if k == "b":
            print(f"bid depth : {len(v)}")
        if k == "a":
            print(f"ask depth : {len(v)}")

def on_close(self):
    print("closed connection")

ws = websocket.WebSocketApp(socket,
                            on_open=on_open,
                            on_message=on_message,
                            on_close=on_close)

ws.run_forever()

btcusdt@depth@100ms

opened
received a message
received a message
bid depth : 3
ask depth : 12
received a message
bid depth : 14
ask depth : 12
received a message
bid depth : 17
ask depth : 24
received a message
bid depth : 14
ask depth : 16
received a message
bid depth : 3
ask depth : 5
received a message
bid depth : 16
ask depth : 6
.
.
.

btcusdt@depth

opened
received a message
received a message
bid depth : 135
ask depth : 127
received a message
bid depth : 125
ask depth : 135
received a message
bid depth : 95
ask depth : 85
received a message
bid depth : 68
ask depth : 88
received a message
bid depth : 119
ask depth : 145
received a message
bid depth : 127
ask depth : 145
.
.
.
koyamashinji
  • 535
  • 1
  • 6
  • 19

2 Answers2

3

Your code reads the length of the diff for the last 100 ms or 1000 ms (the default value when you don't specify the timeframe). I.e. the remote API sends just the diff, not the full list.

The varying length of the diff is expected.


Example:

An order book has 2 bids and 2 asks:

  • ask price 1.02, amount 10
  • ask price 1.01, amount 10
  • bid price 0.99, amount 10
  • bid price 0.98, amount 10

During the timeframe, one more bid is added and one ask is updated. So the message returns:

"b": [
    [ // added new bid
        0.97,
        10
    ]
],
"a": [
    [ // updated existing ask
        1.01,
        20
    ]
]

And your code reads this message as

bid depth: 1
ask depth: 1

During another timeframe, two bids are updated

"b": [
    [ // updated existing bid
        0.98,
        20
    ],
    [ // updated existing bid
        0.99,
        20
    ]
],
"a": [] // no changes

So your code reads this as

bid depth: 2
ask depth: 0
Petr Hejda
  • 40,554
  • 8
  • 72
  • 100
  • Is it expected for the diff length grows continuously? For example if I leave it running for a day, that diff length goes well over 10k records, which obviously take ages to process... – Byron Coetsee Nov 14 '22 at 09:45
  • @ByronCoetsee The returned data only contains diff for the last interval (100 or 1000 ms). It's not a diff between "start of your subscription to the channel" and "now", so it should not grow into 10k records. It seems like you're merging all the results together. So the first response return 2 items, second response returns 3 items, and you're probably merging them to 5 items. – Petr Hejda Nov 14 '22 at 11:01
3

"btcusdt@depth@100ms" only provides the change in the order book, not the order book itself (as mentioned by the other answer)

Use: "btcusdt@depth10@100ms" if you want to stream the book 10 best bids and 10 best asks.

serge
  • 313
  • 4
  • 14