bitrich-info/xchange-stream

Kraken Websocket orderbook is inconsistent [Bug!]

Closed this issue · 14 comments

Hello, i was testing the Kraken orderbook websocket and i found that the prices and volume is inconsistent with the real values. I can send you printscreen if you like. Does anyone found that also? I am waiting for the response of the @pchertalev .Thanks

I just found the issues.

  1. There is an issue when the last digit of the price before dot is zero. For example when the price of bitcoin is 8750.0000, the method stripTrailingZeros() of BigDecimal gives as output 875+E3. I have fixed this by deleting the stripTrailingZeros() method.

  2. When the Kraken book subscription sends a message in order to update values in both bid and ask orderbook, the current implementation updates only the one side of the book( the first one, so only ASK). I have fix this issue and i will make a PR shortly.

Thanks @makarid. I'll be happy to merge the PR if one of our other Kraken users can confirm it works.

I just found the issues.

  1. There is an issue when the last digit of the price before dot is zero. For example when the price of bitcoin is 8750.0000, the method stripTrailingZeros() of BigDecimal gives as output 875+E3. I have fixed this by deleting the stripTrailingZeros() method.

It not correct! 8750.0000 with stripTrailingZeros returns 8.75E+3 (not 875+E3)! Where is the bug here? 8750.0000 fully equals 8.75E+3.

I just found the issues.
2. When the Kraken book subscription sends a message in order to update values in both bid and ask orderbook, the current implementation updates only the one side of the book( the first one, so only ASK). I have fix this issue and i will make a PR shortly.

I have long testing WS Kraken Order book in comparison vs rest order book and it works fully correct in asks and bids. There is only one issue I found - Kraken rest order book uses rounding order book volume UP to 3 decimal points but WS order book not - WS order book is more accurate

@makarid Your pool request is not readable - it contains a lot of durty commits from not merged branches. Could you create new pure fork from xchainge-streaming project, commit your changes and create new pool request?

@pchertalev thanks for your response.

About the first issue, maybe it is my bad, but i have made this test and it fails:
BigDecimal price = new BigDecimal(8500).stripTrailingZeros();
System.out.println(price);
assertThat(price).isEqualTo(BigDecimal.valueOf(8500));

But if i drop the stripTrailingZeros() it passes:
BigDecimal price = new BigDecimal(8500);
System.out.println(price);
assertThat(price).isEqualTo(BigDecimal.valueOf(8500));

About the second issue, i was manual testing the KrakenStreamingOrderBook using this code in the debug log mode:

StreamingExchange krakenExchange = StreamingExchangeFactory.INSTANCE.createExchange(KrakenStreamingExchange.class.getName());
krakenExchange.connect(ProductSubscription.create().addAll(CurrencyPair.BTC_EUR).build()).blockingAwait();
krakenExchange.getStreamingMarketDataService().getOrderBook(CurrencyPair.BTC_EUR).subscribe(orderBook -> {
LOGGER.info("Ask 3: "+orderBook.getAsks().get(2).getLimitPrice()+" volume "+ orderBook.getAsks().get(2).getOriginalAmount());
LOGGER.info("Ask 2: "+orderBook.getAsks().get(1).getLimitPrice()+" volume "+ orderBook.getAsks().get(1).getOriginalAmount());
LOGGER.info("Ask 1: "+orderBook.getAsks().get(0).getLimitPrice()+" volume "+ orderBook.getAsks().get(0).getOriginalAmount());
LOGGER.info("--");
LOGGER.info("Bid 1: "+orderBook.getBids().get(0).getLimitPrice()+" volume "+ orderBook.getBids().get(0).getOriginalAmount());
LOGGER.info("Bid 2: "+orderBook.getBids().get(1).getLimitPrice()+" volume "+ orderBook.getBids().get(1).getOriginalAmount());
LOGGER.info("Bid 3: "+orderBook.getBids().get(2).getLimitPrice()+" volume "+ orderBook.getBids().get(2).getOriginalAmount());
LOGGER.info("=================");
});

    while(true){
        try{
            TimeUnit.SECONDS.sleep(10000);
        }catch (Exception e){
            LOGGER.error(e.getMessage(),e);
        }
    }

In one window i had the pro version kraken orderbook from the website and on the other window i had this test running. I found that they were inconsistent. Maybe you have fix this issue and you haven't merge with the core branch.

I am sorry about the dirty commits, i don't know why they appear or how to delete them. I am not git expert. Thanks

It is not valid to compare BigDecimal using "equals".
Use function "compareTo" for correct comaprison. E.g.
firstBigDecimal.compareTo(secendBigDecimal) == 0

@pchertalev ok. So you want me to put back stripTrailingZeros()?

@pchertalev ok. So you want me to put back stripTrailingZeros()?
Actually it does not metter to use one or not. BigDecimal are good anyway. But for me bigdecimal velue looks more pretty after stripTrailingZeros, more like to Rest Order book returns. And I don't see any strong reasons to change it.

About Kraken order book correctness, I did the following comparison:
On each WS book update I requested order book via res request and compare them.
I never get fully equal order books (rest vs WS), but they was very looks like each other. Its true of couse only if WS order book volume get rounded up to 3 decimal points.

@makarid Anyway, if you have found any bug in my code please drop me the code referrence, I will look at one.

@pchertalev i was also thinking to check via Rest Api, but i thought that this is not the correct way to do it.

Here you are the change that i have made:
1d8ec63

@makarid you are right, there was bug. It causes somtimes losing of bids updates. I did not see problem because number of differents were small and it is not very often case whan we get 2 separate lists with order book items. Thank you for your help!
I created pure pool request with your fix.

@pchertalev thanks a lot!