// AROON OSCILLATOR public static IEnumerable <AroonResult> GetAroon <TQuote>( IEnumerable <TQuote> history, int lookbackPeriod = 25) where TQuote : IQuote { // sort history List <TQuote> historyList = history.Sort(); // check parameter arguments ValidateAroon(history, lookbackPeriod); // initialize List <AroonResult> results = new List <AroonResult>(historyList.Count); // roll through history for (int i = 0; i < historyList.Count; i++) { TQuote h = historyList[i]; int index = i + 1; AroonResult result = new AroonResult { Date = h.Date }; // add aroons if (index > lookbackPeriod) { decimal lastHighPrice = 0; decimal lastLowPrice = decimal.MaxValue; int lastHighIndex = 0; int lastLowIndex = 0; for (int p = index - lookbackPeriod - 1; p < index; p++) { TQuote d = historyList[p]; if (d.High > lastHighPrice) { lastHighPrice = d.High; lastHighIndex = p + 1; } if (d.Low < lastLowPrice) { lastLowPrice = d.Low; lastLowIndex = p + 1; } } result.AroonUp = 100 * (decimal)(lookbackPeriod - (index - lastHighIndex)) / lookbackPeriod; result.AroonDown = 100 * (decimal)(lookbackPeriod - (index - lastLowIndex)) / lookbackPeriod; result.Oscillator = result.AroonUp - result.AroonDown; } results.Add(result); } return(results); }
// AROON OSCILLATOR public static IEnumerable <AroonResult> GetAroon(IEnumerable <Quote> history, int lookbackPeriod = 25) { // clean quotes List <Quote> historyList = Cleaners.PrepareHistory(history).ToList(); // validate parameters ValidateAroon(history, lookbackPeriod); // initialize List <AroonResult> results = new List <AroonResult>(); // roll through history for (int i = 0; i < historyList.Count; i++) { Quote h = historyList[i]; AroonResult result = new AroonResult { Index = (int)h.Index, Date = h.Date }; // add aroons if (h.Index > lookbackPeriod) { decimal lastHighPrice = 0; decimal lastLowPrice = decimal.MaxValue; int lastHighIndex = 0; int lastLowIndex = 0; for (int p = (int)h.Index - lookbackPeriod - 1; p < h.Index; p++) { Quote d = historyList[p]; if (d.High > lastHighPrice) { lastHighPrice = d.High; lastHighIndex = (int)d.Index; } if (d.Low < lastLowPrice) { lastLowPrice = d.Low; lastLowIndex = (int)d.Index; } } result.AroonUp = 100 * (decimal)(lookbackPeriod - (h.Index - lastHighIndex)) / lookbackPeriod; result.AroonDown = 100 * (decimal)(lookbackPeriod - (h.Index - lastLowIndex)) / lookbackPeriod; result.Oscillator = result.AroonUp - result.AroonDown; } results.Add(result); } return(results); }
// AROON OSCILLATOR public static IEnumerable <AroonResult> GetAroon(IEnumerable <Quote> history, int lookbackPeriod = 25) { // clean quotes Cleaners.PrepareHistory(history); // validate parameters ValidateAroon(history, lookbackPeriod); // initialize List <Quote> historyList = history.ToList(); List <AroonResult> results = new List <AroonResult>(); // roll through history for (int i = 0; i < historyList.Count; i++) { Quote h = historyList[i]; AroonResult result = new AroonResult { Index = (int)h.Index, Date = h.Date }; // add aroons if (h.Index >= lookbackPeriod) { List <Quote> period = historyList .Where(x => x.Index <= h.Index && x.Index > (h.Index - lookbackPeriod)) .ToList(); decimal lastHighPrice = period.Select(x => x.High).Max(); decimal lastLowPrice = period.Select(x => x.Low).Min(); int lastHighIndex = period .Where(x => x.High == lastHighPrice) .OrderBy(x => x.Index) // implies "new" high, so not picking new tie for high .Select(x => (int)x.Index) .FirstOrDefault(); int lastLowIndex = period .Where(x => x.Low == lastLowPrice) .OrderBy(x => x.Index) .Select(x => (int)x.Index) .FirstOrDefault(); result.AroonUp = 100 * (decimal)(lookbackPeriod - (h.Index - lastHighIndex)) / lookbackPeriod; result.AroonDown = 100 * (decimal)(lookbackPeriod - (h.Index - lastLowIndex)) / lookbackPeriod; result.Oscillator = result.AroonUp - result.AroonDown; } results.Add(result); } return(results); }
// AROON OSCILLATOR public static IEnumerable <AroonResult> GetAroon(IEnumerable <Quote> history, int lookbackPeriod = 25) { // clean quotes history = Cleaners.PrepareHistory(history); // exceptions if (lookbackPeriod <= 0) { throw new BadParameterException("Lookback period must be greater than 0 for Aroon."); } int qtyHistory = history.Count(); int minHistory = lookbackPeriod; if (qtyHistory < minHistory) { throw new BadHistoryException("Insufficient history provided for Aroon. " + string.Format("You provided {0} periods of history when {1} is required.", qtyHistory, minHistory)); } // initialize List <AroonResult> results = new List <AroonResult>(); // roll through history foreach (Quote h in history) { AroonResult result = new AroonResult { Index = (int)h.Index, Date = h.Date }; // add aroons if (h.Index >= lookbackPeriod) { IEnumerable <Quote> period = history .Where(x => x.Index <= h.Index && x.Index > (h.Index - lookbackPeriod)); decimal lastHighPrice = period.Select(x => x.High).Max(); decimal lastLowPrice = period.Select(x => x.Low).Min(); int lastHighIndex = period .Where(x => x.High == lastHighPrice) .OrderBy(x => x.Index) // implies "new" high, so not picking new tie for high .Select(x => (int)x.Index) .FirstOrDefault(); int lastLowIndex = period .Where(x => x.Low == lastLowPrice) .OrderBy(x => x.Index) .Select(x => (int)x.Index) .FirstOrDefault(); result.AroonUp = 100 * (decimal)(lookbackPeriod - (h.Index - lastHighIndex)) / lookbackPeriod; result.AroonDown = 100 * (decimal)(lookbackPeriod - (h.Index - lastLowIndex)) / lookbackPeriod; result.Oscillator = result.AroonUp - result.AroonDown; } results.Add(result); } return(results); }