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);
        }