public async Task Add(IntervalKey intervalKey) { using (var context = ContextFactory.CreateDbContext(null)) { if (await context.IntervalKey.FindAsync(intervalKey.Key) == null) { await context.IntervalKey.AddAsync(new IntervalKeyEntity { IntervalKey = intervalKey.Key, IntervalGroupId = (int)intervalKey.IntervalGroup, Label = intervalKey.Label }); await context.SaveChangesAsync(); var from = new DateTime(2008, 1, 1, 0, 0, 0, DateTimeKind.Utc); var to = new DateTime(DateTime.Now.Year + 2, 1, 1, 0, 0, 0, DateTimeKind.Utc); var cursor = from; while (cursor < to) { var intervals = IntervalFactory.GenerateIntervals(intervalKey, new Epoch(cursor), new Epoch(cursor.AddYears(1))); await AddInterval(intervals); cursor = cursor.AddYears(1); } } } }
public Interval GetInterval(IntervalKey intervalKey, Epoch epoch) { var ts = TimeSpan.FromMinutes(intervalKey.Duration); return(new Interval { IntervalKey = intervalKey, From = epoch.RoundDown(ts), To = epoch.AddSeconds(1).RoundUp(ts) }); }
public Interval GetInterval(IntervalKey intervalKey, Epoch epoch) { var startOfMonth = new DateTime(epoch.DateTime.Year, epoch.DateTime.Month, 1, 0, 0, 0, DateTimeKind.Utc); return(new Interval { IntervalKey = intervalKey, From = new Epoch(startOfMonth), To = new Epoch(startOfMonth.AddMonths(1)) }); }
public Interval GetInterval(IntervalKey intervalKey, Epoch epoch) { var from = epoch.DateTime.Date.AddDays(-(int)epoch.DateTime.Date.DayOfWeek + (int)DayOfWeek.Monday); return(new Interval { IntervalKey = intervalKey, From = new Epoch(from), To = new Epoch(from.AddDays(7)) }); }
public async Task RsiReturnsExpectedValue() { var intervalKey = new IntervalKey() { IntervalGroup = IntervalGroupEnum.Day, Key = "1D", Duration = 1 }; var from = new Epoch(new DateTime(2018, 2, 1, 0, 0, 0, DateTimeKind.Utc)); var dataPoints = 5; var rsiValues = await MarketIndicatorProvider.Rsi(ExchangeEnum.Kraken, SymbolCodeEnum.BTCUSD, intervalKey, from, dataPoints, CandleTypeEnum.Close, 14); var rsi = rsiValues.First(); Assert.AreEqual(35.8181, Math.Round(rsi.Rsi, 4)); }
public async Task MacdReturnsExpectedValue() { var intervalKey = new IntervalKey() { IntervalGroup = IntervalGroupEnum.Day, Key = "1D", Duration = 1 }; var from = new Epoch(new DateTime(2018, 2, 3, 0, 0, 0, DateTimeKind.Utc)); var dataPoints = 1; var macdValues = await MarketIndicatorProvider.Macd(ExchangeEnum.Kraken, SymbolCodeEnum.BTCUSD, intervalKey, from, dataPoints, CandleTypeEnum.Close, 12, 26, 9); var macd = macdValues.First(); Assert.AreEqual(-1550.9828, Math.Round(macd.Macd, 4)); Assert.AreEqual(-1561.9757, Math.Round(macd.Signal, 4)); Assert.AreEqual(10.9928, Math.Round(macd.Histogram, 4)); }
public async Task <ICollection <MovingAverageDataPoint> > Ema(ExchangeEnum exchange, SymbolCodeEnum symbolCode, IntervalKey intervalKey, Epoch from, int dataPoints, CandleTypeEnum candleType, int period) { 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 smaValues = new double[dataPoints]; var retCode = TicTacTec.TA.Library.Core.Ema(0, values.Length - 1, values, period, out outBegIdx, out outNbElement, smaValues); var validSmaValues = smaValues.Skip(outNbElement - dataPoints).Take(dataPoints).ToArray(); var validAggValues = aggValues.Skip(aggValues.Count - dataPoints).Take(dataPoints).ToArray(); if (retCode == RetCode.Success) { var dp = new List <MovingAverageDataPoint>(); for (var i = 0; i < validAggValues.Length; i++) { var agg = validAggValues[i]; dp.Add(new MovingAverageDataPoint { Epoch = agg.Epoch, Value = validSmaValues[i] }); } return(dp); } throw new Exception("Unable to calculate EMA - " + retCode); }
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 <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 <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 <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 <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); }