DigitalRuby / ExchangeSharp

ExchangeSharp is a powerful, fast and easy to use .NET/C# API for interfacing with many crypto currency exchanges. REST and web sockets are supported.
https://www.digitalruby.com
MIT License
741 stars 374 forks source link

OrderBook Websocket: wrong break condition ? #713

Closed chabar closed 2 years ago

chabar commented 2 years ago

Hi all,

First things: thumbs up for this library !

I'm trying to listen to OKEx Order book market data through websocket api.

Since "Moving to OKEx V5 WebSocket API (#685)", I noticed that I have wrong order book after a period of time (best bid > best ask).

It's easily reproductible by launching : exchange-sharp.exe ws-orderbook -e OKEx -s BTC-USD-SWAP After a while bid and ask are inverted and can remain this way for a long time.

I strongly suspect ParseOrderBookFromJTokenArrays method:

                if (book.Asks.Count == maxCount)
                {
                    break;
                }

By using the default setting maxCount = 20, there is an inconsistency between the request which is 'books-l2-tbt' and maxCount. From https://www.okex.com/docs-v5/en/#websocket-api-public-channel-price-limit-channel: "books-l2-tbt: 400 depth levels will be pushed in the initial full snapshot. Incremental data will be pushed every 10 ms when there is change in order book."

The break condition hides updates with 0 quantity that should remove levels. Those levels remain in the order book and will later create false bid or ask on top of the book depending on the market direction.

An easy fix/workaround is to use a much higher maxCount for this market but I'm wondering why this break condition exists in the first place.

Though very unlikely, nothing prevents the exchange to replace all price levels in one update. You would received all previous prices with 0 quantity and all new prices, that's order book depth x 2.

I check the updates received from OKEx over a period of 15 min. This is the distribution of update count (bid + ask): image

(every occurence above 40 can create a issue in case maxCount is 40)

I would propose to remove the condition at parsing level. I don't know all the use cases of the library so I wondering what the community think about this.

Regards,

Charles

BZ-CO commented 2 years ago

Hi.

I also think that trimming should be done at GetFullOrderBookWebSocketAsync rather than how it's now on the incoming data. Order book store is in GetFullOrderBookWebSocketAsync, so it should be responsible for the max count too.

I've made a sketch and will provide PR tomorrow.

Would be happy to hear what other thinks as well.

jjxtra commented 2 years ago

@BZ-CO Good plan

jjxtra commented 2 years ago

Resolved https://github.com/jjxtra/ExchangeSharp/pull/714