/// <summary> /// Get candlesticks for a symbol. Candlesticks/K-Lines are uniquely identified by their open time. /// If startTime and endTime are not sent, the most recent candlesticks are returned. /// </summary> /// <param name="client"></param> /// <param name="symbol"></param> /// <param name="interval"></param> /// <param name="limit">Default 500; max 500.</param> /// <param name="startTime"></param> /// <param name="endTime"></param> /// <param name="token"></param> /// <returns></returns> public static async Task <string> GetCandlesticksAsync(this IKucoinHttpClient client, string symbol, CandlestickInterval interval, int limit = default, long startTime = default, long endTime = default, CancellationToken token = default) { Throw.IfNull(client, nameof(client)); Throw.IfNullOrWhiteSpace(symbol, nameof(symbol)); if (client.RateLimiter != null) { await client.RateLimiter.DelayAsync(token : token) .ConfigureAwait(false); } var request = new KucoinHttpRequest("/api/v1/klines"); request.AddParameter("symbol", symbol.FormatSymbol()); request.AddParameter("interval", interval.AsString()); if (limit > 0) { request.AddParameter("limit", limit); } if (startTime > 0) { request.AddParameter("startTime", startTime); } if (endTime > 0) { request.AddParameter("endTime", endTime); } return(await client.GetAsync(request, token) .ConfigureAwait(false)); }
/// <summary> /// Get candlesticks for a symbol. Candlesticks/K-Lines are uniquely identified by their open time. /// If startTime and endTime are not sent, the most recent candlesticks are returned. /// </summary> /// <param name="client"></param> /// <param name="symbol"></param> /// <param name="interval"></param> /// <param name="limit">Default 500; max 500.</param> /// <param name="startTime"></param> /// <param name="endTime"></param> /// <param name="token"></param> /// <returns></returns> public static Task <string> GetCandlesticksAsync(this IBinanceHttpClient client, string symbol, CandlestickInterval interval, int limit = default, long startTime = default, long endTime = default, CancellationToken token = default) { Throw.IfNull(client, nameof(client)); Throw.IfNullOrWhiteSpace(symbol, nameof(symbol)); var request = new BinanceHttpRequest("/api/v1/klines", 2); request.AddParameter("symbol", symbol.FormatSymbol()); request.AddParameter("interval", interval.AsString()); if (limit > 0) { request.AddParameter("limit", limit); } if (startTime > 0) { request.AddParameter("startTime", startTime); } if (endTime > 0) { request.AddParameter("endTime", endTime); } return(client.GetAsync(request, token)); }
public virtual void Subscribe(string symbol, CandlestickInterval interval, Action <CandlestickEventArgs> callback) { Throw.IfNullOrWhiteSpace(symbol, nameof(symbol)); Symbol = symbol.FormatSymbol(); SubscribeTo($"{Symbol.ToLowerInvariant()}@kline_{interval.AsString()}", callback); }
private async Task SubscribeToCandlestick(string symbol, CandlestickInterval interval) { var key = GetKey(symbol, interval); if (_candlestickSubscribers.ContainsKey(key)) { return; } try { var subscriber = new CandlestickSubscriber() { Symbol = symbol, Interval = interval }; try { await _candlestickSemaphore.WaitAsync(); if (_candlestickSubscribers.ContainsKey(key)) { return; } _log.LogInformation($"Subscribe to candlestick {symbol} {interval.AsString()}"); _candlestickSubscribers[key] = subscriber; subscriber.TokenSource = new CancellationTokenSource(); subscriber.CandlestickWebSocketClient = _serviceProvider.GetService <ICandlestickWebSocketClient>(); subscriber.SubscribeTask = subscriber.CandlestickWebSocketClient.SubscribeAsync(symbol, interval, _onCandlestickUpdate, subscriber.TokenSource.Token); CandlestickDisconnectionTimerInitialize(subscriber); } finally { _candlestickSemaphore.Release(); } await subscriber.SubscribeTask; RemoveSubscriber(symbol, interval); } catch (Exception) { OnCandlesticDisconnect(symbol, interval, true); RemoveSubscriber(symbol, interval); } }
public virtual Task SubscribeAsync(Symbol symbol, CandlestickInterval interval, Action <CandlestickEventArgs> callback, CancellationToken token) { Throw.IfNullOrWhiteSpace(symbol, nameof(symbol)); if (!token.CanBeCanceled) { throw new ArgumentException("Token must be capable of being in the canceled state.", nameof(token)); } token.ThrowIfCancellationRequested(); return(SubscribeToAsync($"{symbol.ToLower()}@kline_{interval.AsString()}", symbol, callback, token)); }
private void OnCandlesticDisconnect(string symbol, CandlestickInterval interval, bool error = false) { var key = GetKey(symbol, interval); if (_candlestickSubscribers.ContainsKey(key)) { var subscriber = _candlestickSubscribers[key]; subscriber.TokenSource?.Cancel(); } var logMessage = error ? "Error with candlestick websocket" : "Candlestick websocket disconnected"; _log.LogInformation($"{logMessage} {symbol} {interval.AsString()}. Cache will be cleared"); _onCandlestickErrorOrDisconnect(symbol, interval); }
/// <summary> /// Get candlesticks for a symbol. Candlesticks/K-Lines are uniquely identified by their open time. /// If startTime and endTime are not sent, the most recent candlesticks are returned. /// </summary> /// <param name="client"></param> /// <param name="symbol"></param> /// <param name="interval"></param> /// <param name="limit">Default 500; max 500.</param> /// <param name="startTime"></param> /// <param name="endTime"></param> /// <param name="token"></param> /// <returns></returns> public static async Task <string> GetCandlesticksAsync(this IBinanceHttpClient client, string symbol, CandlestickInterval interval, int limit = default, DateTime startTime = default, DateTime endTime = default, CancellationToken token = default) { Throw.IfNull(client, nameof(client)); Throw.IfNullOrWhiteSpace(symbol, nameof(symbol)); if (client.RateLimiter != null) { await client.RateLimiter.DelayAsync(token : token) .ConfigureAwait(false); } var request = new BinanceHttpRequest("/api/v1/klines"); request.AddParameter("symbol", symbol.FormatSymbol()); request.AddParameter("interval", interval.AsString()); if (limit > 0) { request.AddParameter("limit", limit); } if (startTime != default) { if (startTime.Kind != DateTimeKind.Utc) { throw new ArgumentException("Date/Time must be UTC.", nameof(startTime)); } request.AddParameter("startTime", startTime.ToTimestamp()); } // ReSharper disable once InvertIf if (endTime != default) { if (endTime.Kind != DateTimeKind.Utc) { throw new ArgumentException("Date/Time must be UTC.", nameof(endTime)); } request.AddParameter("endTime", endTime.ToTimestamp()); } return(await client.GetAsync(request, token) .ConfigureAwait(false)); }
private void RemoveSubscriber(string symbol, CandlestickInterval interval) { var key = GetKey(symbol, interval); if (_candlestickSubscribers.ContainsKey(key)) { var subscriber = _candlestickSubscribers[key]; subscriber.CandlestickDisconnectionTimer?.Dispose(); subscriber.TokenSource?.Dispose(); } CandlestickSubscriber removedSubscriber = null; if (_candlestickSubscribers.TryRemove(key, out removedSubscriber)) { _log.LogInformation($"subscriber removed for {symbol} {interval.AsString()}"); } }
public virtual Task SubscribeAsync(string symbol, CandlestickInterval interval, Action <CandlestickEventArgs> callback, CancellationToken token) { Throw.IfNullOrWhiteSpace(symbol, nameof(symbol)); if (!token.CanBeCanceled) { throw new ArgumentException("Token must be capable of being in the canceled state.", nameof(token)); } token.ThrowIfCancellationRequested(); Symbol = symbol.FormatSymbol(); if (IsSubscribed) { throw new InvalidOperationException($"{nameof(CandlestickWebSocketClient)} is already subscribed to symbol: \"{symbol}\""); } return(SubscribeToAsync($"{Symbol.ToLower()}@kline_{interval.AsString()}", callback, token)); }
public async Task Candlestick(string symbol, CandlestickInterval interval, Action <CandlestickEventArgs> onUpdate, Action <string, CandlestickInterval> onError) { if (_candlestickSubscribers == null || !_candlestickSubscribers.ContainsKey($"{symbol}{interval.AsString()}")) { _onCandlestickUpdate = onUpdate ?? throw new ArgumentException(nameof(onUpdate)); _onCandlestickError = onError ?? throw new ArgumentException(nameof(onError)); if (_candlestickSubscribers == null) { _candlestickSubscribers = new ConcurrentDictionary <string, CandlestickSubscriber>(); } await SubscribeToCandlestick(symbol, interval); } }
public void SetCandlestick(string symbol, CandlestickInterval interval, ImmutableList <Candlestick> candlesticks) { _memoryCache.Set($"{symbol}{SYMBOL_CANDLESTICK}{interval.AsString()}", candlesticks, TimeSpan.FromMinutes(CACHE_TIME_IN_MINUTES)); }
public virtual ICandlestickClient Unsubscribe(string symbol, CandlestickInterval interval, Action <CandlestickEventArgs> callback) { Throw.IfNullOrWhiteSpace(symbol, nameof(symbol)); symbol = symbol.FormatSymbol(); Logger?.LogDebug($"{nameof(CandlestickClient)}.{nameof(Unsubscribe)}: \"{symbol}\" \"{interval.AsString()}\" (callback: {(callback == null ? "no" : "yes")}). [thread: {Thread.CurrentThread.ManagedThreadId}]"); UnsubscribeStream(GetStreamName(symbol, interval), callback); return(this); }
private async Task SubscribeToCandlestick(string symbol, CandlestickInterval interval, bool reConnect = false) { _log.LogInformation($"Subscribe to candlestick {symbol} {interval.AsString()}"); var key = GetKey(symbol, interval); if (_candlestickSubscribers.ContainsKey(key) && !reConnect) { return; } try { CandlestickSubscriber subscriber = _candlestickSubscribers.ContainsKey(key) ? _candlestickSubscribers[key] : null; if (subscriber != null) { subscriber.TokenSource.Cancel(); subscriber.TokenSource.Dispose(); } else { subscriber = new CandlestickSubscriber() { Symbol = symbol, Interval = interval }; CandlestickReConnectionTimerInitialize(subscriber); _candlestickSubscribers[key] = subscriber; } subscriber.TokenSource = new CancellationTokenSource(); subscriber.CandlestickWebSocketClient = _serviceProvider.GetService <ICandlestickWebSocketClient>(); subscriber.SubscribeTask = subscriber.CandlestickWebSocketClient.SubscribeAsync(symbol, interval, _onCandlestickUpdate, subscriber.TokenSource.Token); await subscriber.SubscribeTask; } catch (Exception ex) { if (_candlestickSubscribers.ContainsKey(key)) { var subscriber = _candlestickSubscribers[key]; subscriber.CandlestickReConnectionTimer?.Dispose(); subscriber.TokenSource?.Dispose(); CandlestickSubscriber removedSubscriber = null; if (_candlestickSubscribers.TryRemove(key, out removedSubscriber)) { _log.LogInformation($"subscriber removed for {symbol} {interval.AsString()}"); } } _log.LogError($"Error with candlestick websocket {ex.Message}", ex); _onCandlestickError?.Invoke(symbol, interval); } }
/// <summary> /// Convert symbol and <see cref="CandlestickInterval"/> to stream name. /// </summary> /// <param name="symbol"></param> /// <param name="interval"></param> /// <returns></returns> public static string GetStreamName(string symbol, CandlestickInterval interval) { Throw.IfNullOrEmpty(symbol, nameof(symbol)); return($"{symbol.ToLowerInvariant()}@kline_{interval.AsString()}"); }
private static string GetStreamName(string symbol, CandlestickInterval interval) => $"{symbol.ToLowerInvariant()}@kline_{interval.AsString()}";
private static string GetKey(string symbol, CandlestickInterval interval) { return($"{symbol}{interval.AsString()}"); }
public void ClearCandlestick(string symbol, CandlestickInterval interval) { _memoryCache.Remove($"{symbol}{SYMBOL_CANDLESTICK}{interval.AsString()}"); }
public ImmutableList <Candlestick> GetCandlesticks(string symbol, CandlestickInterval interval) { return(_memoryCache.Get <ImmutableList <Candlestick> >($"{symbol}{SYMBOL_CANDLESTICK}{interval.AsString()}")); }