// ULTIMATE OSCILLATOR public static IEnumerable <UltimateResult> GetUltimate <TQuote>( IEnumerable <TQuote> history, int shortPeriod = 7, int middlePeriod = 14, int longPeriod = 28) where TQuote : IQuote { // clean quotes List <TQuote> historyList = history.Sort(); // check parameters ValidateUltimate(history, shortPeriod, middlePeriod, longPeriod); // initialize int size = historyList.Count; List <UltimateResult> results = new List <UltimateResult>(size); decimal[] bp = new decimal[size]; // buying pressure decimal[] tr = new decimal[size]; // true range decimal priorClose = 0; // roll through history for (int i = 0; i < historyList.Count; i++) { TQuote h = historyList[i]; int index = i + 1; UltimateResult r = new UltimateResult { Date = h.Date }; results.Add(r); if (i > 0) { bp[i] = h.Close - Math.Min(h.Low, priorClose); tr[i] = Math.Max(h.High, priorClose) - Math.Min(h.Low, priorClose); } if (index >= longPeriod + 1) { decimal sumBP1 = 0m; decimal sumBP2 = 0m; decimal sumBP3 = 0m; decimal sumTR1 = 0m; decimal sumTR2 = 0m; decimal sumTR3 = 0m; for (int p = index - longPeriod; p < index; p++) { int pIndex = p + 1; // short aggregate if (pIndex > index - shortPeriod) { sumBP1 += bp[p]; sumTR1 += tr[p]; } // middle aggregate if (pIndex > index - middlePeriod) { sumBP2 += bp[p]; sumTR2 += tr[p]; } // long aggregate sumBP3 += bp[p]; sumTR3 += tr[p]; } decimal?avg1 = (sumTR1 == 0) ? null : sumBP1 / sumTR1; decimal?avg2 = (sumTR2 == 0) ? null : sumBP2 / sumTR2; decimal?avg3 = (sumTR3 == 0) ? null : sumBP3 / sumTR3; r.Ultimate = 100 * (4m * avg1 + 2m * avg2 + avg3) / 7m; } priorClose = h.Close; } return(results); }
// ULTIMATE OSCILLATOR public static IEnumerable <UltimateResult> GetUltimate( IEnumerable <Quote> history, int shortPeriod = 7, int middlePeriod = 14, int longPeriod = 28) { // clean quotes List <Quote> historyList = Cleaners.PrepareHistory(history).ToList(); // check parameters ValidateUltimate(history, shortPeriod, middlePeriod, longPeriod); // initialize List <UltimateResult> results = new List <UltimateResult>(); decimal priorClose = 0; // roll through history for (int i = 0; i < historyList.Count; i++) { Quote h = historyList[i]; UltimateResult r = new UltimateResult { Index = (int)h.Index, Date = h.Date }; results.Add(r); if (i > 0) { r.Bp = h.Close - Math.Min(h.Low, priorClose); r.Tr = Math.Max(h.High, priorClose) - Math.Min(h.Low, priorClose); } if (h.Index >= longPeriod + 1) { decimal sumBP1 = 0m; decimal sumBP2 = 0m; decimal sumBP3 = 0m; decimal sumTR1 = 0m; decimal sumTR2 = 0m; decimal sumTR3 = 0m; for (int p = (int)h.Index - longPeriod; p < h.Index; p++) { UltimateResult pr = results[p]; // short aggregate if (pr.Index > h.Index - shortPeriod) { sumBP1 += (decimal)pr.Bp; sumTR1 += (decimal)pr.Tr; } // middle aggregate if (pr.Index > h.Index - middlePeriod) { sumBP2 += (decimal)pr.Bp; sumTR2 += (decimal)pr.Tr; } // long aggregate sumBP3 += (decimal)pr.Bp; sumTR3 += (decimal)pr.Tr; } decimal avg1 = sumBP1 / sumTR1; decimal avg2 = sumBP2 / sumTR2; decimal avg3 = sumBP3 / sumTR3; r.Ultimate = 100 * (4m * avg1 + 2m * avg2 + avg3) / 7m; } priorClose = h.Close; } return(results); }