// BOLLINGER BANDS public static IEnumerable <BollingerBandsResult> GetBollingerBands <TQuote>( IEnumerable <TQuote> history, int lookbackPeriod = 20, decimal standardDeviations = 2) where TQuote : IQuote { // clean quotes List <TQuote> historyList = history.Sort(); // validate parameters ValidateBollingerBands(history, lookbackPeriod, standardDeviations); // initialize List <BollingerBandsResult> results = new List <BollingerBandsResult>(); // roll through history for (int i = 0; i < historyList.Count; i++) { TQuote h = historyList[i]; int index = i + 1; BollingerBandsResult r = new BollingerBandsResult { Date = h.Date }; if (index >= lookbackPeriod) { double[] periodClose = new double[lookbackPeriod]; decimal sum = 0m; int n = 0; for (int p = index - lookbackPeriod; p < index; p++) { TQuote d = historyList[p]; periodClose[n] = (double)d.Close; sum += d.Close; n++; } decimal periodAvg = sum / lookbackPeriod; decimal stdDev = (decimal)Functions.StdDev(periodClose); r.Sma = periodAvg; r.UpperBand = periodAvg + standardDeviations * stdDev; r.LowerBand = periodAvg - standardDeviations * stdDev; r.PercentB = (r.UpperBand == r.LowerBand) ? null : (h.Close - r.LowerBand) / (r.UpperBand - r.LowerBand); r.ZScore = (stdDev == 0) ? null : (h.Close - r.Sma) / stdDev; r.Width = (r.Sma == 0) ? null : (r.UpperBand - r.LowerBand) / r.Sma; } results.Add(r); } return(results); }
// BOLLINGER BANDS public static IEnumerable <BollingerBandsResult> GetBollingerBands(IEnumerable <Quote> history, int lookbackPeriod = 20, decimal standardDeviations = 2) { // clean quotes history = Cleaners.PrepareHistory(history); // check exceptions int qtyHistory = history.Count(); int minHistory = lookbackPeriod; if (qtyHistory < minHistory) { throw new BadHistoryException("Insufficient history provided for Bollinger Bands. " + string.Format("You provided {0} periods of history when {1} is required.", qtyHistory, minHistory)); } // initialize List <BollingerBandsResult> results = new List <BollingerBandsResult>(); IEnumerable <SmaResult> sma = GetSma(history, lookbackPeriod); decimal?prevUpperBand = null; decimal?prevLowerBand = null; // roll through history foreach (Quote h in history) { BollingerBandsResult result = new BollingerBandsResult { Index = (int)h.Index, Date = h.Date }; if (h.Index >= lookbackPeriod) { IEnumerable <double> periodClose = history .Where(x => x.Index > (h.Index - lookbackPeriod) && x.Index <= h.Index) .Select(x => (double)x.Close); double stdDev = Functions.StdDev(periodClose); result.Sma = sma.Where(x => x.Date == h.Date).Select(x => x.Sma).FirstOrDefault(); result.UpperBand = result.Sma + standardDeviations * (decimal)stdDev; result.LowerBand = result.Sma - standardDeviations * (decimal)stdDev; if (prevUpperBand != null && prevLowerBand != null) { result.IsDiverging = ((decimal)result.UpperBand - (decimal)result.LowerBand) > ((decimal)prevUpperBand - (decimal)prevLowerBand) ? true : false; } // for next iteration prevUpperBand = result.UpperBand; prevLowerBand = result.LowerBand; } results.Add(result); } return(results); }
// BOLLINGER BANDS public static IEnumerable <BollingerBandsResult> GetBollingerBands( IEnumerable <Quote> history, int lookbackPeriod = 20, decimal standardDeviations = 2) { // clean quotes history = Cleaners.PrepareHistory(history); // validate parameters ValidateBollingerBands(history, lookbackPeriod, standardDeviations); // initialize List <BollingerBandsResult> results = new List <BollingerBandsResult>(); decimal?prevUpperBand = null; decimal?prevLowerBand = null; // roll through history foreach (Quote h in history) { BollingerBandsResult result = new BollingerBandsResult { Index = (int)h.Index, Date = h.Date }; if (h.Index >= lookbackPeriod) { IEnumerable <double> periodClose = history .Where(x => x.Index > (h.Index - lookbackPeriod) && x.Index <= h.Index) .Select(x => (double)x.Close); double stdDev = Functions.StdDev(periodClose); result.Sma = (decimal)periodClose.Average(); result.UpperBand = result.Sma + standardDeviations * (decimal)stdDev; result.LowerBand = result.Sma - standardDeviations * (decimal)stdDev; result.ZScore = (stdDev == 0) ? null : (h.Close - result.Sma) / (decimal)stdDev; result.Width = (result.Sma == 0) ? null : (result.UpperBand - result.LowerBand) / result.Sma; if (prevUpperBand != null && prevLowerBand != null) { result.IsDiverging = ((decimal)result.UpperBand - (decimal)result.LowerBand) > ((decimal)prevUpperBand - (decimal)prevLowerBand); } // for next iteration prevUpperBand = result.UpperBand; prevLowerBand = result.LowerBand; } results.Add(result); } return(results); }
// BOLLINGER BANDS public static IEnumerable <BollingerBandsResult> GetBollingerBands( IEnumerable <Quote> history, int lookbackPeriod = 20, decimal standardDeviations = 2) { // clean quotes List <Quote> historyList = Cleaners.PrepareHistory(history).ToList(); // validate parameters ValidateBollingerBands(history, lookbackPeriod, standardDeviations); // initialize List <BollingerBandsResult> results = new List <BollingerBandsResult>(); // roll through history for (int i = 0; i < historyList.Count; i++) { Quote h = historyList[i]; BollingerBandsResult result = new BollingerBandsResult { Index = (int)h.Index, Date = h.Date }; if (h.Index >= lookbackPeriod) { double[] periodClose = new double[lookbackPeriod]; decimal sum = 0m; int n = 0; for (int p = (int)h.Index - lookbackPeriod; p < h.Index; p++) { Quote d = historyList[p]; periodClose[n] = (double)d.Close; sum += d.Close; n++; } decimal periodAvg = sum / lookbackPeriod; decimal stdDev = (decimal)Functions.StdDev(periodClose); result.Sma = periodAvg; result.UpperBand = periodAvg + standardDeviations * stdDev; result.LowerBand = periodAvg - standardDeviations * stdDev; result.ZScore = (stdDev == 0) ? null : (h.Close - result.Sma) / stdDev; result.Width = (result.Sma == 0) ? null : (result.UpperBand - result.LowerBand) / result.Sma; } results.Add(result); } return(results); }
// BOLLINGER BANDS public static IEnumerable <BollingerBandsResult> GetBollingerBands(IEnumerable <Quote> history, int lookbackPeriod = 20, decimal standardDeviations = 2) { // clean quotes history = Cleaners.PrepareHistory(history); // initialize List <BollingerBandsResult> results = new List <BollingerBandsResult>(); IEnumerable <SmaResult> sma = GetSma(history, lookbackPeriod); decimal?prevUpperBand = null; decimal?prevLowerBand = null; // roll through history foreach (Quote h in history) { BollingerBandsResult result = new BollingerBandsResult { Index = (int)h.Index, Date = h.Date }; if (h.Index >= lookbackPeriod) { IEnumerable <double> periodClose = history .Where(x => x.Index > (h.Index - lookbackPeriod) && x.Index <= h.Index) .Select(x => (double)x.Close); double stdDev = Functions.StdDev(periodClose); result.Sma = sma.Where(x => x.Date == h.Date).Select(x => x.Sma).FirstOrDefault(); result.UpperBand = result.Sma + standardDeviations * (decimal)stdDev; result.LowerBand = result.Sma - standardDeviations * (decimal)stdDev; if (prevUpperBand != null && prevLowerBand != null) { result.IsDiverging = ((decimal)result.UpperBand - (decimal)result.LowerBand) > ((decimal)prevUpperBand - (decimal)prevLowerBand) ? true : false; } // for next iteration prevUpperBand = result.UpperBand; prevLowerBand = result.LowerBand; } results.Add(result); } return(results); }
// BOLLINGER BANDS public static IEnumerable <BollingerBandsResult> GetBollingerBands( IEnumerable <Quote> history, int lookbackPeriod = 20, decimal standardDeviations = 2) { // clean quotes Cleaners.PrepareHistory(history); // validate parameters ValidateBollingerBands(history, lookbackPeriod, standardDeviations); // initialize List <Quote> historyList = history.ToList(); List <BollingerBandsResult> results = new List <BollingerBandsResult>(); // roll through history for (int i = 0; i < historyList.Count; i++) { Quote h = historyList[i]; BollingerBandsResult result = new BollingerBandsResult { Index = (int)h.Index, Date = h.Date }; if (h.Index >= lookbackPeriod) { double[] periodClose = historyList .Where(x => x.Index > (h.Index - lookbackPeriod) && x.Index <= h.Index) .Select(x => (double)x.Close) .ToArray(); decimal stdDev = (decimal)Functions.StdDev(periodClose); result.Sma = (decimal)periodClose.Average(); result.UpperBand = result.Sma + standardDeviations * stdDev; result.LowerBand = result.Sma - standardDeviations * stdDev; result.ZScore = (stdDev == 0) ? null : (h.Close - result.Sma) / stdDev; result.Width = (result.Sma == 0) ? null : (result.UpperBand - result.LowerBand) / result.Sma; } results.Add(result); } return(results); }