Code Monkey home page Code Monkey logo

bitrich-info / xchange-stream Goto Github PK

View Code? Open in Web Editor NEW
412.0 53.0 223.0 2.07 MB

XChange-stream is a Java library providing a simple and consistent streaming API for interacting with Bitcoin and other crypto currency exchanges via WebSocket protocol. It is build on top of of XChange library providing new interfaces for streaming API. User can subscribe for live updates via reactive streams of RxJava library.

License: Apache License 2.0

Java 100.00%
xchange xchange-stream streaming-api bitcoin websocket

xchange-stream's People

Contributors

alphafoobar avatar badgerwithagun avatar benjamintrapani avatar bodysplash avatar bryantharris avatar davidjirovec avatar declan94 avatar dependabot-preview[bot] avatar dependabot-support avatar dependabot[bot] avatar dozd avatar dpisklov avatar flemingjp avatar foat avatar henryxwong avatar janakerman avatar jkolobok avatar kaiserfr avatar langchristian96 avatar lucarosellini avatar lukaszaoralek avatar makarid avatar mdvx avatar nephtys avatar nodarret avatar pchertalev avatar scionaltera avatar traviscollins avatar trojanflash avatar tsavo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

xchange-stream's Issues

Add subscription to heartbeat channel on GDAX

I was not able to make GDAX trade subscription sustainable - for me it terminates every other day without any indication - websocket does not disconnect.
You can emulate this by disconnecting the network after initial subscription has been established.

Checking if I've received any messages in the last n seconds would work, but seems hacky.

GDAX API docs indicate there is heartbeat channel to verify that connection is healthy, would be great to have that implemented.
https://docs.gdax.com, search for 'heartbeat'

Standardize process for exchange channel(s) subscription

@dozd
Please consider the following proposal for subscribing process:
Now the subscription of the product(s)/symbol(s)/pair(s) is related with the methods like getOrderBook, getTrade and getTicker.
But for example the Gdax exchange allows only one subscription per multiple products. Another example is the Gemini exchange, where each product has own wss connection. In The bitfinex scenario, the channel request contains name of the product, but the server sends its channel id in the response and then the server sends the market update/snapshot events with the channel id. In summary, each implementation has "tricky" code how to cover all of these cases.

In my opinion, it should be more standardize way how to subscribe the channles/product(s) without the "tricky" code. Therefore I propose the subscriptions of all product(s) and kind of market events have to be defined before connection to the exchange. For example:
In the interface StreamingExchange extends the method connect with one subscription argument:

public interface StreamingExchange<T extends StreamingSubscription> ... {
  ...
  Completable connect(T streamingSubscription);
  ...
}

Each exchange has to be implemented the own class (ExchangeName)StreamingSubscription (that implements interface StreamingSubscription). Consider the example with Gdax and Gemini cases:

class GdaxStreamingSubscription implements StreamingSubscription {
  private GdaxStreamingSubscription() {...}

  public static createGdaxStreamingSubscription(GdaxProductSubscription[] subscriptions) {}
}

where the class GdaxProductSubscription can look like:

GdaxProductSubscription {
  public GdaxProductSubscription(CurrencyPair pair, boolean orderbook, boolean ticker, boolean trade) {...}
}

and for Gemini case the StreamingSubscription class will be different:

class GeminiStreamingSubscription implements StreamingSubscription {
  private GeminiStreamingSubscription() {...}
  ...
  public static createGeminiStreamingSubscription(CurrencyPair[] pairs) {}
  ...
}

The GdaxExchange will look like:

public class GDAXStreamingExchange extends GDAXExchange implements StreamingExchange<GdaxStreamingSubscription> {
  ...
  public Completable connect(GdaxStreamingSubscription streamingSubscription) {...}
  ...
}

It hides all needs for subscribing the market events for different exchanges, standardize the subscribing process, and the StreamingMarketDataService interface doesn't change.

What do you think guys?

References/examples for building live feed

Hi,

I want to thank you for this great addition to the XChange project, streaming is jsut what I was looking for :) So THANK YOU.

I want to build a live feed of crypto currencies order book, maybe using a deamon that is similar to what was done in bitcoinium.com just with sub seconds(100ms is great) pulling time interval.

I want to describe to you my plan and ask for additional references or tips.

So my plan is:

  1. Loop for forever each exchange and symbol
  2. If it has WebSocket Api, use xchange-stream otherwise use REST with XChange.
  3. Retry with some exponential backoff sleeping when you have a connection error or reached an API rate limit. Like in the RetriesDemo. I Guess that I will need to form IPredicate for each exchange, did anyone do it so far?

I would be happy to get input if people here think that my plan is correct and be shared with references of code any relevant example.

What is the right place for such questions?

Cannot get data from Bitstamp: state from CONNECTED -> DISCONNECTING almost immediately

Cannot get live data from bitstamp. Use test case from Bistamp test. Got this log:

[main] INFO info.bitrich.xchangestream.bitstamp.BitstampStreamingExchange - Calling Remote Init...
[main] INFO info.bitrich.xchangestream.bitstamp.BitstampStreamingExchange - No remote initialization implemented for Bitstamp....
[pusher-java-client eventQueue] INFO info.bitrich.xchangestream.service.pusher.PusherStreamingService - State changed to CONNECTING from DISCONNECTED
[pusher-java-client eventQueue] INFO info.bitrich.xchangestream.service.pusher.PusherStreamingService - State changed to CONNECTED from CONNECTING
[main] INFO info.bitrich.xchangestream.service.pusher.PusherStreamingService - Subscribing to channel order_book.
[main] INFO info.bitrich.xchangestream.service.pusher.PusherStreamingService - Subscribing to channel live_trades.
[main] INFO bitcoinledger.feeds.exchanges.Bitstamp2Test - Disconnected from the Exchange
[pusher-java-client eventQueue] INFO info.bitrich.xchangestream.service.pusher.PusherStreamingService - State changed to DISCONNECTING from CONNECTED
[pusher-java-client eventQueue] INFO info.bitrich.xchangestream.service.pusher.PusherStreamingService - State changed to DISCONNECTED from DISCONNECTING

How to get more details for this case? How to dig into pusher? Please help.

4.3.0-SNAPSHOT will fail to build in SBT because of javax.ws.rs-api dependency

[With an empty .ivy2 cache] SBT will fail to build 4.3.0-SNAPSHOT. Example:

name := "test"

version := "1.0"

scalaVersion := "2.12.1"

resolvers += "Sonatype OSS Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots"

val xchangeStreamVersion = "4.3.0-SNAPSHOT"

libraryDependencies += "info.bitrich.xchange-stream" % "xchange-stream-core" % xchangeStreamVersion
libraryDependencies += "info.bitrich.xchange-stream" % "xchange-poloniex2" % xchangeStreamVersion

Error:

[warn] 	[NOT FOUND  ] javax.ws.rs#javax.ws.rs-api;2.1!javax.ws.rs-api.${packaging.type} (1ms)
[warn] ==== public: tried
[warn]   https://repo1.maven.org/maven2/javax/ws/rs/javax.ws.rs-api/2.1/javax.ws.rs-api-2.1.${packaging.type}

Looking at https://mvnrepository.com/artifact/javax.ws.rs/javax.ws.rs-api/2.1 I kinda understand why. There is actually ${packaging.type} in files instead of jar. So it's most likely a javax.ws.rs-api issue. Meanwhile you can use a workaround in build.sbt:

val workaround = {
  sys.props += "packaging.type" -> "jar"
  ()
}

I was wandering if there is a better way?

BitFinex error response throws NullPointerException

As mentioned in issue #48 invalid symbol errors are not handled correctly when subscribing to BitFinex. A null exception is thrown:

java.lang.NullPointerException
	at info.bitrich.xchangestream.bitfinex.BitfinexStreamingService.getChannelNameFromMessage(BitfinexStreamingService.java:104)
	at info.bitrich.xchangestream.bitfinex.BitfinexStreamingService.getChannelNameFromMessage(BitfinexStreamingService.java:20)
	at info.bitrich.xchangestream.service.netty.NettyStreamingService.getChannel(NettyStreamingService.java:199)
	at info.bitrich.xchangestream.service.netty.NettyStreamingService.handleError(NettyStreamingService.java:213)
	at info.bitrich.xchangestream.bitfinex.BitfinexStreamingService.handleMessage(BitfinexStreamingService.java:88)
	at info.bitrich.xchangestream.bitfinex.BitfinexStreamingService.messageHandler(BitfinexStreamingService.java:54)
	at info.bitrich.xchangestream.service.netty.WebSocketClientHandler.channelRead0(WebSocketClientHandler.java:66)
	at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
	at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:310)
	at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:297)
	at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:413)
	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
	at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1172)
	at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1078)
	at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489)
	at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428)
	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926)
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:134)
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:644)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:579)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:496)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:458)
	at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858)
	at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:138)
	at java.base/java.lang.Thread.run(Thread.java:844)```

Looks like an array (a normal ticker response) is expected, but in fact the response is an ObjectNode.

WebSocket Client disconnected!

How to get the message in my code, when netty found websocket disconnected. many thanks,
2017-12-07 11:19:26.009 INFO 31176 --- [ntLoopGroup-2-1] i.b.x.s.netty.WebSocketClientHandler : WebSocket Client disconnected!

Exchange doesn't disconnect gracefully

When I repeat following steps as in example:

  1. Connect to GDAX exchange.
  2. Subscribe to trades.
  3. Check that there really come trades.
  4. Dispose all my subscriptions.
  5. Disconnect from exchange.
  6. Program main loop goes to its end.

But program doesn't stop! There is still threads running somewhere.

I'm using Spring Boot web app and I'm stopping web server via POST /shutdown request. All other services are then shutdown.

This is not big deal. Currently I call System.exit() 15 s after that request. But this is annoying and smells that there is thread leak somewhere.

Binance example throws NullPointerException

Tried launching Binance code under the test directory and got this stacktrace:

java.lang.NullPointerException
at info.bitrich.xchangestream.service.netty.NettyStreamingService.handleChannelMessage(NettyStreamingService.java:241)
at info.bitrich.xchangestream.service.netty.NettyStreamingService.handleMessage(NettyStreamingService.java:231)
at info.bitrich.xchangestream.binance.BinanceProductStreamingService.messageHandler(BinanceProductStreamingService.java:39)
at info.bitrich.xchangestream.service.netty.WebSocketClientHandler.channelRead0(WebSocketClientHandler.java:66)
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at ...

[Bitstamp] Full snapshot +live orders

Hi!

Has anyone tried to subscribe to snapshot and then listen to live_orders?

It seems like snapshot channel contains only price and size fields (unlike Bitfinex), however orders do contain quoteId. Is there any way to combine those two? Or the only way is just start with live_orders and hope that order book gradually build itself

Gleb

okex null pointer exception

When run the
xchange-stream/xchange-okcoin/src/test/java/info/bitrich/xchangestream/okcoin/OkExManualExample.java
,
a nullPointerException raised and the websocket was disconnected.

After trace the source code, I found that okex send a "addChannel" message after subscription.
The "addChannel" message is like:
{"binary":0,"channel":"addChannel","data":{"result":true,"channel":"ok_sub_spot_btc_usd_ticker"}}

It seems like that there would be two way to fix it.

  1. change the handleChannelMessage method to check whether the "channel" is in "channles" before get the "emitter".
  2. add the "addChannel" as default channel of okex

I guess that the okcoin exchange may have the same issue.
Which solution is better? Or any other ideas?

Bitfinex reconnect loop

I'm seeing the Bitfinex stream get into a reconnect loop in version 4.3.1. On 4.3.2-SNAPSHOT I get issue #81 on the GDAX side instead so it's hard to tell if this is also happening or not.

2018-01-23 17:51:29.888 INFO 1 --- [tLoopGroup-65-1] i.b.x.s.netty.WebSocketClientHandler : WebSocket Client disconnected!
2018-01-23 17:51:29.889 INFO 1 --- [tLoopGroup-65-1] i.b.x.s.netty.NettyStreamingService : Reopening websocket because it was closed by the host
2018-01-23 17:51:29.889 INFO 1 --- [tLoopGroup-65-1] i.b.x.s.netty.NettyStreamingService : Connecting to wss://api.bitfinex.com:-1/ws/2
2018-01-23 17:51:30.605 INFO 1 --- [tLoopGroup-66-1] i.b.x.s.netty.WebSocketClientHandler : WebSocket Client connected!
2018-01-23 17:51:30.605 INFO 1 --- [tLoopGroup-65-1] i.b.x.s.netty.NettyStreamingService : Resubscribing channels
2018-01-23 17:51:30.795 ERROR 1 --- [tLoopGroup-66-1] i.b.x.bitfinex.BitfinexStreamingService : Error with message: "channel: unknown"

Because it doesn't have the right channel name it can't successfully reconnect but it keeps trying until I kill it. So far I've only seen this happen if I leave it running for a long period of time in AWS. I just saw it happen locally on my laptop.

I'm running 4.3.2-SNAPSHOT with the change mentioned in #81 now to see if this issue got fixed in the develop branch already. and it still happens, but seems less frequent.

NPE on GDAX getChannelFromMessage

I got a random NPE on startup in the src on:
return message.get("channels").get(0).get(PRODUCT_IDS).get(0).asText();

It seems there's an update due which has removed that line though.

java.lang.NullPointerException
	at info.bitrich.xchangestream.gdax.GDAXStreamingService.getChannelNameFromMessage(GDAXStreamingService.java:69)
	at info.bitrich.xchangestream.gdax.GDAXStreamingService.getChannelNameFromMessage(GDAXStreamingService.java:24)
	at info.bitrich.xchangestream.service.netty.NettyStreamingService.getChannel(NettyStreamingService.java:199)
	at info.bitrich.xchangestream.service.netty.NettyStreamingService.handleMessage(NettyStreamingService.java:208)
	at info.bitrich.xchangestream.gdax.GDAXStreamingService.handleMessage(GDAXStreamingService.java:97)
	at info.bitrich.xchangestream.gdax.GDAXStreamingService.handleMessage(GDAXStreamingService.java:24)
	at info.bitrich.xchangestream.service.netty.JsonNettyStreamingService.messageHandler(JsonNettyStreamingService.java:42)
	at info.bitrich.xchangestream.service.netty.WebSocketClientHandler.channelRead0(WebSocketClientHandler.java:66)
	at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
	at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:310)
	at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:297)
	at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:413)
	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
	at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1273)
	at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1084)
	at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489)
	at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428)
	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926)
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:134)
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:644)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:579)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:496)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:458)
	at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858)
	at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:138)
	at java.lang.Thread.run(Thread.java:748)

Bitmex websocket returns scrambled data

Since a few days the Bitmex websocket returns scrambled data on wss://testnet.bitmex.com/realtime, the Bitmex-test-API. (Meaning that I get all sorts of special characters instead of plain text)

Please Note that there are two websocket api's available on Bitmex and only one of them returns scrambled data:

  • wss://testnet.bitmex.com/realtime (returns scrambled data)
  • wss://www.bitmex.com/realtime (returns correct plain text)

When I use use a simple manual websocket testprogram on wss://testnet.bitmex.com/realtime everything seems to be ok. This hints at a problem in xchange-stream & Netty, who seem to decode the incoming stream incorrectly .

Please reproduce the problem by calling the info.bitrich.xchangestream.bitmex.BitmexManualExample class and simultanously changing the API_URI in BitmexStreamingExchange to "wss://testnet.bitmex.com/realtime";

No netty-tcnative

Hello, I'm trying to get either 4.2.3 or 4.3.0-SNAPSHOT to work, but both result in an issue with netty not being available.

Full log at: https://pastebin.com/NCmFhyZ6

Relevant bits:

2017-11-21 13:05:24,613 [DEBUG ] NativeLibraryLoader 81 │ Unable to load the library 'netty-tcnative-linux-x86_64', trying other loading mechanism.
java.lang.UnsatisfiedLinkError: no netty-tcnative-linux-x86_64 in java.library.path
	at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1867) ~[?:1.8.0_151]
	at java.lang.Runtime.loadLibrary0(Runtime.java:870) ~[?:1.8.0_151]
	at java.lang.System.loadLibrary(System.java:1122) ~[?:1.8.0_151]
	at io.netty.util.internal.NativeLibraryUtil.loadLibrary(NativeLibraryUtil.java:38) ~[netty-common-4.0.47.Final.jar:4.0.47.Final]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_151]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_151]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_151]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_151]
	at io.netty.util.internal.NativeLibraryLoader$1.run(NativeLibraryLoader.java:272) ~[netty-common-4.0.47.Final.jar:4.0.47.Final]
	at java.security.AccessController.doPrivileged(Native Method) ~[?:1.8.0_151]
	at io.netty.util.internal.NativeLibraryLoader.loadLibraryByHelper(NativeLibraryLoader.java:264) ~[netty-common-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.util.internal.NativeLibraryLoader.loadLibrary(NativeLibraryLoader.java:252) ~[netty-common-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.util.internal.NativeLibraryLoader.load(NativeLibraryLoader.java:199) ~[netty-common-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.util.internal.NativeLibraryLoader.loadFirstAvailable(NativeLibraryLoader.java:170) ~[netty-common-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.handler.ssl.OpenSsl.loadTcNative(OpenSsl.java:403) ~[netty-handler-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.handler.ssl.OpenSsl.<clinit>(OpenSsl.java:85) ~[netty-handler-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.handler.ssl.SslContext.defaultProvider(SslContext.java:118) ~[netty-handler-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.handler.ssl.SslContext.defaultClientProvider(SslContext.java:114) ~[netty-handler-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.handler.ssl.SslContext.newClientContextInternal(SslContext.java:763) ~[netty-handler-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.handler.ssl.SslContextBuilder.build(SslContextBuilder.java:446) ~[netty-handler-4.0.47.Final.jar:4.0.47.Final]
	at info.bitrich.xchangestream.service.netty.NettyStreamingService.lambda$connect$2(NettyStreamingService.java:83) ~[service-netty-4.3.0-SNAPSHOT.jar:?]
	at io.reactivex.internal.operators.completable.CompletableCreate.subscribeActual(CompletableCreate.java:39) [rxjava-2.0.4.jar:2.0.4]
	at io.reactivex.Completable.subscribe(Completable.java:1613) [rxjava-2.0.4.jar:2.0.4]
	at io.reactivex.Completable.blockingAwait(Completable.java:909) [rxjava-2.0.4.jar:2.0.4]
	at com.sirolf2009.orderbook.collector.OrderbookCollector.run(OrderbookCollector.java:16) [classes/:?]
	at com.sirolf2009.orderbook.collector.OrderbookCollector.main(OrderbookCollector.java:25) [classes/:?]
2017-11-21 13:05:24,616 [DEBUG ] NativeLibraryLoader 81 │ Unable to load the library 'netty-tcnative-linux-x86_64', trying next name...
java.lang.UnsatisfiedLinkError: no netty-tcnative-linux-x86_64 in java.library.path

It tries a few more names until resulting to

2017-11-21 13:05:24,622 [DEBUG ] OpenSsl 91 │ Failed to initialize netty-tcnative; OpenSslEngine will be unavailable. See http://netty.io/wiki/forked-tomcat-native.html for more information.

It eventually crashes with

2017-11-21 13:05:24,842 [WARN  ] ChannelInitializer 151 │ Failed to initialize a channel. Closing: [id: 0xb9e45b6d]
java.lang.NoSuchMethodError: io.netty.handler.codec.compression.ZlibCodecFactory.isSupportingWindowSizeAndMemLevel()Z
	at info.bitrich.xchangestream.gdax.netty.WebSocketClientCompressionAllowClientNoContextHandler.<init>(WebSocketClientCompressionAllowClientNoContextHandler.java:22) ~[xchange-gdax-4.3.0-SNAPSHOT.jar:?]
	at info.bitrich.xchangestream.gdax.netty.WebSocketClientCompressionAllowClientNoContextHandler.<clinit>(WebSocketClientCompressionAllowClientNoContextHandler.java:18) ~[xchange-gdax-4.3.0-SNAPSHOT.jar:?]
	at info.bitrich.xchangestream.gdax.GDAXStreamingService.getWebSocketClientExtensionHandler(GDAXStreamingService.java:102) ~[xchange-gdax-4.3.0-SNAPSHOT.jar:?]
	at info.bitrich.xchangestream.service.netty.NettyStreamingService$1.initChannel(NettyStreamingService.java:105) ~[service-netty-4.3.0-SNAPSHOT.jar:?]
	at info.bitrich.xchangestream.service.netty.NettyStreamingService$1.initChannel(NettyStreamingService.java:97) ~[service-netty-4.3.0-SNAPSHOT.jar:?]
	at io.netty.channel.ChannelInitializer.initChannel(ChannelInitializer.java:113) [netty-transport-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.channel.ChannelInitializer.handlerAdded(ChannelInitializer.java:105) [netty-transport-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.channel.DefaultChannelPipeline.callHandlerAdded0(DefaultChannelPipeline.java:582) [netty-transport-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.channel.DefaultChannelPipeline.access$000(DefaultChannelPipeline.java:43) [netty-transport-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.channel.DefaultChannelPipeline$PendingHandlerAddedTask.execute(DefaultChannelPipeline.java:1347) [netty-transport-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.channel.DefaultChannelPipeline.callHandlerAddedForAllHandlers(DefaultChannelPipeline.java:1082) [netty-transport-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.channel.DefaultChannelPipeline.invokeHandlerAddedIfNeeded(DefaultChannelPipeline.java:632) [netty-transport-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.channel.AbstractChannel$AbstractUnsafe.register0(AbstractChannel.java:452) [netty-transport-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.channel.AbstractChannel$AbstractUnsafe.access$200(AbstractChannel.java:374) [netty-transport-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.channel.AbstractChannel$AbstractUnsafe$1.run(AbstractChannel.java:424) [netty-transport-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:399) [netty-common-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:463) [netty-transport-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:131) [netty-common-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:138) [netty-common-4.0.47.Final.jar:4.0.47.Final]
	at java.lang.Thread.run(Thread.java:748) [?:1.8.0_151]
2017-11-21 13:05:24,845 [WARN  ] DefaultPromise 151 │ An exception was thrown by info.bitrich.xchangestream.service.netty.NettyStreamingService$$Lambda$4/405896924.operationComplete()
java.lang.NullPointerException: null
	at info.bitrich.xchangestream.service.netty.NettyStreamingService.lambda$null$1(NettyStreamingService.java:117) ~[service-netty-4.3.0-SNAPSHOT.jar:?]
	at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:507) [netty-common-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:481) [netty-common-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:420) [netty-common-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.util.concurrent.DefaultPromise.tryFailure(DefaultPromise.java:122) [netty-common-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.channel.AbstractChannel$AbstractUnsafe.safeSetFailure(AbstractChannel.java:851) [netty-transport-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.channel.AbstractChannel$AbstractUnsafe.ensureOpen(AbstractChannel.java:834) [netty-transport-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.connect(AbstractNioChannel.java:194) [netty-transport-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.channel.DefaultChannelPipeline$HeadContext.connect(DefaultChannelPipeline.java:1226) [netty-transport-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeConnect(AbstractChannelHandlerContext.java:539) [netty-transport-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.channel.AbstractChannelHandlerContext.connect(AbstractChannelHandlerContext.java:524) [netty-transport-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.channel.AbstractChannelHandlerContext.connect(AbstractChannelHandlerContext.java:506) [netty-transport-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.channel.DefaultChannelPipeline.connect(DefaultChannelPipeline.java:970) [netty-transport-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.channel.AbstractChannel.connect(AbstractChannel.java:214) [netty-transport-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.bootstrap.Bootstrap$2.run(Bootstrap.java:166) [netty-transport-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:399) [netty-common-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:463) [netty-transport-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:131) [netty-common-4.0.47.Final.jar:4.0.47.Final]
	at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:138) [netty-common-4.0.47.Final.jar:4.0.47.Final]
	at java.lang.Thread.run(Thread.java:748) [?:1.8.0_151]

pom.xml (relevant bits, full at https://pastebin.com/2zHZvLMN)

(snip)
		<extensions>
			<extension>
				<groupId>kr.motd.maven</groupId>
				<artifactId>os-maven-plugin</artifactId>
				<version>1.4.0.Final</version>
			</extension>
		</extensions>
(snip)
		<dependency>
			<groupId>info.bitrich.xchange-stream</groupId>
			<artifactId>xchange-stream-core</artifactId>
			<version>4.3.0-SNAPSHOT</version>
		</dependency>
		<dependency>
			<groupId>info.bitrich.xchange-stream</groupId>
			<artifactId>xchange-gdax</artifactId>
			<version>4.3.0-SNAPSHOT</version>
		</dependency>
		<dependency>
			<groupId>io.netty</groupId>
			<artifactId>netty-tcnative</artifactId>
			<version>2.0.0.Final</version>
			<classifier>linux-x86_64</classifier>
		</dependency>
(snip)

As you can see I tried to follow the guide from http://netty.io/wiki/forked-tomcat-native.html, but to no avail

also, this might help

$ cat /proc/version
Linux version 4.9.0-4-amd64 ([email protected]) (gcc version 6.3.0 20170516 (Debian 6.3.0-18) ) #1 SMP Debian 4.9.51-1 (2017-09-28)

Exception while subscribing to Bitstemp OrderBook

Hi there,

i am currently testing your example code. In particular i am interested in the orderbook subscription. if i try your code example I get the following exception:

com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of org.knowm.xchange.bitstamp.dto.marketdata.BitstampOrderBook, problem: null

Although, the detailed error messages shows bids and asks I get this error.

As far as I know, Bistamp does not support timestamps in placed trades in the Orderbook. I though all timestamps of the orders in the OrderBook are null. Maybe that cause the problem?

Kind regards,
Hendrik

Coinbase ETH/USD

Coinbase gave me the following Ticker for CurrencyPair.ETH_USD:

Ticker [currencyPair=ETH/USD, last=6442.00, bid=6409.78, ask=6474.21, high=null, low=null,avg=null, volume=null, timestamp=null]

This is too good to be true :-)

Seems to be the values for BTC_USD, instead of ETH_USD.

CodecException: invalid WebSocket Extension handshake for "permessage-deflate; client_no_context_takeover"

Hi, I am attempting to use the 4.3.2-SNAPSHOT of the GDAX Streaming library. Upon connection to the websocket, I receive the error:

09:57:09.137 [main] INFO  info.bitrich.xchangestream.gdax.GDAXStreamingService - Registering GDAXWebSocketClientHandler
io.netty.handler.codec.CodecException: invalid WebSocket Extension handshake for "permessage-deflate; client_no_context_takeover"
	at io.netty.handler.codec.http.websocketx.extensions.WebSocketClientExtensionHandler.channelRead(WebSocketClientExtensionHandler.java:111)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
	at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:438)
	at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:310)
	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:284)
	at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:253)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
	at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1267)
	at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1078)
	at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489)
	at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428)
	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926)
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:134)
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:644)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:579)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:496)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:458)
	at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858)
	at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:138)
	at java.lang.Thread.run(Unknown Source)

Below are my dependencies:

		<dependency>
			<groupId>info.bitrich.xchange-stream</groupId>
			<artifactId>xchange-stream-core</artifactId>
			<version>4.3.2-SNAPSHOT</version>
		</dependency>
		<dependency>
			<groupId>info.bitrich.xchange-stream</groupId>
			<artifactId>xchange-gdax</artifactId>
			<version>4.3.2-SNAPSHOT</version>
		</dependency>
		<dependency>
			<groupId>org.knowm.xchange</groupId>
			<artifactId>xchange-core</artifactId>
			<version>4.3.2-SNAPSHOT</version>
		</dependency>
		<dependency>
			<groupId>org.knowm.xchange</groupId>
			<artifactId>xchange-examples</artifactId>
			<version>4.3.2-SNAPSHOT</version>
		</dependency>
		<dependency>
			<groupId>org.knowm.xchange</groupId>
			<artifactId>xchange-gdax</artifactId>
			<version>4.3.2-SNAPSHOT</version>
		</dependency>

Poloniex Websocket provided too old data.

I use xchange-stream lib for Polonix websocket.
It's works!
But that provides too old Orderboox and Trade data.

For example
I have received 30. OCT Trade Data as ETH/BTC.
How can i fix it?

GDAX Order Book

"GDAX authenticated live updates is not yet supported, hopefully it will be added in the near future."
Does getting order book work with unauthenticated one or it's just missing?

BitStamp order book timestamp is wrong

XChange BitStampOrderBook constructor multiplies timestamp by 1000 - therefore
BitstampStreamingMarketDataService
new org.knowm.xchange.bitstamp.dto.marketdata.BitstampOrderBook((new Date()).getTime()
should divide it by 1000 just to make it work

Can you add Cryptocompare

Cryptocompare i not an exchange but it provides good quality exchange data from all exchanges.
It can be an "easy" way to wrap cryptocompare API in a java client.

Bitfinex fails to subscribe to DASH

DASH/BTC and DASH/USD are listed as supported by getExchangeSymbols() for BitfinexStreamingExchange.

Any other pair works:

import info.bitrich.xchangestream.core.StreamingExchangeFactory
import info.bitrich.xchangestream.bitfinex.BitfinexStreamingExchange
import org.knowm.xchange.currency.CurrencyPair
import org.knowm.xchange.dto.marketdata.Trade

object Tst extends App {
  val pair = new CurrencyPair("BTC", "USD")
  val exchange = StreamingExchangeFactory.INSTANCE.createExchange(classOf[BitfinexStreamingExchange].getName)

  exchange.connect.blockingAwait()

  exchange.getStreamingMarketDataService.getTrades(pair).subscribe((trade: Trade) => {
    println(trade)
  }, (throwable: Throwable) => println("ERROR in getting trades: ", pair, throwable))
}

Same code with DASH won't work:

import info.bitrich.xchangestream.core.StreamingExchangeFactory
import info.bitrich.xchangestream.bitfinex.BitfinexStreamingExchange
import org.knowm.xchange.currency.CurrencyPair
import org.knowm.xchange.dto.marketdata.Trade

object Tst extends App {
  val pair = new CurrencyPair("DASH", "USD")
  val exchange = StreamingExchangeFactory.INSTANCE.createExchange(classOf[BitfinexStreamingExchange].getName)
 
  exchange.connect.blockingAwait()

  exchange.getStreamingMarketDataService.getTrades(pair).subscribe((trade: Trade) => {
    println(trade)
  }, (throwable: Throwable) => println("ERROR in getting trades: ", pair, throwable))
}

Exception:

java.lang.NullPointerException
	at info.bitrich.xchangestream.bitfinex.BitfinexStreamingService.getChannelNameFromMessage(BitfinexStreamingService.java:104)
	at info.bitrich.xchangestream.bitfinex.BitfinexStreamingService.getChannelNameFromMessage(BitfinexStreamingService.java:20)
	at info.bitrich.xchangestream.service.netty.NettyStreamingService.getChannel(NettyStreamingService.java:199)
	at info.bitrich.xchangestream.service.netty.NettyStreamingService.handleError(NettyStreamingService.java:213)
	at info.bitrich.xchangestream.bitfinex.BitfinexStreamingService.handleMessage(BitfinexStreamingService.java:88)
	at info.bitrich.xchangestream.bitfinex.BitfinexStreamingService.messageHandler(BitfinexStreamingService.java:54)
	at info.bitrich.xchangestream.service.netty.WebSocketClientHandler.channelRead0(WebSocketClientHandler.java:66)
	at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
	at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:310)
	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:284)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
	at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1267)
	at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1078)
	at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489)
	at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428)
	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926)
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:134)
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:644)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:579)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:496)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:458)
	at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858)
	at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:138)
	at java.lang.Thread.run(Thread.java:748)

I could probably fix it myself if pointed in the right direction.

Resubscribing after client reconnects?

I have been streaming tickers from Poloniex succesfully by following the example here. Works nicely, but everytime the wampclient disconnects (and automatically reconnects) I lose all my subscribtions. So I guess I should always resubscribe to getTicker when the client state changes to connected, but what is the best way to detect this? I can only see the "State changed:" log message when this happens.

Very new to RxJava, so the answer might be obvious, but I just can't seem to figure it out. Thanks!

Bitfinex orderbook not in sync

Hello, I've been displaying the bitfinex orderbook in my own trading platform and I've been seeing a difference between the bitfinex dashboard and the data received from the xchange api. I don't know how often this happens, because I only really check the walls, but every hour or so I realize that I am out of sync

Differentiate between live orders and trades?

For the Bitstamp implementation, the current getTrades() method returns the live orders information. However Bitstamp does have an api for the live trades. I have tested it, which works fine. Do you think it's a good idea to differentiate these two at the top level abstraction (StreamingMarketDataService)? or Can you suggest some workaround? I am happy to contribute either way.

Including busy spin into example code

Hi, Im new to RxJava and have some difficulties to understand how it works

In your example, if I try to run the app, I do not get any output. However, if I include while (true) {} before disconnect, I start getting live trades while busy spinning. Is it correct way to implement such applications? When can one read some examples? RxJava docs does not help much honestly

Thanks a lot

Implement Bitmex exchange with bounty

Hello,i am offering a bounty of 50mBTC in order someone to implement the Bitmex exchange,using websocket connection.I am mostly interested for XBTUSD contracts.I am waiting for your response,please ask me if you want to specify anything.Thanks a lot!

BitFinex ticker API - incorrect symbol value for DASH

When subscribing for the pair DASH/BTC from the BitFinex ticker, an symbol: invalid response is received. (This actually results in a NullPointerException but that is a separate issue.)

This is the request message that is sent out:
{"event":"subscribe","channel":"ticker","pair":"DASHBTC","prec":null,"len":null}

This is the response received:
{"channel":"ticker","pair":"ASHBTC","event":"error","symbol":"DASHBTC","msg":"symbol: invalid","code":10300}

When you play with the BitFinex's websocket API on their websocket playground, it behaves the same, but when you use the pair DSH/BTC it starts to send updates. I can only assume that this is DASH as the base, because their /symbols API doesn't work as advertised.

Looks like BitFinex API simply expects a different currency symbol that the Currency - probably just a configuration update for that exchanges meta data json file?

Poloniex - connect() issue

Hi, I tried to use this combination fo dependencies:

 <!-- https://mvnrepository.com/artifact/info.bitrich.xchange-stream/xchange-stream-core -->
        <dependency>
            <groupId>info.bitrich.xchange-stream</groupId>
            <artifactId>xchange-stream-core</artifactId>
            <version>4.3.0</version>
        </dependency>


        <!-- https://mvnrepository.com/artifact/org.knowm.xchange/xchange-poloniex -->
        <dependency>
            <groupId>info.bitrich.xchange-stream</groupId>
            <artifactId>xchange-poloniex2</artifactId>
            <version>4.3.1-SNAPSHOT</version>
        </dependency>

And getting following error:

Exception in thread "main" java.lang.AbstractMethodError: info.bitrich.xchangestream.poloniex2.PoloniexStreamingExchange.connect()Lio/reactivex/Completable;
	at sample.playground.Main.main(Main.java:25)

java.lang.NoSuchMethodError... netty versions?

I'm just trying to get started with this project. I'm getting the error below, looks like a Netty versioning problem. The code is running inside the same project (& VM) as my regular xchange project. Are they incompatible?

Exception in thread "main" java.lang.NoSuchMethodError: io.netty.handler.ssl.SslContext.newClientContextInternal(Lio/netty/handler/ssl/SslProvider;[Ljava/security/cert/X509Certificate;Ljavax/net/ssl/TrustManagerFactory;[Ljava/security/cert/X509Certificate;Ljava/security/PrivateKey;Ljava/lang/String;Ljavax/net/ssl/KeyManagerFactory;Ljava/lang/Iterable;Lio/netty/handler/ssl/CipherSuiteFilter;Lio/netty/handler/ssl/ApplicationProtocolConfig;JJ)Lio/netty/handler/ssl/SslContext;

dependency on xchange 4.2.0

I'm trying out this project (4.2.3-SNAPSHOT) and have a dependency on the xchange project snapshot 4.2.1. This project however appears to required an older version of xchange (4.2.0) and so I'm getting a bunch of NoSuchMethodErrors. Has this problem been solved?

netty websocket reconnect stability discussion

A month ago I committed an automatic reconnect for the poloniex websocket #43. This seems to work and I'm glad to see it integrated in the Netty class #56. This reconnect solves a lot of problems and is in my opinion the correct behaviour for the subscription.

Now we're still facing some stability problems with the websocket that aren't solved by the fix above.

  1. The exchange drops the subscription on server side but doesn't inform us. (websocket stays open but no trades are sent)
  2. A connection interrupt doesn't close the Netty websocket and doesn't trigger the disconnected event.

My first idea was to enable tcp keepalive on the netty socket to recognize a connection lost, but this doesn't seem to solve the problem as described here: https://stackoverflow.com/questions/23238319/websockets-ping-pong-why-not-tcp-keepalive.

What I've learned is that we should use a custom ping pong but since poloniex doesn't provide such a functionality we have to use their own implementation. They solved this problem with heartbeats. @chuggol has also recognized this problem on gdax #66.

Poloniex API heartbeats:

In some markets, if there is no update for more than 1 second, a heartbeat message consisting of an empty argument list and the latest sequence number will be sent. These will go out once per second, but if there is no update for more than 60 seconds, the heartbeat interval will be reduced to 8 seconds until the next update.

What I ended up doing is to start a watcher thread that verifies that in the last 10 seconds at least a heartbeat or a trade/orderbook/... update was sent to verify that the websocket is still open. develop...firegnome:develop#files_bucket

When the thread recognizes that the connection is lost it does following:

  1. call the resubscribe function -> that will result in a connection timeout (I set the Netty websocket timeout to 10 seconds)
  2. With this ReadTimeout Netty will recognize the lost connection and trigger the disconnected event
  3. Now the reconnect/resubscribe procedure that was implemented in #43 will reestablish the connection.

I tested and improved this solution with the watcher thread and it really seems to work quite well and seems to solve the second problem. (I run the websocket 24/7) But so far I didn't create a pull request because it is in my opinion a really ugly fix that can't be easily adapted to other exchanges because its very specific.

I look forward to your opinions and advice on this problem!

Incorrect timestamp on BitFinex ticker

Timestamps on BitFinex ticker is incorrect. The API isn't returning a timestamp and is being given the current system time in BitfinexWebSocketTickerTransaction:35
float timestamp = System.currentTimeMillis(); //float!?

Later, this is being multiplied by 1000 in BitfinexAdaptors::238:
Date timestamp = DateUtils.fromMillisUtc((long) (bitfinexTicker.getTimestamp() * 1000L));

If XStream is expecting a "to the second" timestamp in it's adaptor then BitfinexWebSocketTickerTransaction should probably take that into account and / by 1000.

Happy to make a PR here - is there anything I should watch out for? E.g other routes that depend on this in millis.

Can't subscribe on ticker after unsubscription

Hi,
If subscribe on ticker for currency pair once, everthing will work fine, but if unsubscribe and try to subscribe again, nothing will happen.
I've tried to get ticker from Bitfinex in such way and after currency pair was unsubscribed and then was subscribed again there were no more tickers.
I guess it is bug in NettyStreamingService. For my point of view, there is wrong condition check at doOnDispose.

public Observable<T> subscribeChannel(String channelName, Object... args) {
        ...
       }).doOnDispose(() -> {
            if (!channels.containsKey(channelId)) {
                sendMessage(getUnsubscribeMessage(channelId));
                channels.remove(channelId);
            }
        }).share();
    }

What is supported not available via API

Feature Suggestion

There's a really helpful graphic of what StreamingExchanges support what features (Order Books, Trades, Tickers).

Exchange order books trades tickers
Binance ✔️
Bitfinex ✔️ ✔️ ✔️
Bitflyer ✔️ ✔️ ✔️
BitMEX ✔️ ✔️ ✔️
Bitstamp ✔️ ✔️
Coinmate ✔️ ✔️
OKCoin ✔️ ✔️ ✔️
OKEx ✔️ ✔️ ✔️
Poloniex ✔️ ✔️ ✔️
GDAX ✔️ ✔️ ✔️
Gemini ✔️ ✔️
Wex ✔️ ✔️

As a suggestion, the metadata for the exchange should include methods to inspect and return what is supported at runtime. That way, it can be coded that if support is added, things will 'just start working' if the code checks the metadata as opposed to hardcoding it based on a list on a wiki page.

Obviously low priority, but thought it would be helpful.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.