// AVERAGE TRUE RANGE public static IEnumerable <AtrResult> GetAtr(IEnumerable <Quote> history, int lookbackPeriod = 14) { // clean quotes history = Cleaners.PrepareHistory(history); // initialize results List <AtrResult> results = new List <AtrResult>(); decimal prevAtr = 0; decimal prevClose = 0; decimal highMinusPrevClose = 0; decimal lowMinusPrevClose = 0; decimal sumTr = 0; // roll through history foreach (Quote h in history) { AtrResult result = new AtrResult { Index = (int)h.Index, Date = h.Date }; if (h.Index > 1) { highMinusPrevClose = Math.Abs(h.High - prevClose); lowMinusPrevClose = Math.Abs(h.Low - prevClose); } decimal tr = Math.Max((h.High - h.Low), Math.Max(highMinusPrevClose, lowMinusPrevClose)); result.Tr = tr; if (h.Index > lookbackPeriod) { // calculate ATR result.Atr = (prevAtr * (lookbackPeriod - 1) + tr) / lookbackPeriod; prevAtr = (decimal)result.Atr; } else if (h.Index == lookbackPeriod) { // initialize ATR sumTr += tr; result.Atr = sumTr / lookbackPeriod; prevAtr = (decimal)result.Atr; } else { // only used for periods before ATR initialization sumTr += tr; } results.Add(result); prevClose = h.Close; } return(results); }
// 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); }
// STARC BANDS /// <include file='./info.xml' path='indicator/*' /> /// public static IEnumerable <StarcBandsResult> GetStarcBands <TQuote>( IEnumerable <TQuote> history, int smaPeriod = 20, decimal multiplier = 2, int atrPeriod = 10) where TQuote : IQuote { // sort history List <TQuote> historyList = history.Sort(); // check parameter arguments ValidateStarcBands(history, smaPeriod, multiplier, atrPeriod); // initialize List <StarcBandsResult> results = new List <StarcBandsResult>(historyList.Count); List <SmaResult> smaResults = GetSma(history, smaPeriod).ToList(); List <AtrResult> atrResults = GetAtr(history, atrPeriod).ToList(); int lookbackPeriod = Math.Max(smaPeriod, atrPeriod); // roll through history for (int i = 0; i < historyList.Count; i++) { TQuote h = historyList[i]; int index = i + 1; StarcBandsResult result = new StarcBandsResult { Date = h.Date }; if (index >= lookbackPeriod) { SmaResult s = smaResults[i]; AtrResult a = atrResults[i]; result.Centerline = s.Sma; result.UpperBand = s.Sma + multiplier * a.Atr; result.LowerBand = s.Sma - multiplier * a.Atr; } results.Add(result); } return(results); }
// AVERAGE TRUE RANGE public static IEnumerable <AtrResult> GetAtr(IEnumerable <Quote> history, int lookbackPeriod = 14) { // clean quotes List <Quote> historyList = history.Sort(); // validate parameters ValidateAtr(history, lookbackPeriod); // initialize results List <AtrResult> results = new List <AtrResult>(); decimal prevAtr = 0; decimal prevClose = 0; decimal highMinusPrevClose = 0; decimal lowMinusPrevClose = 0; decimal sumTr = 0; // roll through history for (int i = 0; i < historyList.Count; i++) { Quote h = historyList[i]; int index = i + 1; AtrResult result = new AtrResult { Date = h.Date }; if (index > 1) { highMinusPrevClose = Math.Abs(h.High - prevClose); lowMinusPrevClose = Math.Abs(h.Low - prevClose); } decimal tr = Math.Max((h.High - h.Low), Math.Max(highMinusPrevClose, lowMinusPrevClose)); result.Tr = tr; if (index > lookbackPeriod) { // calculate ATR result.Atr = (prevAtr * (lookbackPeriod - 1) + tr) / lookbackPeriod; result.Atrp = (h.Close == 0) ? null : (result.Atr / h.Close) * 100; prevAtr = (decimal)result.Atr; } else if (index == lookbackPeriod) { // initialize ATR sumTr += tr; result.Atr = sumTr / lookbackPeriod; result.Atrp = (h.Close == 0) ? null : (result.Atr / h.Close) * 100; prevAtr = (decimal)result.Atr; } else { // only used for periods before ATR initialization sumTr += tr; } results.Add(result); prevClose = h.Close; } return(results); }
// AVERAGE TRUE RANGE public static IEnumerable <AtrResult> GetAtr(IEnumerable <Quote> history, int lookbackPeriod = 14) { // clean quotes history = Cleaners.PrepareHistory(history); // check exceptions int qtyHistory = history.Count(); int minHistory = lookbackPeriod + 1; if (qtyHistory < minHistory) { throw new BadHistoryException("Insufficient history provided for ATR. " + string.Format("You provided {0} periods of history when {1} is required. " , qtyHistory, minHistory)); } // initialize results List <AtrResult> results = new List <AtrResult>(); decimal prevAtr = 0; decimal prevClose = 0; decimal highMinusPrevClose = 0; decimal lowMinusPrevClose = 0; decimal sumTr = 0; // roll through history foreach (Quote h in history) { AtrResult result = new AtrResult { Index = (int)h.Index, Date = h.Date }; if (h.Index > 1) { highMinusPrevClose = Math.Abs(h.High - prevClose); lowMinusPrevClose = Math.Abs(h.Low - prevClose); } decimal tr = Math.Max((h.High - h.Low), Math.Max(highMinusPrevClose, lowMinusPrevClose)); result.Tr = tr; if (h.Index > lookbackPeriod) { // calculate ATR result.Atr = (prevAtr * (lookbackPeriod - 1) + tr) / lookbackPeriod; prevAtr = (decimal)result.Atr; } else if (h.Index == lookbackPeriod) { // initialize ATR sumTr += tr; result.Atr = sumTr / lookbackPeriod; prevAtr = (decimal)result.Atr; } else { // only used for periods before ATR initialization sumTr += tr; } results.Add(result); prevClose = h.Close; } return(results); }