public override MACDSerie Calculate() { MACDSerie macdSerie = new MACDSerie(); EMA ema = new EMA(Fast, false); ema.Load(OhlcList); List <double?> fastEmaValues = ema.Calculate().Values; ema = new EMA(Slow, false); ema.Load(OhlcList); List <double?> slowEmaValues = ema.Calculate().Values; for (int i = 0; i < OhlcList.Count; i++) { // MACD Line if (fastEmaValues[i].HasValue && slowEmaValues[i].HasValue) { if (!Percent) { macdSerie.MACDLine.Add(fastEmaValues[i].Value - slowEmaValues[i].Value); } else { // macd <- 100 * ( mavg.fast / mavg.slow - 1 ) macdSerie.MACDLine.Add(100 * ((fastEmaValues[i].Value / slowEmaValues[i].Value) - 1)); } OhlcList[i].Close = macdSerie.MACDLine[i].Value; } else { macdSerie.MACDLine.Add(null); OhlcList[i].Close = 0.0; } } int zeroCount = macdSerie.MACDLine.Where(x => x == null).Count(); ema = new EMA(Signal, false); ema.Load(OhlcList.Skip(zeroCount).ToList()); List <double?> signalEmaValues = ema.Calculate().Values; for (int i = 0; i < zeroCount; i++) { signalEmaValues.Insert(0, null); } // Fill Signal and MACD Histogram lists for (int i = 0; i < signalEmaValues.Count; i++) { macdSerie.Signal.Add(signalEmaValues[i]); macdSerie.MACDHistogram.Add(macdSerie.MACDLine[i] - macdSerie.Signal[i]); } return(macdSerie); }
/// <summary> /// TrueHigh = Highest of high[0] or close[-1] /// TrueLow = Highest of low[0] or close[-1] /// TR = TrueHigh - TrueLow /// ATR = EMA(TR) /// </summary> /// <see cref="http://www.fmlabs.com/reference/default.htm?url=TR.htm"/> /// <see cref="http://www.fmlabs.com/reference/default.htm?url=ATR.htm"/> /// <returns></returns> public override ATRSerie Calculate() { ATRSerie atrSerie = new ATRSerie(); atrSerie.TrueHigh.Add(null); atrSerie.TrueLow.Add(null); atrSerie.TrueRange.Add(null); atrSerie.ATR.Add(null); for (int i = 1; i < OhlcList.Count; i++) { double trueHigh = OhlcList[i].High >= OhlcList[i - 1].Close ? OhlcList[i].High : OhlcList[i - 1].Close; atrSerie.TrueHigh.Add(trueHigh); double trueLow = OhlcList[i].Low <= OhlcList[i - 1].Close ? OhlcList[i].Low : OhlcList[i - 1].Close; atrSerie.TrueLow.Add(trueLow); double trueRange = trueHigh - trueLow; atrSerie.TrueRange.Add(trueRange); } for (int i = 1; i < OhlcList.Count; i++) { OhlcList[i].Close = atrSerie.TrueRange[i].Value; } EMA ema = new EMA(Period, true); ema.Load(OhlcList.Skip(1).ToList()); List <double?> atrList = ema.Calculate().Values; foreach (var atr in atrList) { atrSerie.ATR.Add(atr); } return(atrSerie); }
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); }