Coinex WebSocket market depth channel sometimes does not send message to remove price level

1.2k Views Asked by At

I'm writing a Node.js application which attempts to re-create the Coinex orderbook for ETH-USDT using their Websocket. My application subscribes to the market depth channel and keeps an ongoing, updated local copy of the orderbook stored in memory.

I have a working implementation, but I'm noticing that my local copy of the orderbook always seems to eventually fall out of sync with the exchange. I've run the application for up to 2 hours without seeing a single issue, but eventually and invariably, I end up with a "stale" price level in my local copy that was removed from the exchange at some point.

I'm fairly certain that the WS message to remove the level was never sent because I've run multiple tests where I log every WS message sent during the test period. I can probably rule out the obvious issue of there being some bug with my system.

Is this just an issue on the Coinex side? Is there some other way I need to be expiring messages? How can I best detect and handle this issue assuming it's a problem with the Coinex Websocket?

3

There are 3 best solutions below

0
On BEST ANSWER

Are you making use of the 'complete result' flag in Coinex's depth.update response (i.e. - params[0])? The server occasionally sends a complete copy of the order book (up to the count limit in your request), setting this flag to true. Completely resetting your local order book state when this flag is set should keep you in sync.

Another thing it could be is how you're handling depth updates with 0 volume for a certain price (i.e. - setting the value at that price to 0 vs removing the key from your map).

Here's a Java example of how I'm handling updates (the maps' sizes stay consistent with the count limit initially sent in the request):

@AllArgsConstructor
@Data
public class LimitOrderBook {
    private double last;
    private final SortedMap<Double, Double> asks;
    private final SortedMap<Double, Double> bids;
    private int time;

    public void handleUpdate(final LimitOrderBookUpdate update) {
        if (update.isFullUpdate()) {
            asks.clear();
            bids.clear();
        }
        last = update.getLast();
        update.getAskUpdates().forEach(p -> updateMap(asks, p));
        update.getBidUpdates().forEach(p -> updateMap(bids, p));
        time = update.getTime();
    }

    private void updateMap(final SortedMap<Double, Double> map, final Pair<Double, Double> pair) {
        if (pair.getValue() == 0) {
            map.remove(pair.getKey());
        } else {
            map.put(pair.getKey(), pair.getValue());
        }
    }
}
1
On

I had the same problem with other exchanges.

Unfortunately we can't 100% trust websocket APIs due to several reason (often bound to the exchange).

The best solution I found (and I'm still using) is to keep track of changes through websocket APIs to keep an almost aligned book on my server, plus (under a setInterval) I periodically download the full book to resync my book.

Hope this helps.

1
On

I looked up for a few resources which could be useful to tackle up your problem.
But first thing first, executing WebSocket each time isn't a trustworthy solution. There are some other better approaches to do the same task. As you've asked for suggestions to dislodge messages, I would encourage you to lookup the demo application and implementation in coinex-exchange-api here.

IMO, using setInterval() will just be a makeshift to this solution. You need a better directive to do that.

CryptoCurrency eXchange WebSockets is another but better approach in invoking real-time data. It is a JavaScript library for connecting to realtime public APIs on all cryptocurrency exchanges. Install and use it using below command:

npm install ccxws

For more detail, visit: blocktap.io.