public SymbolCodeEnum Convert(SymbolCodeEnum baseSymbolCode, ExchangeStatsKeyEnum statsKey) { string convertedSymbolCode = null; switch (statsKey) { case ExchangeStatsKeyEnum.OpenLongs: convertedSymbolCode = baseSymbolCode.ToString() + "LONGS"; break; case ExchangeStatsKeyEnum.OpenShorts: convertedSymbolCode = baseSymbolCode.ToString() + "SHORTS"; break; default: throw new ArgumentException($"Unsupported stats key: {statsKey}"); } if (convertedSymbolCode == null) { throw new ArgumentException($"Unable to convert {baseSymbolCode} {statsKey}"); } return((SymbolCodeEnum)Enum.Parse(typeof(SymbolCodeEnum), convertedSymbolCode)); }
private void AggregateTradeStats(ISymbol baseSymbol, ExchangeStatsKeyEnum statsKey, int processLimit) => Task.Run(async() => { var fullSymbolCode = ExchangeTradeStatProvider.Convert(baseSymbol.Code, statsKey); var logger = LoggerFactory.CreateLogger($"Historian.{Exchange.Name}.{fullSymbolCode}.Worker.TradeStatAggregate"); using (logger.BeginExchangeScope(Exchange.Name)) { using (logger.BeginSymbolScope(fullSymbolCode)) { using (logger.BeginExchangeStatsScope(statsKey)) { var tradeStatId = (await HistorianRepository.GetLastTradeStatId(Exchange.Name, fullSymbolCode)).GetValueOrDefault(0); while (true) { try { var s = DateTime.Now; var tradeStats = await MarketRepository.GetNextTradeStats(Exchange.Name, baseSymbol.Code, statsKey, tradeStatId, processLimit); if (tradeStats.Count > 0) { using (var transaction = await StorageTransactionFactory.Begin()) { await MarketRepository.SaveTradeStatAggregates(transaction, Exchange.Name, fullSymbolCode, tradeStats); tradeStatId = tradeStats.Max(t => t.TradeStatId); await HistorianRepository.SetLastTradeStatId(transaction, Exchange.Name, fullSymbolCode, tradeStatId); await transaction.Commit(); } var e = DateTime.Now; logger.LogInformation($"Aggregation up to trade stat id {tradeStatId} took {(e.Subtract(s).TotalMilliseconds)}ms."); } await Task.Delay(5); } catch (Exception ex) { logger.LogCritical(ex, "Aggregation failed."); await Task.Delay(250); } } } } } });
private async Task ReceiveTradeStatsHttp(ISymbol symbol, ExchangeStatsKeyEnum statsKey) { Logger.LogInformation("Requesting stats"); var response = await HttpClient.GetStats(symbol, statsKey); var tradeStats = response.Data; if (response.StatusCode != WrappedResponseStatusCode.Ok) { var errorCode = !string.IsNullOrEmpty(response.ErrorCode) ? $"Error Code: {response.ErrorCode} Message: " : ""; Logger.LogWarning($"Unable to get stats: {errorCode}{response.ErrorMessage}"); return; } if (tradeStats.Count > 0) { try { var marketTradeStats = tradeStats.Select(s => new MarketTradeStat { Exchange = Exchange.Name, SymbolCode = symbol.Code, Epoch = s.Epoch, StatKey = s.StatKey, Value = s.Value }).OrderBy(t => t.Epoch.TimestampMilliseconds).ToList(); using (var transaction = await StorageTransactionFactory.Begin()) { await MarketRepository.SaveTradeStats(transaction, marketTradeStats); await transaction.Commit(); } } catch (Exception ex) { Logger.LogError(ex, "Unable to save trade stats."); } } }
public Task <WrappedResponse <ICollection <ExchangeStats> > > GetStats(ISymbol symbol, ExchangeStatsKeyEnum statsKey) { throw new NotImplementedException(); }
public async Task <ICollection <MarketTradeStat> > GetNextTradeStats(ExchangeEnum exchange, SymbolCodeEnum symbolCode, ExchangeStatsKeyEnum statKey, long tradeStatId, int limit = 1) { using (var context = ContextFactory.CreateDbContext(null)) { var tradeStats = context.ExchangeTradeStat .Where(t => t.ExchangeId == (int)exchange && t.SymbolId == (int)symbolCode && t.StatKeyId == (int)statKey && t.TradeStatId > tradeStatId) .OrderBy(t => t.TradeStatId) .Take(limit) .Select(t => new { Exchange = exchange, SymbolCode = symbolCode, StatKey = statKey, Timestamp = t.Timestamp, TradeStatId = (long)t.TradeStatId, Value = t.Value }); var raw = await tradeStats.ToListAsync(); return(raw.Select(t => new MarketTradeStat { Exchange = t.Exchange, SymbolCode = t.SymbolCode, StatKey = t.StatKey, Epoch = Epoch.FromMilliseconds(t.Timestamp), TradeStatId = t.TradeStatId, Value = t.Value }).ToList()); } }
public async Task <WrappedResponse <ICollection <ExchangeStats> > > GetStats(ISymbol symbol, ExchangeStatsKeyEnum statsKey) { var relativeUrl = $"v2/stats1/pos.size:1m:t{Exchange.GetCurrencyCode(symbol.BaseCurrencyCode)}{Exchange.GetCurrencyCode(symbol.QuoteCurrencyCode)}:{(statsKey == ExchangeStatsKeyEnum.OpenLongs ? "long" : "short")}/hist"; var additionalData = new NameValueCollection(); additionalData.Add("StatKey", statsKey.ToString()); additionalData.Add("SymbolCode", symbol.Code.ToString()); return(await InternalRequest <List <BitfinexMarketStats>, ICollection <ExchangeStats> >(false, relativeUrl, HttpMethod.Get, null, additionalData)); }
public static IDisposable BeginExchangeStatsScope(this ILogger logger, ExchangeStatsKeyEnum statsKey) { return(logger.BeginScope(new { StatsKey = statsKey })); }