-
Notifications
You must be signed in to change notification settings - Fork 217
[WORK IN PROGRESS] Generic authenticated stream API #274
Comments
One challenge I am working on is how to make sure that the streams arrive in order without any exchange-specific reconciliation logic. Relying on a websocket feed for updates of snapshot data is difficult and risky, and every exchange has a different approach (e.g. Binance always supplies timestamps). Any suggestions here obviously very welcome. |
@dozd, does this fit with the existing design? I'd like to know we have agreement before making much more progress. |
I like the general ideas from the approach. These points all make good sense, good work! |
…ned in bitrich-info#274. Coinbase Pro is a challenge here. It seems to need an initial snapshot. At the moment the implementation is bare-bones. Need to start working on the ordering challenge. All three seem to provide a sequence number. This will be essential for maintaining any sort of snapshot. Not done balances yet.
…ned in bitrich-info#274. Coinbase Pro is a challenge here. It seems to need an initial snapshot. At the moment the implementation is bare-bones. Need to start working on the ordering challenge. All three seem to provide a sequence number. This will be essential for maintaining any sort of snapshot. Not done balances yet.
Binance Level 2 support is now in! Just need Bitfinex support in and I'll publicise my fork where I'm building the Level 1 support on top (plus lots of additional L2 support...) |
…ned in bitrich-info#274. Coinbase Pro is a challenge here. It seems to need an initial snapshot. At the moment the implementation is bare-bones. Need to start working on the ordering challenge. All three seem to provide a sequence number. This will be essential for maintaining any sort of snapshot. Not done balances yet.
Bitfinex support now into |
I plan to make a release tomorrow (was busy on Tuesday). Should I wait or is it ok? |
The new L2 APIs aren't stable at the moment, but I don't think that's a good reason to delay resynchronization with XChange's release cycle. Do it :) |
Binance and Bitfinex balance updates now working. However, there is currently no ordering protection. That will arrive as I get Coinbase Pro working, which requires snapshot management to work at all. |
I think this is ready for a pull request. No changes to the level of functionality, but it is useful in its current state and I've been running it successfully in production for a couple of weeks now. I'll keep the branch open and keep working towards reliable streams. |
Updated OP to describe how the approach has evolved and clearly indicate current status. |
@badgerwithagun I have just started using the library, but this is something I'm very interested in having. I can help out with review or anything else if there's something specific you need help with (I have been using xchange for a many months with different exchanges, but only just stated with xchange-stream with Binance for start). |
@wlk thanks. I'll need a review when I publish the first PR. One thing I really need, for all three exchanges, is a clear guide for how to manage sequencing and dropped messages. They all publish instructions on this, in different levels of detail. What I'd like is to have the information in one place so I can start designing a common pattern which can then be re-used as more exchanges are added. It's a surprisingly difficult thing. |
I've been working on other stuff recently, but hope to focus back on this soon. The branch linked above is working really well for what it does, but without ordering/dropped message protection it's not safe to trust it, so I don't want to submit a PR yet. |
Hi @badgerwithagun, I would be happy to help you finishing this, I will take a look at the current code and think a potential solution for the order/dropped messages protection. Let me know if you want to have a chat about that. |
Please elaborate, @garciapd! The big problem I have found is that none of the exchanges I have been analysing implement any sort of dropped message protection. If I connect, then pull the internet cable, create an order then reconnect the internet, I can miss the message where the order was connected and get no clue that anything was missed. Some, like Binance, provide enough clues that you've missed a message when you receive a message following it, but none seem to.provide heartbeat messages which will tell you that you might have missed something in the meantime. |
Hi @badgerwithagun, I think there is no way to do that by just using their websocket API (Bitfinex), we could provide a listener that notifies when the websocket is connected and when is disconnected, then we could know when was the last time the websocket was disconnected and keep track of all the orders done while the websocket wasn't connected. When the websocket is connected again we can notify, and the user will know that from now he will start receiving updates. For the orders done while the websocket was disconnected, he will have to use the REST endpoints. I found that ticket of somebody asking that, maybe you find it helpful too ([https://github.com/bitfinexcom/bitfinex-api-node/issues/247]) What do you think about providing a listener and let the user to re-sync specific orders? |
Hi @badgerwithagun , I did some draft implementation as a proposal to deal with the order updates internally, the idea is to keep track of every order made, have them cached and when there isn't an update for a while we can trigger an update via REST. Do you think that could be a good way? |
@garciapd I was trying out similar ideas. It starts to get a bit messy though due to the possibility of race conditions between the REST call and any socket updates that might suddenly arrive while the call is occurring. These could result in us sending the older data last and the newer first. Binance has a solution for this in the form of a timestamp on all socket and REST responses which is coherent (see my branch badgerwithagun@1dd746c) but I can't extend this logic to all exchanges. |
Also, I have started to think that the |
I agree, this kind of solution will become messy and bring potential edge cases. I think is a good idea to change the name to |
@badgerwithagun what is missing then for the PR? |
Here's my thinking. I have already built a layer over the top of XChange and xchange-stream that combines polling with websockets as part of Orko. It's open source so anyone can copy it (see MarketDataSubscriptionManager ). This approach has the advantage that it always works, even for exchanges that don't have support in xchange-stream (by falling back to core XChange APIs). However, if websockets are available, it uses them to be able to respond quicker. I wanted to improve on this though. I wanted to eliminate REST polling. I am now starting to think it's not possible in a generic way without making xchange-stream too difficult to maintain. Binance is a dream come true (strangely!); it has all the right answers to these problems, but most other exchanges don't. I think we could probably work out a way around these problems on an exchange-by-exchange basis, by combining idle detection, polling and lots of other tricks, but my fear is that the result will just be too complicated. It'll get broken by a bad PR pretty quickly (it's really, really hard to review xchange-stream PRs well, since no-one uses the same combination of exchanges, and it's impossible to write good tests without "official" stubs). Anyone that tries to implement this new behaviour for additional exchanges will probably get it wrong somehow. You'll notice that At their hearts, both XChange and xchange-stream are pretty simple wrappers around the exchange APIs, and should probably stay that way. Easy to write, easy to review, but as a result, not "clever". All this is a long way of saying: maybe I've taken this as far as we should take it... LGTM. That means, remove these from the spec above:
And replace with:
Then LGTM. This may not be ideal, but it means that xchange-stream remains a relatively simple API around the exchange APIs which is easy for developers to extend, and not a complex beast like Orko's |
I share the thoughts, I think either XChange and XChange-stream should be easy to use and provide a simple API, clear, with no hidden tricks. Then each developer can use them the way they need. I think it is easier to know the limitations of the exchange rather than having to dive into the code to check the tricks that have been done to deal with the sync and out of order messages (as every exchange is different) It is nice to have smart libraries, but that could be done besides the "standard API", having like BitfinexStreamExchange and SmartBitfinexStreamExchange xD. I vote to do the replacement of the description :) Btw, nice work with Orko. I'm creating VirtuaBroker |
Nice!
OK, next time I get a spare moment, I'll see if I can get the existing code to line up with what we've discussed. It should be easy enough - only Coinbase will require any extra thought. |
I've been reading the Coinbase documentation and I can only confirm what you said hehe. In order to get all the information about the orders, they suggest to queue the messages coming from the stream and fill them with the REST endpoints. And there isn't initial snapshot. Maybe we could write an example (I can do it) about how to use the websocket and REST combined in case someone needs the full information of the orders. But we can leave the And the same to get a full snapshot of your orders before getting the deltas, the snapshot can be simply done by calling Of course it would be ideal if all of this logic was done by the library, but as we discussed before, it has implications, for instance making calls to the REST endpoint can get you throttled, and it slows down the updates, maybe you don't always need all the info. |
I've woken back up and am going to get this tidied up finally and a PR created shortly. |
Thank you for starting this update @badgerwithagun !!! I will implement the Coinmate exchange when you PR. |
No problem. I did a bit more work today. It's almost there :) |
Code I am now testing is opened as #340. |
Introduction
I intend to create
StreamingTradeService
andStreamingAccountService
interfaces to accompanyStreamingMarketDataService
, mirroring XChange's core APIs.These will deliver the following:
This has been a long time coming, but I'm now working on it. I'll will publish regular PRs to merge work into this repo as I go, status updates here, and fork URLs for anyone that wants to use the work in progress.
Please post here if you have thoughts on the API or implementation approach.
Approach
PRs #273 (formerly #209), #267, #246 and #244 all have taken different approaches to user-authenticated streams. I am trying to standardise these around the approach of #246 and #273 to follow on from #160, which is:
ExchangeSpecification
BinanceStreamingTradeService
will have agetExecutionReports()
method which returns instances of the execution report data structure in the binance API docs.PublishSubject
-like fashion. If you're subscribed to theObservable
, you get the data. If you're not, you don't. Nothing will be buffered.StreamingTradeService
andStreamingAccountService
interfaces and move the new methods fromStreamingMarketDataService
to bring the location of these methods in line with XChange.Therefore, to use the streams reliably, you should combine these streams with polling to make sure any local snapshots you create are re-synced regularly
API changes
The following new methods will be created:
StreamingTradeService
Observable<UserTrade> getUserTrades(CurrencyPair currencyPair, Object... args)
getTrades()
. This will be changed. If you needUserTrade
s mixed with yourTrade
s, justObservable.merge()
the two streams. This will be more flexible.StreamingTradeService
Observable<Order> getOrderUpdates(CurrencyPair currencyPair, Object... args)
CANCELED
) you should assume you'll get no more updates. A status ofNEW
will indicate acceptance and appearance on the order book andPENDING_NEW
will indicate receipt but not confirmation.StreamingAccountService
Observable<Balance> getBalanceUpdates(Currency currency, Object... args)
These will explicitly state that they do not guarantee delivery or sequence (see below for the discussion around this).
Status
Level 2 Support
Is already in the mainline.
Level 1 support
PR #340 has been issued but should be considered ready for merge. I'm conducting some production testing.
The text was updated successfully, but these errors were encountered: