/// <summary> /// Subscribe to wallet updates /// </summary> /// <param name="onOrderMarginUpdate">Data handler for order margin updates</param> /// <param name="onBalanceUpdate">Data handler for balance updates</param> /// <param name="onWithdrawableUpdate">Data handler for withdrawable funds updates</param> /// <returns>A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected and to unsubscribe</returns> public async Task <CallResult <UpdateSubscription> > SubscribeToBalanceUpdatesAsync( Action <DataEvent <KucoinStreamOrderMarginUpdate> > onOrderMarginUpdate, Action <DataEvent <KucoinStreamFuturesBalanceUpdate> > onBalanceUpdate, Action <DataEvent <KucoinStreamFuturesWithdrawableUpdate> > onWithdrawableUpdate) { var innerHandler = new Action <DataEvent <JToken> >(tokenData => { var subject = tokenData.Data["subject"]?.ToString(); if (subject == "orderMargin.change") { var data = GetData <KucoinStreamOrderMarginUpdate>(tokenData); InvokeHandler(tokenData.As(data, data.Currency), onOrderMarginUpdate); } else if (subject == "availableBalance.change") { var data = GetData <KucoinStreamFuturesBalanceUpdate>(tokenData); InvokeHandler(tokenData.As(data, data.Currency), onBalanceUpdate); } else if (subject == "withdrawHold.change") { var data = GetData <KucoinStreamFuturesWithdrawableUpdate>(tokenData); InvokeHandler(tokenData.As(data, data.Currency), onWithdrawableUpdate); } else { log.Write(LogLevel.Warning, "Unknown update: " + subject); } }); var request = new KucoinRequest(NextId().ToString(CultureInfo.InvariantCulture), "subscribe", $"/contractAccount/wallet", false); return(await SubscribeAsync("futures", request, null, true, innerHandler).ConfigureAwait(false)); }
/// <summary> /// Subscribe to full order book updates /// </summary> /// <param name="symbol">The symbol to subscribe</param> /// <param name="onData">Data handler</param> /// <returns>A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected and to unsubscribe</returns> public async Task <CallResult <UpdateSubscription> > SubscribeToOrderBookUpdatesAsync(string symbol, Action <DataEvent <KucoinFuturesOrderBookChange> > onData) { var innerHandler = new Action <DataEvent <JToken> >(tokenData => { var data = GetData <JToken>(tokenData); var change = data["change"]?.ToString(); var sequence = data["sequence"]?.ToString(); if (string.IsNullOrEmpty(change) || string.IsNullOrEmpty(sequence)) { return; } var items = change !.Split(','); var result = new KucoinFuturesOrderBookChange { Sequence = long.Parse(sequence), Price = decimal.Parse(items[0], CultureInfo.InvariantCulture), Side = items[1] == "sell" ? KucoinOrderSide.Sell: KucoinOrderSide.Buy, Quantity = decimal.Parse(items[2], CultureInfo.InvariantCulture) }; InvokeHandler(tokenData.As(result, symbol), onData); }); var request = new KucoinRequest(NextId().ToString(CultureInfo.InvariantCulture), "subscribe", $"/contractMarket/level2:" + symbol, false); return(await SubscribeAsync("futures", request, null, false, innerHandler).ConfigureAwait(false)); }
/// <summary> /// Subscribe to order updates for your own orders /// </summary> /// <param name="onOrderData">Data handler for order updates</param> /// <param name="onTradeData">Data handler for trade updates</param> /// <returns>A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected and to unsubscribe</returns> public async Task <CallResult <UpdateSubscription> > SubscribeToOrderUpdatesAsync(Action <KucoinStreamOrderBaseUpdate> onOrderData, Action <KucoinStreamOrderMatchUpdate> onTradeData) { var innerHandler = new Action <JToken>(tokenData => { var type = (string)tokenData["data"]["type"]; switch (type) { case "canceled": case "open": case "filled": case "update": var orderData = GetData <KucoinStreamOrderBaseUpdate>(tokenData); InvokeHandler(orderData, onOrderData !); break; case "match": var tradeData = GetData <KucoinStreamOrderMatchUpdate>(tokenData); InvokeHandler(tradeData, onTradeData !); break; } }); var request = new KucoinRequest(NextId().ToString(CultureInfo.InvariantCulture), "subscribe", "/spotMarket/tradeOrders", true); return(await Subscribe(request, null, true, innerHandler).ConfigureAwait(false)); }
/// <summary> /// Subscribe to ticker updates /// </summary> /// <param name="symbol">The symbol to subscribe on</param> /// <param name="onData">The data handler</param> /// <returns>A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected and to unsubscribe</returns> public async Task <CallResult <UpdateSubscription> > SubscribeToTickerUpdatesAsync(string symbol, Action <DataEvent <KucoinStreamFuturesTick> > onData) { var innerHandler = new Action <DataEvent <JToken> >(tokenData => { InvokeHandler(tokenData.As(GetData <KucoinStreamFuturesTick>(tokenData), symbol), onData); }); var request = new KucoinRequest(NextId().ToString(CultureInfo.InvariantCulture), "subscribe", "/contractMarket/tickerV2:" + symbol, false); return(await SubscribeAsync("futures", request, null, false, innerHandler).ConfigureAwait(false)); }
/// <summary> /// Subscribe to updates for stop orders /// </summary> /// <param name="onData">Data handler</param> /// <returns>A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected and to unsubscribe</returns> public async Task <CallResult <UpdateSubscription> > SubscribeToStopOrderUpdatesAsync(Action <KucoinStreamStopOrderUpdate> onData) { var innerHandler = new Action <JToken>(tokenData => { InvokeHandler(GetData <KucoinStreamStopOrderUpdate>(tokenData), onData); }); var request = new KucoinRequest(NextId().ToString(CultureInfo.InvariantCulture), "subscribe", $"/spotMarket/advancedOrders", true); return(await Subscribe(request, null, false, innerHandler).ConfigureAwait(false)); }
/// <summary> /// Subscribe to position updates /// </summary> /// <param name="symbol">Symbol</param> /// <param name="onData">Data handler</param> /// <returns>A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected and to unsubscribe</returns> public async Task <CallResult <UpdateSubscription> > SubscribeToPositionUpdatesAsync(string symbol, Action <DataEvent <KucoinPosition> > onData) { var innerHandler = new Action <DataEvent <JToken> >(tokenData => { var data = GetData <KucoinPosition>(tokenData); InvokeHandler(tokenData.As(data, symbol), onData); }); var request = new KucoinRequest(NextId().ToString(CultureInfo.InvariantCulture), "subscribe", $"/contract/position:" + symbol, false); return(await SubscribeAsync("futures", request, null, true, innerHandler).ConfigureAwait(false)); }
/// <summary> /// Subscribe to snapshot updates /// </summary> /// <param name="symbol">Symbol</param> /// <param name="onData">Data handler</param> /// <returns>A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected and to unsubscribe</returns> public async Task <CallResult <UpdateSubscription> > SubscribeTo24HourSnapshotUpdatesAsync(string symbol, Action <DataEvent <KucoinStreamTransactionStatisticsUpdate> > onData) { var innerHandler = new Action <DataEvent <JToken> >(tokenData => { var data = GetData <KucoinStreamTransactionStatisticsUpdate>(tokenData); InvokeHandler(tokenData.As(data, symbol), onData); }); var request = new KucoinRequest(NextId().ToString(CultureInfo.InvariantCulture), "subscribe", $"/contractMarket/snapshot:" + symbol, false); return(await SubscribeAsync("futures", request, null, false, innerHandler).ConfigureAwait(false)); }
/// <summary> /// Subscribe to stop order updates /// </summary> /// <param name="onData">Data handler</param> /// <returns>A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected and to unsubscribe</returns> public async Task <CallResult <UpdateSubscription> > SubscribeToStopOrderUpdatesAsync(Action <DataEvent <KucoinStreamStopOrderUpdateBase> > onData) { var innerHandler = new Action <DataEvent <JToken> >(tokenData => { var data = GetData <KucoinStreamFuturesStopOrderUpdate>(tokenData); InvokeHandler(tokenData.As((KucoinStreamStopOrderUpdateBase)data, data.Symbol), onData); }); var request = new KucoinRequest(NextId().ToString(CultureInfo.InvariantCulture), "subscribe", $"/contractMarket/advancedOrders", false); return(await SubscribeAsync("futures", request, null, true, innerHandler).ConfigureAwait(false)); }
/// <summary> /// Subscribe to updates for symbol or market snapshots /// </summary> /// <param name="symbolOrMarkets">The symbols (ie KCS-BTC) or markets (ie BTC) to subscribe on</param> /// <param name="onData">The data handler</param> /// <returns>A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected and to unsubscribe</returns> public async Task <CallResult <UpdateSubscription> > SubscribeToSnapshotUpdatesAsync( IEnumerable <string> symbolOrMarkets, Action <KucoinStreamSnapshot> onData) { var innerHandler = new Action <JToken>(tokenData => { InvokeHandler(GetData <KucoinStreamSnapshotWrapper>(tokenData)?.Data, onData !); }); var request = new KucoinRequest(NextId().ToString(CultureInfo.InvariantCulture), "subscribe", "/market/snapshot:" + string.Join(",", symbolOrMarkets), false); return(await Subscribe(request, null, false, innerHandler).ConfigureAwait(false)); }
/// <summary> /// Subscribe to updates for symbol snapshots /// </summary> /// <param name="symbol">The symbol to subscribe on</param> /// <param name="onData">The data handler</param> /// <returns>A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected and to unsubscribe</returns> public async Task <CallResult <UpdateSubscription> > SubscribeToSnapshotUpdatesAsync(string symbol, Action <KucoinStreamSnapshot> onData) { symbol.ValidateKucoinSymbol(); var innerHandler = new Action <JToken>(tokenData => { InvokeHandler(GetData <KucoinStreamSnapshotWrapper>(tokenData)?.Data, onData !); }); var request = new KucoinRequest(NextId().ToString(), "subscribe", "/market/snapshot:" + symbol, false); return(await Subscribe(request, null, false, innerHandler).ConfigureAwait(false)); }
/// <summary> /// Subscribe to kline updates /// </summary> /// <param name="symbol">Symbol to subscribe</param> /// <param name="interval">Interval of the klines</param> /// <param name="onData">Data handler</param> /// <returns>A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected and to unsubscribe</returns> public async Task <CallResult <UpdateSubscription> > SubscribeToKlineUpdatesAsync(string symbol, KucoinKlineInterval interval, Action <DataEvent <KucoinStreamCandle> > onData) { symbol.ValidateKucoinSymbol(); var innerHandler = new Action <DataEvent <JToken> >(tokenData => { InvokeHandler(tokenData.As(GetData <KucoinStreamCandle>(tokenData), symbol), onData); }); var request = new KucoinRequest(NextId().ToString(CultureInfo.InvariantCulture), "subscribe", $"/market/candles:{symbol}_{JsonConvert.SerializeObject(interval, new KlineIntervalConverter(false))}", false); return(await SubscribeAsync(request, null, false, innerHandler).ConfigureAwait(false)); }
/// <summary> /// Subscribe to trade updates /// </summary> /// <param name="symbol">The symbol to subscribe on</param> /// <param name="onData">The data handler</param> /// <returns>A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected and to unsubscribe</returns> public async Task <CallResult <UpdateSubscription> > SubscribeToTradeUpdatesAsync(string symbol, Action <DataEvent <KucoinStreamMatch> > onData) { symbol.ValidateKucoinSymbol(); var innerHandler = new Action <DataEvent <JToken> >(tokenData => { InvokeHandler(tokenData.As(GetData <KucoinStreamMatch>(tokenData), symbol), onData); }); var request = new KucoinRequest(NextId().ToString(CultureInfo.InvariantCulture), "subscribe", "/market/match:" + symbol, false); return(await SubscribeAsync(request, null, false, innerHandler).ConfigureAwait(false)); }
/// <summary> /// Subscribe system announcement /// </summary> /// <param name="onData">Data handler</param> /// <returns>A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected and to unsubscribe</returns> public async Task <CallResult <UpdateSubscription> > SubscribeToSystemAnnouncementsAsync(Action <DataEvent <KucoinContractAnnouncement> > onData) { var innerHandler = new Action <DataEvent <JToken> >(tokenData => { var data = GetData <KucoinContractAnnouncement>(tokenData); data.Event = tokenData.Data["subject"]?.ToString() ?? ""; InvokeHandler(tokenData.As(data), onData); }); var request = new KucoinRequest(NextId().ToString(CultureInfo.InvariantCulture), "subscribe", $"/contract/announcement", false); return(await SubscribeAsync("futures", request, null, false, innerHandler).ConfigureAwait(false)); }
/// <summary> /// Subscribe to partial order book updates /// </summary> /// <param name="symbol">The symbol to subscribe</param> /// <param name="limit">The amount of levels to receive, either 5 or 50</param> /// <param name="onData">Data handler</param> /// <returns>A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected and to unsubscribe</returns> public async Task <CallResult <UpdateSubscription> > SubscribeToPartialOrderBookUpdatesAsync(string symbol, int limit, Action <DataEvent <KucoinStreamOrderBookChanged> > onData) { limit.ValidateIntValues(nameof(limit), 5, 50); var innerHandler = new Action <DataEvent <JToken> >(tokenData => { var book = GetData <KucoinStreamOrderBookChanged>(tokenData); InvokeHandler(tokenData.As(book, symbol), onData); }); var request = new KucoinRequest(NextId().ToString(CultureInfo.InvariantCulture), "subscribe", $"/contractMarket/level2Depth{limit}:" + symbol, false); return(await SubscribeAsync("futures", request, null, false, innerHandler).ConfigureAwait(false)); }
/// <summary> /// Subscribe to funding book updates /// </summary> /// <param name="currencies">Currencies to subscribe</param> /// <param name="onData">Data handler</param> /// <returns>A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected and to unsubscribe</returns> public async Task <CallResult <UpdateSubscription> > SubscribeToFundingBookUpdatesAsync(IEnumerable <string> currencies, Action <DataEvent <KucoinStreamFundingBookUpdate> > onData) { foreach (var currency in currencies) { currency.ValidateNotNull(currency); } var innerHandler = new Action <DataEvent <JToken> >(tokenData => { var data = GetData <KucoinStreamFundingBookUpdate>(tokenData); InvokeHandler(tokenData.As(data, data.Currency), onData); }); var request = new KucoinRequest(NextId().ToString(CultureInfo.InvariantCulture), "subscribe", $"/margin/fundingBook:" + string.Join(",", currencies), false); return(await SubscribeAsync(request, null, false, innerHandler).ConfigureAwait(false)); }
/// <summary> /// Subscribe to mark price updates /// </summary> /// <param name="symbols">Currency to subscribe</param> /// <param name="onData">Data handler</param> /// <returns>A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected and to unsubscribe</returns> public async Task <CallResult <UpdateSubscription> > SubscribeToMarkPriceUpdatesAsync(IEnumerable <string> symbols, Action <DataEvent <KucoinStreamIndicatorPrice> > onData) { foreach (var symbol in symbols) { symbol.ValidateKucoinSymbol(); } var innerHandler = new Action <DataEvent <JToken> >(tokenData => { var data = GetData <KucoinStreamIndicatorPrice>(tokenData); InvokeHandler(tokenData.As(data, data.Symbol), onData); }); var request = new KucoinRequest(NextId().ToString(CultureInfo.InvariantCulture), "subscribe", $"/indicator/markPrice:" + string.Join(",", symbols), false); return(await SubscribeAsync(request, null, false, innerHandler).ConfigureAwait(false)); }
/// <summary> /// Subscribe to aggregated order book updates /// </summary> /// <param name="symbols">The symbols to subscribe on</param> /// <param name="onData">The data handler</param> /// <returns>A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected and to unsubscribe</returns> public async Task <CallResult <UpdateSubscription> > SubscribeToAggregatedOrderBookUpdatesAsync(IEnumerable <string> symbols, Action <KucoinStreamOrderBook> onData) { symbols.ValidateNotNull(nameof(symbols)); foreach (var symbol in symbols) { symbol.ValidateKucoinSymbol(); } var innerHandler = new Action <JToken>(tokenData => { InvokeHandler(GetData <KucoinStreamOrderBook>(tokenData), onData); }); var request = new KucoinRequest(NextId().ToString(), "subscribe", "/market/level2:" + string.Join(",", symbols), false); return(await Subscribe(request, null, false, innerHandler).ConfigureAwait(false)); }
/// <summary> /// Subscribe to full order book updates /// </summary> /// <param name="symbols">The symbols to subscribe</param> /// <param name="limit">The amount of levels to receive, either 5 or 50</param> /// <param name="onData">Data handler</param> /// <returns>A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected and to unsubscribe</returns> public async Task <CallResult <UpdateSubscription> > SubscribeToOrderBookUpdatesAsync(IEnumerable <string> symbols, int limit, Action <KucoinStreamOrderBookChanged> onData) { foreach (var symbol in symbols) { symbol.ValidateKucoinSymbol(); } limit.ValidateIntValues(nameof(limit), 5, 50); var innerHandler = new Action <JToken>(tokenData => { InvokeHandler(GetData <KucoinStreamOrderBookChanged>(tokenData), onData); }); var request = new KucoinRequest(NextId().ToString(CultureInfo.InvariantCulture), "subscribe", $"/spotMarket/level2Depth{limit}:" + string.Join(",", symbols), false); return(await Subscribe(request, null, false, innerHandler).ConfigureAwait(false)); }
/// <summary> /// <para>Subscribe to match engine updates for your own orders. There are different update types with classes derived from <see cref="KucoinStreamOrderBaseUpdate" /></para> /// <para><see cref="KucoinStreamOrderReceivedUpdate" />: A valid order is received by the matching engine</para> /// <para><see cref="KucoinStreamOrderOpenUpdate" />: A limit order is opened on the order book</para> /// <para><see cref="KucoinStreamOrderDoneUpdate" />: An order is no longer on the order book</para> /// <para><see cref="KucoinStreamOrderMatchUpdate" />: An order is matched with another order</para> /// <para><see cref="KucoinStreamOrderChangeUpdate" />: An order is changed (decreased) in size</para> /// </summary> /// <param name="symbols">The symbols to subscribe on</param> /// <param name="onData">The data handler</param> /// <returns>A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected and to unsubscribe</returns> public async Task <CallResult <UpdateSubscription> > SubscribeToOwnMatchEngineUpdatesAsync(IEnumerable <string> symbols, Action <KucoinStreamOrderBaseUpdate> onData) { symbols.ValidateNotNull(nameof(symbols)); foreach (var symbol in symbols) { symbol.ValidateKucoinSymbol(); } var innerHandler = new Action <JToken>(tokenData => { KucoinStreamOrderBaseUpdate?data = null; var subject = (string)tokenData["subject"]["data"]["type"]; var type = (string)tokenData["subject"]; switch (subject) { case "trade.l3received" when type == "stop" || type == "activate": data = GetData <KucoinStreamOrderStopUpdate>(tokenData); break; case "trade.l3received": data = GetData <KucoinStreamOrderReceivedUpdate>(tokenData); break; case "trade.l3open": data = GetData <KucoinStreamOrderOpenUpdate>(tokenData); break; case "trade.l3done": data = GetData <KucoinStreamOrderDoneUpdate>(tokenData); break; case "trade.l3match": data = GetData <KucoinStreamOrderMatchUpdate>(tokenData); break; case "trade.l3change": data = GetData <KucoinStreamOrderChangeUpdate>(tokenData); break; } InvokeHandler(data, onData !); }); var request = new KucoinRequest(NextId().ToString(), "subscribe", "/market/level3:" + string.Join(",", symbols), true); return(await Subscribe(request, null, true, innerHandler).ConfigureAwait(false)); }
/// <summary> /// <para>Subscribe to match engine updates. There are different update types with classes derived from <see cref="KucoinStreamOrderBaseUpdate" /></para> /// <para><see cref="KucoinStreamMatchEngineUpdate" />: A valid order is received by the matching engine</para> /// <para><see cref="KucoinStreamMatchEngineOpenUpdate" />: A limit order is opened on the order book</para> /// <para><see cref="KucoinStreamMatchEngineDoneUpdate" />: An order is no longer on the order book</para> /// <para><see cref="KucoinStreamMatchEngineMatchUpdate" />: An order is matched with another order</para> /// <para><see cref="KucoinStreamMatchEngineChangeUpdate" />: An order is changed (decreased) in size</para> /// </summary> /// <param name="symbols">The symbols to subscribe on</param> /// <param name="onData">The data handler</param> /// <returns>A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected and to unsubscribe</returns> public async Task <CallResult <UpdateSubscription> > SubscribeToMatchEngineUpdatesAsync(IEnumerable <string> symbols, Action <DataEvent <KucoinStreamMatchEngineUpdate> > onData) { symbols.ValidateNotNull(nameof(symbols)); foreach (var symbol in symbols) { symbol.ValidateKucoinSymbol(); } var innerHandler = new Action <DataEvent <JToken> >(tokenData => { KucoinStreamMatchEngineUpdate?data = null; var subject = tokenData.Data["subject"]?.ToString(); switch (subject) { case "received": data = GetData <KucoinStreamMatchEngineUpdate>(tokenData); break; case "open": data = GetData <KucoinStreamMatchEngineOpenUpdate>(tokenData); break; case "done": data = GetData <KucoinStreamMatchEngineDoneUpdate>(tokenData); break; case "match": data = GetData <KucoinStreamMatchEngineMatchUpdate>(tokenData); break; case "update": data = GetData <KucoinStreamMatchEngineChangeUpdate>(tokenData); break; default: log.Write(LogLevel.Warning, "Unknown match engine update type: " + subject); return; } InvokeHandler(tokenData.As <KucoinStreamMatchEngineUpdate>(data, data.Symbol), onData !); }); var request = new KucoinRequest(NextId().ToString(CultureInfo.InvariantCulture), "subscribe", "/spotMarket/level3:" + string.Join(",", symbols), false); return(await SubscribeAsync(request, null, false, innerHandler).ConfigureAwait(false)); }
/// <summary> /// Subscribe to balance updates /// </summary> /// <param name="onBalanceChange">The data handler</param> /// <returns>A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected and to unsubscribe</returns> public async Task <CallResult <UpdateSubscription> > SubscribeToBalanceChangesAsync(Action <KucoinBalanceUpdate> onBalanceChange) { var innerHandler = new Action <JToken>(data => { var desResult = Deserialize <KucoinUpdateMessage <KucoinBalanceUpdate> >(data, false); if (!desResult) { log.Write(LogVerbosity.Warning, "Failed to deserialize balance update: " + desResult.Error); return; } onBalanceChange(desResult.Data.Data); }); var request = new KucoinRequest(NextId().ToString(), "subscribe", "/account/balance", true); return(await Subscribe(request, null, true, innerHandler).ConfigureAwait(false)); }
/// <summary> /// Subscribe to updates for all symbol tickers /// </summary> /// <param name="onData">The data handler</param> /// <returns>A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected and to unsubscribe</returns> public async Task <CallResult <UpdateSubscription> > SubscribeToAllTickerUpdatesAsync(Action <KucoinStreamTick> onData) { var innerHandler = new Action <JToken>(tokenData => { var data = GetData <KucoinStreamTick>(tokenData); if (data == null) { return; } data.Symbol = (string)tokenData["subject"]; InvokeHandler(data, onData); }); var request = new KucoinRequest(NextId().ToString(), "subscribe", "/market/ticker:all", false); return(await Subscribe(request, null, false, innerHandler).ConfigureAwait(false)); }
/// <summary> /// Subscribe to updates for symbol or market snapshots /// </summary> /// <param name="symbolOrMarkets">The symbols (ie KCS-BTC) or markets (ie BTC) to subscribe on</param> /// <param name="onData">The data handler</param> /// <returns>A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected and to unsubscribe</returns> public async Task <CallResult <UpdateSubscription> > SubscribeToSnapshotUpdatesAsync( IEnumerable <string> symbolOrMarkets, Action <DataEvent <KucoinStreamSnapshot> > onData) { var innerHandler = new Action <DataEvent <JToken> >(tokenData => { var data = GetData <KucoinStreamSnapshotWrapper>(tokenData)?.Data; if (data == null) { log.Write(LogLevel.Warning, "Failed to process snapshot update"); return; } InvokeHandler(tokenData.As(data, data?.Symbol), onData !); }); var request = new KucoinRequest(NextId().ToString(CultureInfo.InvariantCulture), "subscribe", "/market/snapshot:" + string.Join(",", symbolOrMarkets), false); return(await SubscribeAsync(request, null, false, innerHandler).ConfigureAwait(false)); }
/// <summary> /// Subscribe to market data updates /// </summary> /// <param name="symbol">The symbol to subscribe</param> /// <param name="onMarkIndexPriceUpdate">Mark/Index price update handler</param> /// <param name="onFundingRateUpdate">Funding price update handler</param> /// <returns>A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected and to unsubscribe</returns> public async Task <CallResult <UpdateSubscription> > SubscribeToMarketUpdatesAsync(string symbol, Action <DataEvent <KucoinStreamFuturesMarkIndexPrice> > onMarkIndexPriceUpdate, Action <DataEvent <KucoinStreamFuturesFundingRate> > onFundingRateUpdate) { var innerHandler = new Action <DataEvent <JToken> >(tokenData => { if (tokenData.Data["subject"]?.ToString() == "mark.index.price") { var data = GetData <KucoinStreamFuturesMarkIndexPrice>(tokenData); InvokeHandler(tokenData.As(data, symbol), onMarkIndexPriceUpdate); } else { var data = GetData <KucoinStreamFuturesFundingRate>(tokenData); InvokeHandler(tokenData.As(data, symbol), onFundingRateUpdate); } }); var request = new KucoinRequest(NextId().ToString(CultureInfo.InvariantCulture), "subscribe", $"/contract/instrument:" + symbol, false); return(await SubscribeAsync("futures", request, null, false, innerHandler).ConfigureAwait(false)); }
/// <inheritdoc /> protected override async Task <bool> Unsubscribe(SocketConnection connection, SocketSubscription s) { var kRequest = (KucoinRequest)s.Request !; var request = new KucoinRequest(NextId().ToString(), "unsubscribe", kRequest.Topic, false); var success = false; await connection.SendAndWait(request, TimeSpan.FromSeconds(5), message => { var id = message["id"]; if (id == null) { return(false); } if ((string)id != kRequest.Id) { return(false); } var result = Deserialize <KucoinSubscribeResponse>(message, false); if (!result) { log.Write(LogVerbosity.Warning, "Failed to unsubscribe: " + result.Error); success = false; return(true); } if (result.Data.Type != "ack") { log.Write(LogVerbosity.Warning, "Failed to unsubscribe: " + new ServerError(result.Data.Code, result.Data.Data)); success = false; return(true); } success = true; return(true); }).ConfigureAwait(false); return(success); }
/// <summary> /// Subscribe to updates for a symbol ticker /// </summary> /// <param name="symbols">The symbols to subscribe to</param> /// <param name="onData">The data handler</param> /// <returns>A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected and to unsubscribe</returns> public async Task <CallResult <UpdateSubscription> > SubscribeToTickerUpdatesAsync(IEnumerable <string> symbols, Action <KucoinStreamTick> onData) { symbols.ValidateNotNull(nameof(symbols)); foreach (var symbol in symbols) { symbol.ValidateKucoinSymbol(); } var innerHandler = new Action <JToken>(tokenData => { var data = GetData <KucoinStreamTick>(tokenData); if (data == null) { return; } data.Symbol = ((string)tokenData["topic"]).Split(':').Last(); InvokeHandler(data, onData); }); var request = new KucoinRequest(NextId().ToString(), "subscribe", "/market/ticker:" + string.Join(",", symbols), false); return(await Subscribe(request, null, false, innerHandler).ConfigureAwait(false)); }
/// <summary> /// Subscribe to updates for a symbol ticker /// </summary> /// <param name="symbols">The symbols to subscribe to</param> /// <param name="onData">The data handler</param> /// <returns>A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected and to unsubscribe</returns> public async Task <CallResult <UpdateSubscription> > SubscribeToTickerUpdatesAsync(IEnumerable <string> symbols, Action <DataEvent <KucoinStreamTick> > onData) { symbols.ValidateNotNull(nameof(symbols)); foreach (var symbol in symbols) { symbol.ValidateKucoinSymbol(); } var innerHandler = new Action <DataEvent <JToken> >(tokenData => { var data = GetData <KucoinStreamTick>(tokenData); if (data == null) { return; } data.Symbol = TryGetSymbolFromTopic(tokenData) !; InvokeHandler(tokenData.As(data, data.Symbol), onData); }); var request = new KucoinRequest(NextId().ToString(CultureInfo.InvariantCulture), "subscribe", "/market/ticker:" + string.Join(",", symbols), false); return(await SubscribeAsync(request, null, false, innerHandler).ConfigureAwait(false)); }