public override ADXSerie Calculate()
        {
            ADXSerie adxSerie = new ADXSerie();

            List <Ohlc> tempOhlcList = new List <Ohlc>();

            for (int i = 0; i < OhlcList.Count; i++)
            {
                Ohlc tempOhlc = new Ohlc()
                {
                    Close = OhlcList[i].High
                };
                tempOhlcList.Add(tempOhlc);
            }
            Momentum momentum = new Momentum();

            momentum.Load(tempOhlcList);
            List <double?> highMomentums = momentum.Calculate().Values;

            tempOhlcList = new List <Ohlc>();
            for (int i = 0; i < OhlcList.Count; i++)
            {
                Ohlc tempOhlc = new Ohlc()
                {
                    Close = OhlcList[i].Low
                };
                tempOhlcList.Add(tempOhlc);
            }
            momentum = new Momentum();
            momentum.Load(tempOhlcList);
            List <double?> lowMomentums = momentum.Calculate().Values;

            for (int i = 0; i < lowMomentums.Count; i++)
            {
                if (lowMomentums[i].HasValue)
                {
                    lowMomentums[i] *= -1;
                }
            }

            //DMIp <- ifelse( dH==dL | (dH< 0 & dL< 0), 0, ifelse( dH >dL, dH, 0 ) )
            List <double?> DMIPositives = new List <double?>()
            {
                null
            };
            // DMIn <- ifelse( dH==dL | (dH< 0 & dL< 0), 0, ifelse( dH <dL, dL, 0 ) )
            List <double?> DMINegatives = new List <double?>()
            {
                null
            };

            for (int i = 1; i < OhlcList.Count; i++)
            {
                if (highMomentums[i] == lowMomentums[i] || (highMomentums[i] < 0 & lowMomentums[i] < 0))
                {
                    DMIPositives.Add(0);
                }
                else
                {
                    if (highMomentums[i] > lowMomentums[i])
                    {
                        DMIPositives.Add(highMomentums[i]);
                    }
                    else
                    {
                        DMIPositives.Add(0);
                    }
                }

                if (highMomentums[i] == lowMomentums[i] || (highMomentums[i] < 0 & lowMomentums[i] < 0))
                {
                    DMINegatives.Add(0);
                }
                else
                {
                    if (highMomentums[i] < lowMomentums[i])
                    {
                        DMINegatives.Add(lowMomentums[i]);
                    }
                    else
                    {
                        DMINegatives.Add(0);
                    }
                }
            }

            ATR atr = new ATR();

            atr.Load(OhlcList);
            List <double?> trueRanges = atr.Calculate().TrueRange;

            adxSerie.TrueRange = trueRanges;

            List <double?> trSum = wilderSum(trueRanges);

            // DIp <- 100 * wilderSum(DMIp, n=n) / TRsum
            List <double?> DIPositives     = new List <double?>();
            List <double?> wilderSumOfDMIp = wilderSum(DMIPositives);

            for (int i = 0; i < wilderSumOfDMIp.Count; i++)
            {
                if (wilderSumOfDMIp[i].HasValue)
                {
                    DIPositives.Add(wilderSumOfDMIp[i].Value * 100 / trSum[i].Value);
                }
                else
                {
                    DIPositives.Add(null);
                }
            }
            adxSerie.DIPositive = DIPositives;

            // DIn <- 100 * wilderSum(DMIn, n=n) / TRsum
            List <double?> DINegatives     = new List <double?>();
            List <double?> wilderSumOfDMIn = wilderSum(DMINegatives);

            for (int i = 0; i < wilderSumOfDMIn.Count; i++)
            {
                if (wilderSumOfDMIn[i].HasValue)
                {
                    DINegatives.Add(wilderSumOfDMIn[i].Value * 100 / trSum[i].Value);
                }
                else
                {
                    DINegatives.Add(null);
                }
            }
            adxSerie.DINegative = DINegatives;

            // DX  <- 100 * ( abs(DIp - DIn) / (DIp + DIn) )
            List <double?> DX = new List <double?>();

            for (int i = 0; i < OhlcList.Count; i++)
            {
                if (DIPositives[i].HasValue)
                {
                    double?dx = 100 * (Math.Abs(DIPositives[i].Value - DINegatives[i].Value) / (DIPositives[i].Value + DINegatives[i].Value));
                    DX.Add(dx);
                }
                else
                {
                    DX.Add(null);
                }
            }
            adxSerie.DX = DX;

            for (int i = 0; i < OhlcList.Count; i++)
            {
                if (DX[i].HasValue)
                {
                    OhlcList[i].Close = DX[i].Value;
                }
                else
                {
                    OhlcList[i].Close = 0.0;
                }
            }

            EMA ema = new EMA(Period, true);

            ema.Load(OhlcList.Skip(Period).ToList());
            List <double?> emaValues = ema.Calculate().Values;

            for (int i = 0; i < Period; i++)
            {
                emaValues.Insert(0, null);
            }
            adxSerie.ADX = emaValues;

            return(adxSerie);
        }
        static public void buildIndicators(List <BarRecord> barRecords)
        {
            SMA sma9 = new SMA(9);

            sma9.LoadOhlcList(barRecords);
            SingleDoubleSerie sma9Serie = sma9.Calculate();

            double?[] sma9Arry = sma9Serie.Values.ToArray();

            SMA sma20 = new SMA(20);

            sma20.LoadOhlcList(barRecords);
            SingleDoubleSerie sma20Serie = sma20.Calculate();

            double?[] sma20Arry = sma20Serie.Values.ToArray();

            SMA sma50 = new SMA(50);

            sma50.LoadOhlcList(barRecords);
            SingleDoubleSerie sma50Serie = sma50.Calculate();

            double?[] sma50Arry = sma50Serie.Values.ToArray();

            MACD macd = new MACD(true);

            macd.LoadOhlcList(barRecords);
            MACDSerie macdSerie = macd.Calculate();

            double?[] macdHistArry = macdSerie.MACDHistogram.ToArray();

            RSI rsi = new RSI(14);

            rsi.LoadOhlcList(barRecords);
            RSISerie rsiSerie = rsi.Calculate();

            double?[] rsiArry = rsiSerie.RSI.ToArray();

            BollingerBand bollingerBand = new BollingerBand();

            bollingerBand.LoadOhlcList(barRecords);
            BollingerBandSerie bollingerSerie = bollingerBand.Calculate();

            double?[] bollLowArry = bollingerSerie.LowerBand.ToArray();
            double?[] bollUpArry  = bollingerSerie.UpperBand.ToArray();

            CCI cci = new CCI();

            cci.LoadOhlcList(barRecords);
            SingleDoubleSerie cciSerie = cci.Calculate();

            double?[] cciArry = cciSerie.Values.ToArray();

            ATR atr = new ATR();

            atr.LoadOhlcList(barRecords);
            ATRSerie atrSerie = atr.Calculate();

            double?[] atrHighArry = atrSerie.TrueHigh.ToArray();
            double?[] atrLowArry  = atrSerie.TrueLow.ToArray();
            double?[] atrArry     = atrSerie.ATR.ToArray();

            ADX adx = new ADX();

            adx.LoadOhlcList(barRecords);
            ADXSerie adxSerie = adx.Calculate();

            double?[] adxPositiveArry = adxSerie.DIPositive.ToArray();
            double?[] adxNegativeArry = adxSerie.DINegative.ToArray();
            double?[] adxArry         = adxSerie.ADX.ToArray();

            Momentum mo = new Momentum();

            mo.LoadOhlcList(barRecords);
            SingleDoubleSerie moSerie = mo.Calculate();

            double?[] moArry = moSerie.Values.ToArray();

            VROC vroc = new VROC(25);

            vroc.LoadOhlcList(barRecords);
            SingleDoubleSerie vrocSerie = vroc.Calculate();

            double?[] vrocArry = vrocSerie.Values.ToArray();

            int index = 0;

            foreach (BarRecord bar in barRecords)
            {
                bar.SMA9           = sma9Arry[index].ToString();
                bar.SMA20          = sma20Arry[index].ToString();
                bar.SMA50          = sma50Arry[index].ToString();
                bar.MACD_DIFF      = macdHistArry[index].ToString();
                bar.RSI            = rsiArry[index].ToString();
                bar.BOLL_LOW       = bollLowArry[index].ToString();
                bar.BOLL_HIGH      = bollUpArry[index].ToString();
                bar.CCI            = cciArry[index].ToString();
                bar.ADX_DIPositive = adxPositiveArry[index].ToString();
                bar.ADX_DINegative = adxNegativeArry[index].ToString();
                //bar.ADX = adxArry[index].ToString();
                bar.ATR_TrueHigh = atrHighArry[index].ToString();
                bar.ATR_TrueLow  = atrLowArry[index].ToString();
                //bar.ATR = atrArry[index].ToString();
                bar.Momentum = moArry[index].ToString();
                bar.VROC     = vrocArry[index].ToString();
                index++;
            }
        }