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)); }
public Symbol(SymbolCodeEnum code, CurrencyCodeEnum baseCurrencyCode, CurrencyCodeEnum quoteCurrencyCode, bool tradable) { Code = code; BaseCurrencyCode = baseCurrencyCode; QuoteCurrencyCode = quoteCurrencyCode; Tradable = tradable; }
public ISymbol Get(SymbolCodeEnum symbolCode) { var matched = Symbols.Where(s => s.Code == symbolCode).FirstOrDefault(); if (matched == null) { throw new ArgumentException($"No symbol could be found for symbol '{symbolCode}'"); } return(matched); }
public async Task <ICollection <MacdDataPoint> > Macd(ExchangeEnum exchange, SymbolCodeEnum symbolCode, IntervalKey intervalKey, Epoch from, int dataPoints, CandleTypeEnum candleType, int fastEmaPeriod, int slowEmaPeriod, int signalPeriod) { var periodOffset = (slowEmaPeriod + signalPeriod) - 2; var fromOffset = IntervalFactory.GetInterval(intervalKey, from, periodOffset * -1); var aggValues = await MarketRepository.GetTradeAggregates(exchange, symbolCode, intervalKey, fromOffset.From, periodOffset + dataPoints); var values = aggValues.GetValues(candleType); int outBegIdx, outNbElement; var macdValues = new double[dataPoints]; var signalValues = new double[dataPoints]; var histogramValues = new double[dataPoints]; var retCode = TicTacTec.TA.Library.Core.Macd(0, values.Length - 1, values, fastEmaPeriod, slowEmaPeriod, signalPeriod, out outBegIdx, out outNbElement, macdValues, signalValues, histogramValues); var validMacdValues = macdValues.Skip(outNbElement - dataPoints).Take(dataPoints).ToArray(); var validSignalValues = signalValues.Skip(outNbElement - dataPoints).Take(dataPoints).ToArray(); var validHistogramValues = histogramValues.Skip(outNbElement - dataPoints).Take(dataPoints).ToArray(); var validAggValues = aggValues.Skip(aggValues.Count - dataPoints).Take(dataPoints).ToArray(); if (retCode == RetCode.Success) { var dp = new List <MacdDataPoint>(); for (var i = 0; i < validAggValues.Length; i++) { var agg = validAggValues[i]; dp.Add(new MacdDataPoint { Epoch = agg.Epoch, Macd = validMacdValues[i], Signal = validSignalValues[i], Histogram = validHistogramValues[i] }); } return(dp); } throw new Exception("Unable to calculate MACD - " + retCode); }
public async Task AddSymbol(ExchangeEnum exchange, SymbolCodeEnum symbolCode) { using (var context = ContextFactory.CreateDbContext(null)) { var entity = new ExchangeSymbolEntity { ExchangeId = (int)exchange, SymbolId = (int)symbolCode }; if (await context.ExchangeSymbol.FindAsync(entity.ExchangeId, entity.SymbolId) == null) { await context.ExchangeSymbol.AddAsync(entity); await context.SaveChangesAsync(); } } }
public async Task <ICollection <RsiDataPoint> > Rsi(ExchangeEnum exchange, SymbolCodeEnum symbolCode, IntervalKey intervalKey, Epoch from, int dataPoints, CandleTypeEnum candleType, int rsiPeriod) { var fromOffset = IntervalFactory.GetInterval(intervalKey, from, rsiPeriod * -1); var aggValues = await MarketRepository.GetTradeAggregates(exchange, symbolCode, intervalKey, fromOffset.From, rsiPeriod + dataPoints); var values = aggValues.GetValues(candleType); int outBegIdx, outNbElement; var rsiValues = new double[dataPoints]; var retCode = TicTacTec.TA.Library.Core.Rsi(0, values.Length - 1, values, rsiPeriod, out outBegIdx, out outNbElement, rsiValues); var validRsiValues = rsiValues.Skip(outNbElement - dataPoints).Take(dataPoints).ToArray(); var validAggValues = aggValues.Skip(aggValues.Count - dataPoints).Take(dataPoints).ToArray(); if (retCode == RetCode.Success) { var dp = new List <RsiDataPoint>(); for (var i = 0; i < validAggValues.Length; i++) { var agg = validAggValues[i]; dp.Add(new RsiDataPoint { Epoch = agg.Epoch, Rsi = validRsiValues[i] }); } return(dp); } throw new Exception("Unable to calculate RSI - " + retCode); }
public async Task <PagedCollection <MarketTrade> > GetTrades(ExchangeEnum exchange, SymbolCodeEnum symbolCode, Epoch from, Epoch to, int?pageSize, int?pageNumber) { using (var context = ContextFactory.CreateDbContext(null)) { var query = from t in context.ExchangeTrade where t.ExchangeId == (int)exchange && t.SymbolId == (int)symbolCode && t.Timestamp >= @from.TimestampMilliseconds && t.Timestamp <= to.TimestampMilliseconds select new { Exchange = exchange, SymbolCode = symbolCode, Timestamp = t.Timestamp, TradeId = t.TradeId, Side = t.OrderSideId.HasValue ? (OrderSideEnum)t.OrderSideId : (OrderSideEnum?)null, Price = t.Price, Volume = t.Volume }; var totalCount = 0; if (pageSize.HasValue) { totalCount = await query.CountAsync(); query = query.Skip(pageNumber.GetValueOrDefault(0) * pageSize.Value).Take(pageSize.Value); } var trades = await query.ToListAsync(); return(new PagedCollection <MarketTrade>() { PageNumber = pageNumber.GetValueOrDefault(0), PageSize = pageSize.GetValueOrDefault(0), ItemCount = pageSize.HasValue ? totalCount : trades.Count, Items = trades.Select(t => new MarketTrade { Exchange = t.Exchange, SymbolCode = t.SymbolCode, Epoch = Epoch.FromMilliseconds(t.Timestamp), TradeId = t.TradeId, Side = t.Side, Price = t.Price, Volume = t.Volume }).ToList() }); } }
public async Task <MarketTick> GetTick(ExchangeEnum exchange, SymbolCodeEnum symbolCode, Epoch at) { using (var context = ContextFactory.CreateDbContext(null)) { var minAt = at.AddSeconds((int)TimeSpan.FromDays(-1).TotalSeconds); var buyTradeQuery = from t in context.ExchangeTrade where t.ExchangeId == (int)exchange && t.SymbolId == (int)symbolCode && t.Timestamp >= minAt.TimestampMilliseconds && t.Timestamp <= at.TimestampMilliseconds && t.OrderSideId == (int)OrderSideEnum.Buy orderby t.ExchangeId, t.SymbolId, t.Timestamp descending select t; var buyTrade = await buyTradeQuery.FirstOrDefaultAsync(); var sellTradeQuery = from t in context.ExchangeTrade where t.ExchangeId == (int)exchange && t.SymbolId == (int)symbolCode && t.Timestamp >= minAt.TimestampMilliseconds && t.Timestamp <= at.TimestampMilliseconds && t.OrderSideId == (int)OrderSideEnum.Sell orderby t.ExchangeId, t.SymbolId, t.Timestamp descending select t; var sellTrade = await sellTradeQuery.FirstOrDefaultAsync(); ExchangeTradeEntity lastTrade = null; if (buyTrade != null && sellTrade != null) { lastTrade = buyTrade.Timestamp <= sellTrade.Timestamp ? buyTrade : sellTrade; } else { var lastTradeQuery = from t in context.ExchangeTrade where t.ExchangeId == (int)exchange && t.SymbolId == (int)symbolCode && t.Timestamp >= minAt.TimestampMilliseconds && t.Timestamp <= at.TimestampMilliseconds orderby t.ExchangeId, t.SymbolId, t.Timestamp descending select t; lastTrade = await lastTradeQuery.FirstOrDefaultAsync(); } if (lastTrade == null) { return(null); } return(new MarketTick { Exchange = exchange, SymbolCode = symbolCode, Epoch = at, BuyPrice = buyTrade != null ? buyTrade.Price : lastTrade.Price, SellPrice = sellTrade != null ? sellTrade.Price : lastTrade.Price, LastPrice = lastTrade.Price }); } }
public async Task SaveTradeStatAggregates(IStorageTransaction transaction, ExchangeEnum exchange, SymbolCodeEnum symbolCode, ICollection <MarketTradeStat> tradeStats) { var min = tradeStats.Min(t => t.Epoch); var max = tradeStats.Max(t => t.Epoch); var expanded = new List <TradeStatCartesian>(); foreach (var group in IntervalFactory.ListGroups()) { foreach (var ik in IntervalFactory.ListIntervalKeys(group.IntervalGroup)) { foreach (var tradeStat in tradeStats) { var period = IntervalFactory.GenerateIntervals(ik, tradeStat.Epoch, tradeStat.Epoch).FirstOrDefault(); expanded.Add(new TradeStatCartesian { IntervalKey = period.IntervalKey, IntervalEpoch = period.From, Exchange = tradeStat.Exchange, SymbolCode = symbolCode, StatKey = tradeStat.StatKey, Epoch = tradeStat.Epoch, Value = tradeStat.Value }); } } } using (var context = ContextFactory.CreateDbContext(null)) { using (var cmd = context.Database.GetDbConnection().CreateCommand()) { var sql = @"insert into `exchange_trade_aggregate` (`exchange_id`, `symbol_id`, `interval_key`, `timestamp`, `open`, `open_timestamp`, `high`, `low`, `close`, `close_timestamp`, `total_count`) values "; sql += string.Join(",\r\n", expanded.Select(t => $"(" + $"{(int)t.Exchange}," + $"{(int)t.SymbolCode}," + $"'{t.IntervalKey.Key}'," + $"{t.IntervalEpoch.TimestampMilliseconds}," + $"{t.Value}," + $"{t.Epoch.TimestampMilliseconds}," + $"{t.Value}," + $"{t.Value}," + $"{t.Value}," + $"{t.Epoch.TimestampMilliseconds}," + $"1)")); sql += @" on duplicate key update `open` = case when values(`open_timestamp`) < `open_timestamp` then values(`open`) else `open` end, `open_timestamp` = case when values(`open_timestamp`) < `open_timestamp` then values(`open_timestamp`) else `open_timestamp` end, `high` = case when values(`high`) > `high` then values(`high`) else `high` end, `low` = case when values(`low`) < `low` then values(`low`) else `low` end, `close` = case when values(`close_timestamp`) > `close_timestamp` then values(`close`) else `close` end, `close_timestamp` = case when values(`close_timestamp`) > `close_timestamp` then values(`close_timestamp`) else `close_timestamp` end, `total_count` = `total_count` + values(`total_count`)" ; cmd.CommandText = sql; await cmd.Connection.OpenAsync(); await cmd.ExecuteNonQueryAsync(); cmd.Connection.Close(); } } }
public async Task SaveTradeAggregates(IStorageTransaction transaction, ExchangeEnum exchange, SymbolCodeEnum symbolCode, ICollection <MarketTrade> trades) { var min = trades.Min(t => t.Epoch); var max = trades.Max(t => t.Epoch); var expanded = new List <TradeCartesian>(); foreach (var group in IntervalFactory.ListGroups()) { foreach (var ik in IntervalFactory.ListIntervalKeys(group.IntervalGroup)) { foreach (var trade in trades) { var period = IntervalFactory.GenerateIntervals(ik, trade.Epoch, trade.Epoch).FirstOrDefault(); expanded.Add(new TradeCartesian { IntervalKey = period.IntervalKey, IntervalEpoch = period.From, Exchange = trade.Exchange, SymbolCode = trade.SymbolCode, Epoch = trade.Epoch, TradeId = trade.TradeId, Price = trade.Price, Volume = trade.Volume, Side = trade.Side }); } } } var context = (HistorianDbContext)transaction.GetContext(); using (var cmd = context.Database.GetDbConnection().CreateCommand()) { cmd.Transaction = context.Database.CurrentTransaction.GetDbTransaction(); var sql = @"insert into `exchange_trade_aggregate` (`exchange_id`, `symbol_id`, `interval_key`, `timestamp`, `open`, `open_timestamp`, `high`, `low`, `close`, `close_timestamp`, `buy_volume`, `sell_volume`, `total_volume`, `buy_count`, `sell_count`, `total_count`) values "; sql += string.Join(",\r\n", expanded.Select(t => $"(" + $"{(int)t.Exchange}," + $"{(int)t.SymbolCode}," + $"'{t.IntervalKey.Key}'," + $"{t.IntervalEpoch.TimestampMilliseconds}," + $"{t.Price}," + $"{t.Epoch.TimestampMilliseconds}," + $"{t.Price}," + $"{t.Price}," + $"{t.Price}," + $"{t.Epoch.TimestampMilliseconds}," + $"{(t.Side == OrderSideEnum.Buy ? t.Volume.ToString() : "NULL")}," + $"{(t.Side == OrderSideEnum.Sell ? t.Volume.ToString() : "NULL")}," + $"{t.Volume}," + $"{(t.Side == OrderSideEnum.Buy ? "1" : "NULL")}," + $"{(t.Side == OrderSideEnum.Sell ? "1" : "NULL")}," + $"1)")); sql += @" on duplicate key update `open` = case when values(`open_timestamp`) < `open_timestamp` then values(`open`) else `open` end, `open_timestamp` = case when values(`open_timestamp`) < `open_timestamp` then values(`open_timestamp`) else `open_timestamp` end, `high` = case when values(`high`) > `high` then values(`high`) else `high` end, `low` = case when values(`low`) < `low` then values(`low`) else `low` end, `close` = case when values(`close_timestamp`) > `close_timestamp` then values(`close`) else `close` end, `close_timestamp` = case when values(`close_timestamp`) > `close_timestamp` then values(`close_timestamp`) else `close_timestamp` end, `buy_volume` = case when values(`buy_volume`) is not null then ifnull(`buy_volume`, 0) + values(`buy_volume`) else `buy_volume` end, `sell_volume` = case when values(`sell_volume`) is not null then ifnull(`sell_volume`, 0) + values(`sell_volume`) else `sell_volume` end, `total_volume` = `total_volume` + values(`total_volume`), `buy_count` = case when values(`buy_count`) is not null then ifnull(`buy_count`, 0) + values(`buy_count`) else `buy_count` end, `sell_count` = case when values(`sell_count`) is not null then ifnull(`sell_count`, 0) + values(`sell_count`) else `sell_count` end, `total_count` = `total_count` + values(`total_count`)"; cmd.CommandText = sql; await cmd.ExecuteNonQueryAsync(); } }
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 <string> GetTradeFilter(ExchangeEnum exchange, SymbolCodeEnum symbolCode) { var history = await GetSymbol(exchange, symbolCode); return(history != null ? history.TradeFilter : null); }
public async Task <PagedCollection <MarketAggregate> > GetTradeAggregates(ExchangeEnum exchange, SymbolCodeEnum symbolCode, IntervalKey intervalKey, Epoch from, Epoch to, int?pageSize, int?pageNumber) { var intervals = IntervalFactory.GenerateIntervals(intervalKey, from, to); var min = intervals.First(); var max = intervals.Last(); using (var context = ContextFactory.CreateDbContext(null)) { var query = context.ExchangeTradeAggregate .Where(a => a.ExchangeId == (int)exchange && a.SymbolId == (int)symbolCode && a.IntervalKey == intervalKey.Key && a.Timestamp >= min.From.TimestampMilliseconds && a.Timestamp <= max.From.TimestampMilliseconds); var totalCount = 0; if (pageSize.HasValue) { totalCount = await query.CountAsync(); query = query.Skip(pageNumber.GetValueOrDefault(0) * pageSize.Value).Take(pageSize.Value); } var aggs = await query.ToListAsync(); return(new PagedCollection <MarketAggregate>() { PageNumber = pageNumber.GetValueOrDefault(0), PageSize = pageSize.GetValueOrDefault(0), ItemCount = pageSize.HasValue ? totalCount : aggs.Count, Items = aggs.Select(a => new MarketAggregate { Exchange = exchange, Symbol = symbolCode, IntervalKey = a.IntervalKey, Epoch = Epoch.FromMilliseconds(a.Timestamp), Open = a.Open, OpenEpoch = Epoch.FromMilliseconds(a.OpenTimestamp), High = a.High, Low = a.Low, Close = a.Close, CloseEpoch = Epoch.FromMilliseconds(a.CloseTimestamp), BuyVolume = a.BuyVolume, SellVolume = a.SellVolume, TotalVolume = a.TotalVolume, BuyCount = a.BuyCount, SellCount = a.SellCount, TotalCount = a.TotalCount }).ToList() }); } }
public async Task SetTradeFilter(IStorageTransaction transaction, ExchangeEnum exchange, SymbolCodeEnum symbolCode, string filter) { var context = (HistorianDbContext)transaction.GetContext(); var entity = await context.HistorianExchangeSymbol.FindAsync((int)exchange, (int)symbolCode); if (entity == null) { entity = new HistorianExchangeSymbolEntity { ExchangeId = (int)exchange, SymbolId = (int)symbolCode, TradeFilter = filter }; await context.HistorianExchangeSymbol.AddAsync(entity); } else { entity.TradeFilter = filter; context.Update(entity); } }
public async Task <ICollection <StochasticDataPoint> > Stochastic(ExchangeEnum exchange, SymbolCodeEnum symbolCode, IntervalKey intervalKey, Epoch from, int dataPoints, MovingAverageTypeEnum kMaType, int kFastPeriod, int kSlowPeriod, MovingAverageTypeEnum dMaType, int dSlowPeriod) { var dMaTypeConverted = dMaType.ToTaLib(); var kMaTypeConverted = kMaType.ToTaLib(); var periodOffset = kSlowPeriod + 1; var fromOffset = IntervalFactory.GetInterval(intervalKey, from, periodOffset * -1); var aggValues = await MarketRepository.GetTradeAggregates(exchange, symbolCode, intervalKey, fromOffset.From, periodOffset + dataPoints); var highPoints = aggValues.GetValues(CandleTypeEnum.High); var lowPoints = aggValues.GetValues(CandleTypeEnum.Low); var closePoints = aggValues.GetValues(CandleTypeEnum.Close); int outBegIdx, outNbElement; var kValues = new double[dataPoints]; var dValues = new double[dataPoints]; var retCode = Stoch(0, closePoints.Length - 1, highPoints, lowPoints, closePoints, kFastPeriod, kSlowPeriod, kMaTypeConverted, dSlowPeriod, dMaTypeConverted, out outBegIdx, out outNbElement, kValues, dValues); var validKValues = kValues.Skip(outNbElement - dataPoints).Take(dataPoints).ToArray(); var validDValues = dValues.Skip(outNbElement - dataPoints).Take(dataPoints).ToArray(); var validAggValues = aggValues.Skip(aggValues.Count - dataPoints).Take(dataPoints).ToArray(); if (retCode == RetCode.Success) { var dp = new List <StochasticDataPoint>(); for (var i = 0; i < validAggValues.Length; i++) { var agg = validAggValues[i]; dp.Add(new StochasticDataPoint { Epoch = agg.Epoch, D = validKValues[i], K = validDValues[i], }); } return(dp); } throw new Exception("Unable to calculate Stochastic - " + retCode); }
public async Task <MarketTickAverage> GetTickAverage(ICollection <ExchangeEnum> exchanges, SymbolCodeEnum symbolCode, Epoch at) { var ticks = new Dictionary <ExchangeEnum, MarketTick>(); foreach (var exchange in exchanges) { var tick = await GetTick(exchange, symbolCode, at); if (tick != null) { ticks.Add(exchange, tick); } } if (ticks.Count == 0) { return(null); } return(new MarketTickAverage { Epoch = at, SymbolCode = symbolCode, BuyPrice = ticks.Values.Average(t => t.BuyPrice), SellPrice = ticks.Values.Average(t => t.SellPrice), LastPrice = ticks.Values.Average(t => t.LastPrice), Exchanges = ticks.Keys.ToList() }); }
public async Task SetLastTradeStatId(IStorageTransaction transaction, ExchangeEnum exchange, SymbolCodeEnum symbolCode, long lastTradeStatId) { var context = (HistorianDbContext)transaction.GetContext(); var history = await context.HistorianExchangeSymbol.FindAsync((int)exchange, (int)symbolCode); if (history == null) { history = new HistorianExchangeSymbolEntity { ExchangeId = (int)exchange, SymbolId = (int)symbolCode }; await context.HistorianExchangeSymbol.AddAsync(history); } history.LastTradeStatId = lastTradeStatId; }
public async Task <long?> GetLastTradeStatId(ExchangeEnum exchange, SymbolCodeEnum symbolCode) { var history = await GetSymbol(exchange, symbolCode); return(history != null ? history.LastTradeStatId : null); }
private async Task <HistorianExchangeSymbolEntity> GetSymbol(ExchangeEnum exchange, SymbolCodeEnum symbolCode) { using (var context = ContextFactory.CreateDbContext(null)) { return(await context.HistorianExchangeSymbol.FindAsync((int)exchange, (int)symbolCode)); } }
public async Task <HistorianTradeCatchup> GetNextTradeCatchup(ExchangeEnum exchange, SymbolCodeEnum symbolCode) { using (var context = ContextFactory.CreateDbContext(null)) { var next = await context.HistorianTradeCatchup .Where(c => c.ExchangeId == (int)exchange && c.SymbolId == (int)symbolCode) .OrderByDescending(c => c.TimestampTo) .OrderBy(c => c.Priority) .FirstOrDefaultAsync(); return(next != null ? new HistorianTradeCatchup { Exchange = (ExchangeEnum)next.ExchangeId, SymbolCode = (SymbolCodeEnum)next.SymbolId, TradeFilter = next.TradeFilter, EpochTo = Epoch.FromMilliseconds(next.TimestampTo), CurrentTradeFilter = next.CurrentTradeFilter, Priority = next.Priority } : null); } }
public async Task <ICollection <BollingerBandsDataPoint> > BollingerBands(ExchangeEnum exchange, SymbolCodeEnum symbolCode, IntervalKey intervalKey, Epoch from, int dataPoints, CandleTypeEnum candleType, int period, MovingAverageTypeEnum maType, double stdDevUp, double stdDevDown) { var maTypeConverted = maType.ToTaLib(); var periodOffset = period - 1; var fromOffset = IntervalFactory.GetInterval(intervalKey, from, periodOffset * -1); var aggValues = await MarketRepository.GetTradeAggregates(exchange, symbolCode, intervalKey, fromOffset.From, periodOffset + dataPoints); var values = aggValues.GetValues(candleType); int outBegIdx, outNbElement; var upperBandValues = new double[dataPoints]; var middleBandValues = new double[dataPoints]; var lowerBandValues = new double[dataPoints]; var retCode = Bbands(0, values.Length - 1, values, period, stdDevUp, stdDevDown, maTypeConverted, out outBegIdx, out outNbElement, upperBandValues, middleBandValues, lowerBandValues); var validUpperBandValues = upperBandValues.Skip(outNbElement - dataPoints).Take(dataPoints).ToArray(); var validMiddleBandValues = middleBandValues.Skip(outNbElement - dataPoints).Take(dataPoints).ToArray(); var validLowerBandValues = lowerBandValues.Skip(outNbElement - dataPoints).Take(dataPoints).ToArray(); var validAggValues = aggValues.Skip(aggValues.Count - dataPoints).Take(dataPoints).ToArray(); if (retCode == RetCode.Success) { var dp = new List <BollingerBandsDataPoint>(); for (var i = 0; i < validAggValues.Length; i++) { var agg = validAggValues[i]; dp.Add(new BollingerBandsDataPoint { Epoch = agg.Epoch, Upper = upperBandValues[i], Middle = middleBandValues[i], Lower = lowerBandValues[i] }); } return(dp); } throw new Exception("Unable to calculate Bollinger Bands - " + retCode); }
public async Task <ICollection <MarketAggregate> > GetTradeAggregates(ExchangeEnum exchange, SymbolCodeEnum symbolCode, IntervalKey intervalKey, Epoch from, int dataPoints) { var intervals = IntervalFactory.GenerateIntervals(intervalKey, from, dataPoints); var min = intervals.First(); var max = intervals.Last(); var aggs = await GetTradeAggregates(exchange, symbolCode, intervalKey, min.From, max.From, null, null); return(aggs.Items); }
public async Task <ICollection <MarketTrade> > GetNextTrades(ExchangeEnum exchange, SymbolCodeEnum symbolCode, Epoch from, long tradeId, int limit = 1) { using (var context = ContextFactory.CreateDbContext(null)) { var trades = context.ExchangeTrade .Where(t => t.ExchangeId == (int)exchange && t.SymbolId == (int)symbolCode && t.Timestamp >= from.TimestampMilliseconds && t.TradeId > tradeId) .OrderBy(t => t.TradeId) .Take(limit) .Select(t => new { Exchange = exchange, SymbolCode = symbolCode, Timestamp = t.Timestamp, TradeId = (long)t.TradeId, Side = t.OrderSideId.HasValue ? (OrderSideEnum)t.OrderSideId : (OrderSideEnum?)null, Price = t.Price, Volume = t.Volume }); var raw = await trades.ToListAsync(); return(raw.Select(t => new MarketTrade { Exchange = t.Exchange, SymbolCode = t.SymbolCode, Epoch = Epoch.FromMilliseconds(t.Timestamp), TradeId = t.TradeId, Side = t.Side, Price = t.Price, Volume = t.Volume }).ToList()); } }
public static IDisposable BeginSymbolScope(this ILogger logger, SymbolCodeEnum symbolCode) { return(logger.BeginScope(new { SymbolCode = symbolCode })); }