// DONCHIAN CHANNEL public static IEnumerable <KeltnerResult> GetKeltner( IEnumerable <Quote> history, int emaPeriod = 20, decimal multiplier = 2, int atrPeriod = 10) { // clean quotes history = Cleaners.PrepareHistory(history); // validate parameters ValidateKeltner(history, emaPeriod, multiplier, atrPeriod); // initialize List <KeltnerResult> results = new List <KeltnerResult>(); IEnumerable <EmaResult> emaResults = GetEma(history, emaPeriod); IEnumerable <AtrResult> atrResults = GetAtr(history, atrPeriod); int lookbackPeriod = Math.Max(emaPeriod, atrPeriod); decimal?prevWidth = null; // roll through history foreach (Quote h in history) { KeltnerResult result = new KeltnerResult { Index = (int)h.Index, Date = h.Date }; if (h.Index >= lookbackPeriod) { IEnumerable <Quote> period = history .Where(x => x.Index > (h.Index - lookbackPeriod) && x.Index <= h.Index); EmaResult ema = emaResults.Where(x => x.Index == h.Index).FirstOrDefault(); AtrResult atr = atrResults.Where(x => x.Index == h.Index).FirstOrDefault(); result.UpperBand = ema.Ema + multiplier * atr.Atr; result.LowerBand = ema.Ema - multiplier * atr.Atr; result.Centerline = ema.Ema; result.Width = (result.Centerline == 0) ? null : (result.UpperBand - result.LowerBand) / result.Centerline; // for next iteration prevWidth = result.Width; } results.Add(result); } return(results); }
// DONCHIAN CHANNEL public static IEnumerable <KeltnerResult> GetKeltner <TQuote>( IEnumerable <TQuote> history, int emaPeriod = 20, decimal multiplier = 2, int atrPeriod = 10) where TQuote : IQuote { // clean quotes List <TQuote> historyList = history.Sort(); // validate parameters ValidateKeltner(history, emaPeriod, multiplier, atrPeriod); // initialize List <KeltnerResult> results = new List <KeltnerResult>(); List <EmaResult> emaResults = GetEma(history, emaPeriod).ToList(); List <AtrResult> atrResults = GetAtr(history, atrPeriod).ToList(); int lookbackPeriod = Math.Max(emaPeriod, atrPeriod); // roll through history for (int i = 0; i < historyList.Count; i++) { TQuote h = historyList[i]; int index = i + 1; KeltnerResult result = new KeltnerResult { Date = h.Date }; if (index >= lookbackPeriod) { EmaResult ema = emaResults[i]; AtrResult atr = atrResults[i]; result.UpperBand = ema.Ema + multiplier * atr.Atr; result.LowerBand = ema.Ema - multiplier * atr.Atr; result.Centerline = ema.Ema; result.Width = (result.Centerline == 0) ? null : (result.UpperBand - result.LowerBand) / result.Centerline; } results.Add(result); } return(results); }