/// <summary> /// Upper Envelope: 20-day SMA + (20-day SMA x .025) /// Lower Envelope: 20-day SMA - (20-day SMA x .025) /// </summary> /// <see cref="http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:moving_average_envelopes"/> /// <returns></returns> public override EnvelopeSerie Calculate() { EnvelopeSerie envelopeSerie = new EnvelopeSerie(); SMA sma = new SMA(Period); sma.Load(OhlcList); List <double?> smaList = sma.Calculate().Values; for (int i = 0; i < OhlcList.Count; i++) { if (smaList[i].HasValue) { envelopeSerie.Lower.Add(smaList[i].Value - (smaList[i].Value * Factor)); envelopeSerie.Upper.Add(smaList[i].Value + (smaList[i].Value * Factor)); } else { envelopeSerie.Lower.Add(null); envelopeSerie.Upper.Add(null); } } return(envelopeSerie); }
/// <summary> /// Price {X/2 + 1} periods ago less the X-period simple moving average. /// X refers to the number of periods used to calculate the Detrended Price /// Oscillator. A 20-day DPO would use a 20-day SMA that is displaced by 11 /// periods {20/2 + 1 = 11}. This displacement shifts the 20-day SMA 11 days /// to the left, which actually puts it in the middle of the look-back /// period. The value of the 20-day SMA is then subtracted from the price /// in the middle of this look-back period. In short, DPO(20) equals price /// 11 days ago less the 20-day SMA. /// </summary> /// <see cref="http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:detrended_price_osci"/> /// <returns></returns> public override SingleDoubleSerie Calculate() { SingleDoubleSerie dpoSerie = new SingleDoubleSerie(); SMA sma = new SMA(Period); sma.Load(OhlcList); List <double?> smaList = sma.Calculate().Values; // shift to left (n / 2) + 1 for (int i = 0; i < smaList.Count; i++) { if (i >= Period - 1) { smaList[i - ((Period / 2) + 1)] = smaList[i]; smaList[i] = null; } } for (int i = 0; i < OhlcList.Count; i++) { if (smaList[i].HasValue) { double dpo = OhlcList[i].Close - smaList[i].Value; dpoSerie.Values.Add(dpo); } else { dpoSerie.Values.Add(null); } } return(dpoSerie); }
/// <summary> /// Commodity Channel Index (CCI) /// tp = (high + low + close) / 3 /// cci = (tp - SMA(tp)) / (Factor * meanDeviation(tp)) /// </summary> /// <see cref="http://www.fmlabs.com/reference/default.htm?url=CCI.htm"/> /// <see cref="http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:commodity_channel_index_cci"/> /// <returns></returns> public override SingleDoubleSerie Calculate() { SingleDoubleSerie cciSerie = new SingleDoubleSerie(); for (int i = 0; i < OhlcList.Count; i++) { OhlcList[i].Close = (OhlcList[i].High + OhlcList[i].Low + OhlcList[i].Close) / 3; } SMA sma = new SMA(Period); sma.Load(OhlcList); List <double?> smaList = sma.Calculate().Values; List <double?> meanDeviationList = new List <double?>(); for (int i = 0; i < OhlcList.Count; i++) { if (i >= Period - 1) { double total = 0.0; for (int j = i; j >= i - (Period - 1); j--) { total += Math.Abs(smaList[i].Value - OhlcList[j].Close); } meanDeviationList.Add(total / (double)Period); double cci = (OhlcList[i].Close - smaList[i].Value) / (Factor * meanDeviationList[i].Value); cciSerie.Values.Add(cci); } else { meanDeviationList.Add(null); cciSerie.Values.Add(null); } } return(cciSerie); }