-
Notifications
You must be signed in to change notification settings - Fork 217
Gdax adding user channel #160
Changes from 4 commits
74f5c40
78808fb
50a77e6
beb0a9d
a280d61
54638bb
d361c85
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,18 @@ | ||
package info.bitrich.xchangestream.gdax; | ||
|
||
import java.io.IOException; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
import org.knowm.xchange.ExchangeSpecification; | ||
import org.knowm.xchange.gdax.dto.account.GDAXWebsocketAuthData; | ||
import org.knowm.xchange.gdax.service.GDAXAccountServiceRaw; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import com.fasterxml.jackson.databind.JsonNode; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
|
||
import info.bitrich.xchangestream.core.ProductSubscription; | ||
import info.bitrich.xchangestream.gdax.dto.GDAXWebSocketSubscriptionMessage; | ||
import info.bitrich.xchangestream.gdax.netty.WebSocketClientCompressionAllowClientNoContextHandler; | ||
|
@@ -11,12 +22,6 @@ | |
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker; | ||
import io.netty.handler.codec.http.websocketx.extensions.WebSocketClientExtensionHandler; | ||
import io.reactivex.Observable; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import java.io.IOException; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
public class GDAXStreamingService extends JsonNettyStreamingService { | ||
private static final Logger LOG = LoggerFactory.getLogger(GDAXStreamingService.class); | ||
|
@@ -25,11 +30,13 @@ public class GDAXStreamingService extends JsonNettyStreamingService { | |
private static final String SHARE_CHANNEL_NAME = "ALL"; | ||
private final Map<String, Observable<JsonNode>> subscriptions = new HashMap<>(); | ||
private ProductSubscription product = null; | ||
GDAXStreamingExchange exchange; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use private final |
||
|
||
private WebSocketClientHandler.WebSocketMessageHandler channelInactiveHandler = null; | ||
|
||
public GDAXStreamingService(String apiUrl) { | ||
public GDAXStreamingService(String apiUrl, GDAXStreamingExchange exchange) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not a big fan of cyclic class dependencies like this. There should contract "parent" <- "child" in this scenario. So if |
||
super(apiUrl, Integer.MAX_VALUE); | ||
this.exchange = exchange; | ||
} | ||
|
||
public ProductSubscription getProduct() { | ||
|
@@ -66,15 +73,27 @@ protected String getChannelNameFromMessage(JsonNode message) { | |
|
||
@Override | ||
public String getSubscribeMessage(String channelName, Object... args) throws IOException { | ||
GDAXWebSocketSubscriptionMessage subscribeMessage = new GDAXWebSocketSubscriptionMessage(SUBSCRIBE, product); | ||
ExchangeSpecification exchangeSpec = exchange.getExchangeSpecification(); | ||
GDAXWebsocketAuthData authData = null; | ||
if ( exchangeSpec.getApiKey() != null ) { | ||
GDAXAccountServiceRaw rawAccountService = (GDAXAccountServiceRaw) exchange.getAccountService(); | ||
authData = rawAccountService.getWebsocketAuthData(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would prefer not to include |
||
} | ||
GDAXWebSocketSubscriptionMessage subscribeMessage = new GDAXWebSocketSubscriptionMessage(SUBSCRIBE, product, authData); | ||
ObjectMapper objectMapper = new ObjectMapper(); | ||
return objectMapper.writeValueAsString(subscribeMessage); | ||
} | ||
|
||
@Override | ||
public String getUnsubscribeMessage(String channelName) throws IOException { | ||
ExchangeSpecification exchangeSpec = exchange.getExchangeSpecification(); | ||
GDAXWebsocketAuthData authData = null; | ||
if ( exchangeSpec.getApiKey() != null ) { | ||
GDAXAccountServiceRaw rawAccountService = (GDAXAccountServiceRaw) exchange.getAccountService(); | ||
authData = rawAccountService.getWebsocketAuthData(); | ||
} | ||
GDAXWebSocketSubscriptionMessage subscribeMessage = | ||
new GDAXWebSocketSubscriptionMessage(UNSUBSCRIBE, new String[]{"level2", "matches", "ticker"}); | ||
new GDAXWebSocketSubscriptionMessage(UNSUBSCRIBE, new String[]{"level2", "matches", "ticker"}, authData); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this unsubscribe message also include "user" if |
||
ObjectMapper objectMapper = new ObjectMapper(); | ||
return objectMapper.writeValueAsString(subscribeMessage); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm working on something similar for Binance right now, and this bit gave me pause. Are you getting duplicated trades appearing where you get both the
Trade
from thematches
channel and theUserTrade
from theuser
channel?I certainly do with Binance and it itched. The only way I could think of to resolve the issue looks something like this:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the code replaces the Trade object with a UserTrade object so there wouldn't be a duplicate.
Honestly in my usage (external to this project) I'm just looking for the fills coming in (UserTrade) so it never hurt my bot if there was or wasn't a Trade reported via the regular trade feed.
I suppose if the record came in via the trade feed with no user information there would be a duplicate.