gruelbox/orko

[kraken] Kraken support

Opened this issue · 7 comments

Which exchange?
Kraken: https://www.kraken.com/

XChange and x-change-stream support
XChange yes, xchange-stream no (however bounty available for implementation)

Bounty
None

Progress

  • Public market data
    • BUG: market trades not coming through (socket timeouts)
    • BUG: intermittent "Premature EOF" on trades and order book requests
  • Sandbox support
  • Limit orders
  • Stop orders
  • Open orders
  • Trade history
  • Consider adding streaming (maybe worth doing for the bounty on bitrich-info/xchange-stream#279)

Beta read-only support provided. Need to test authenticated. No rush to provide streaming support unless there's a particularly strong reason to do so.

Getting stale nonce issues:

Jan 15 10:28:55: ERROR [2019-01-15 10:28:55,192] com.gruelbox.orko.marketdata.MarketDataSubscriptionManager: Error fetching market data: bitfinex/USD/NEO/OPEN_ORDERS 
Jan 15 10:28:55: ! org.knowm.xchange.exceptions.NonceException: Nonce is too small. 
Jan 15 10:28:55: ! at org.knowm.xchange.bitfinex.v1.service.BitfinexBaseService.handleException(BitfinexBaseService.java:49) 
Jan 15 10:28:55: ! at org.knowm.xchange.bitfinex.v1.service.BitfinexTradeServiceRaw.getBitfinexOpenOrders(BitfinexTradeServiceRaw.java:83) 
Jan 15 10:28:55: ! at org.knowm.xchange.bitfinex.v1.service.BitfinexTradeService.getOpenOrders(BitfinexTradeService.java:53) 
Jan 15 10:28:55: ! at com.gruelbox.orko.marketdata.MarketDataSubscriptionManager.pollAndEmitOpenOrders(MarketDataSubscriptionManager.java:676) 
Jan 15 10:28:55: ! at com.gruelbox.orko.marketdata.MarketDataSubscriptionManager.fetchAndBroadcast(MarketDataSubscriptionManager.java:644) 
Jan 15 10:28:55: ! at com.gruelbox.orko.marketdata.MarketDataSubscriptionManager.pollExchange(MarketDataSubscriptionManager.java:545) 
Jan 15 10:28:55: ! at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184) 
Jan 15 10:28:55: ! at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948) 
Jan 15 10:28:55: ! at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) 
Jan 15 10:28:55:  ! at java.util.stream.ForEachOps$ForEachTask.compute(ForEachOps.java:291) 
Jan 15 10:28:55:  ! at java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:731) 
Jan 15 10:28:55:  ! at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289) 
Jan 15 10:28:55:  ! at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056) 
Jan 15 10:28:55:  ! at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692) 
Jan 15 10:28:55:  ! at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157) 

Also looks like SocketTimeoutException is getting wrapped and thus not treated silently:

Feb 26 20:57:35: ERROR [2019-02-26 20:57:35,179] com.gruelbox.orko.marketdata.MarketDataSubscriptionManager: Error fetching data for kraken 
Feb 26 20:57:35: ! java.net.SocketTimeoutException: Read timed out 
Feb 26 20:57:35: ! at java.net.SocketInputStream.socketRead0(Native Method) 
Feb 26 20:57:35: ! at java.net.SocketInputStream.socketRead(SocketInputStream.java:116) 
Feb 26 20:57:35: ! at java.net.SocketInputStream.read(SocketInputStream.java:171) 
Feb 26 20:57:35: ! at java.net.SocketInputStream.read(SocketInputStream.java:141) 
Feb 26 20:57:35: ! at sun.security.ssl.InputRecord.readFully(InputRecord.java:465) 
Feb 26 20:57:35: ! at sun.security.ssl.InputRecord.read(InputRecord.java:503) 
Feb 26 20:57:35: ! at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:975) 
Feb 26 20:57:35: ! at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:933) 
Feb 26 20:57:35: ! at sun.security.ssl.AppInputStream.read(AppInputStream.java:105) 
Feb 26 20:57:35: ! at java.io.BufferedInputStream.fill(BufferedInputStream.java:246) 
Feb 26 20:57:35: ! at java.io.BufferedInputStream.read1(BufferedInputStream.java:286) 
Feb 26 20:57:35: ! at java.io.BufferedInputStream.read(BufferedInputStream.java:345) 
Feb 26 20:57:35: ! at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:735) 
Feb 26 20:57:35: ! at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:678) 
Feb 26 20:57:35: ! at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1587) 
Feb 26 20:57:35: ! at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492) 
Feb 26 20:57:35: ! at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480) 
Feb 26 20:57:35: ! at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:347) 
Feb 26 20:57:35: ! at si.mazi.rescu.HttpTemplate.receive(HttpTemplate.java:122) 
Feb 26 20:57:35: ! at si.mazi.rescu.RestInvocationHandler.receiveAndMap(RestInvocationHandler.java:162) 
Feb 26 20:57:35: ! at si.mazi.rescu.RestInvocationHandler.invoke(RestInvocationHandler.java:119) 
Feb 26 20:57:35: ! ... 14 common frames omitted 
Feb 26 20:57:35: ! Causing: java.lang.reflect.UndeclaredThrowableException: null 
Feb 26 20:57:35: ! at com.sun.proxy.$Proxy108.getTicker(Unknown Source) 
Feb 26 20:57:35: ! at org.knowm.xchange.kraken.service.KrakenMarketDataServiceRaw.getKrakenTicker(KrakenMarketDataServiceRaw.java:48) 
Feb 26 20:57:35: ! at org.knowm.xchange.kraken.service.KrakenMarketDataService.getTicker(KrakenMarketDataService.java:35) 
Feb 26 20:57:35: ! at com.gruelbox.orko.marketdata.MarketDataSubscriptionManager$Poller.pollAndEmitTicker(MarketDataSubscriptionManager.java:916) 
Feb 26 20:57:35: ! at com.gruelbox.orko.marketdata.MarketDataSubscriptionManager$Poller.lambda$fetchAndBroadcast$25(MarketDataSubscriptionManager.java:806) 
Feb 26 20:57:35: ! at com.gruelbox.orko.marketdata.MarketDataSubscriptionManager$Poller.manageExchangeExceptions(MarketDataSubscriptionManager.java:462) 
Feb 26 20:57:35: ! at com.gruelbox.orko.marketdata.MarketDataSubscriptionManager$Poller.fetchAndBroadcast(MarketDataSubscriptionManager.java:801) 
Feb 26 20:57:35: ! at com.gruelbox.orko.marketdata.MarketDataSubscriptionManager$Poller.loop(MarketDataSubscriptionManager.java:443) 
Feb 26 20:57:35: ! at com.gruelbox.orko.marketdata.MarketDataSubscriptionManager$Poller.run(MarketDataSubscriptionManager.java:386) 
Feb 26 20:57:35: ! at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) 
Feb 26 20:57:35: ! at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
Feb 26 20:57:35: ! at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) 
Feb 26 20:57:35: ! at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) 
Feb 26 20:57:35: ! at java.lang.Thread.run(Thread.java:748)

Now the two issues I'm seeing are what look like XChange bugs:

When fetching trades. Looks like XChange bug

ERROR [2019-03-01 06:08:43,330] com.gruelbox.orko.marketdata.MarketDataSubscriptionManager: Error fetching data for kraken 
 ! si.mazi.rescu.HttpStatusIOException: Unrecognized token 'j': was expecting ('true', 'false' or 'null') 
 !  at [Source: (StringReader); line: 1, column: 595] (through reference chain: org.knowm.xchange.kraken.dto.marketdata.results.KrakenPublicTradesResult["result"]) 
 ! at si.mazi.rescu.ResponseReader.read(ResponseReader.java:104) 
 ! at si.mazi.rescu.RestInvocationHandler.mapInvocationResult(RestInvocationHandler.java:175) 
 ! at si.mazi.rescu.RestInvocationHandler.receiveAndMap(RestInvocationHandler.java:163) 
 ! at si.mazi.rescu.RestInvocationHandler.invoke(RestInvocationHandler.java:119) 
 ! at com.sun.proxy.$Proxy112.getTrades(Unknown Source) 
 ! at org.knowm.xchange.kraken.service.KrakenMarketDataServiceRaw.getKrakenTrades(KrakenMarketDataServiceRaw.java:78) 
 ! at org.knowm.xchange.kraken.service.KrakenMarketDataService.getTrades(KrakenMarketDataService.java:83) 
 ! at com.gruelbox.orko.marketdata.MarketDataSubscriptionManager$Poller.pollAndEmitTrades(MarketDataSubscriptionManager.java:883) 

And

ERROR [2019-03-01 07:15:14,783] com.gruelbox.orko.marketdata.MarketDataSubscriptionManager: Error fetching data for kraken 
! java.io.IOException: Premature EOF 
! at sun.net.www.http.ChunkedInputStream.readAheadBlocking(ChunkedInputStream.java:565) 
! at sun.net.www.http.ChunkedInputStream.readAhead(ChunkedInputStream.java:609) 
! at sun.net.www.http.ChunkedInputStream.read(ChunkedInputStream.java:696) 
! at java.io.FilterInputStream.read(FilterInputStream.java:133) 
! at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:3444) 
! at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284) 
! at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326) 
! at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178) 
! at java.io.InputStreamReader.read(InputStreamReader.java:184) 
! at java.io.BufferedReader.fill(BufferedReader.java:161) 
! at java.io.BufferedReader.readLine(BufferedReader.java:324) 
! at java.io.BufferedReader.readLine(BufferedReader.java:389) 
! at si.mazi.rescu.HttpTemplate.readInputStreamAsEncodedString(HttpTemplate.java:231) 
! at si.mazi.rescu.HttpTemplate.receive(HttpTemplate.java:134) 
! at si.mazi.rescu.RestInvocationHandler.receiveAndMap(RestInvocationHandler.java:162) 
! at si.mazi.rescu.RestInvocationHandler.invoke(RestInvocationHandler.java:119) 
! at com.sun.proxy.$Proxy112.getTrades(Unknown Source) 
! at org.knowm.xchange.kraken.service.KrakenMarketDataServiceRaw.getKrakenTrades(KrakenMarketDataServiceRaw.java:78) 
! at org.knowm.xchange.kraken.service.KrakenMarketDataService.getTrades(KrakenMarketDataService.java:83) 
! at com.gruelbox.orko.marketdata.MarketDataSubscriptionManager$Poller.pollAndEmitTrades(MarketDataSubscriptionManager.java:883)

Looking more stable at the back-end now despite a lot of socket timeouts and premature EOFs (hooray for the tolerance code and automated backoff)

Damn, looks like market trades don't work at all (all the requests are timing out).

I started on this, but am no longer actively using Kraken so it's fallen some way down my priority list.

If anyone else wants to pick it up, please do. Happy to give pointers.