// PRICE RELATIVE STRENGTH public static IEnumerable <PrsResult> GetPrs( IEnumerable <Quote> historyBase, IEnumerable <Quote> historyEval, int?smaPeriod = null) { // clean quotes List <Quote> historyBaseList = Cleaners.PrepareHistory(historyBase).ToList(); List <Quote> historyEvalList = Cleaners.PrepareHistory(historyEval).ToList(); // validate parameters ValidatePriceRelative(historyBase, historyEval, smaPeriod); // initialize List <PrsResult> results = new List <PrsResult>(); // roll through history for interim data for (int i = 0; i < historyEvalList.Count; i++) { Quote b = historyBaseList[i]; Quote e = historyEvalList[i]; if (e.Date != b.Date) { throw new BadHistoryException( "Date sequence does not match. Price Relative requires matching dates in provided histories."); } PrsResult r = new PrsResult { Index = (int)e.Index, Date = e.Date, Prs = e.Close / b.Close // relative strength }; results.Add(r); if (smaPeriod != null && r.Index >= smaPeriod) { // get average over lookback decimal sumRs = 0m; for (int p = r.Index - (int)smaPeriod; p < r.Index; p++) { PrsResult d = results[p]; sumRs += (decimal)d.Prs; } r.Sma = sumRs / smaPeriod; } } return(results); }
// PRICE RELATIVE STRENGTH public static IEnumerable <PrsResult> GetPrs <TQuote>( IEnumerable <TQuote> historyBase, IEnumerable <TQuote> historyEval, int?lookbackPeriod = null, int?smaPeriod = null) where TQuote : IQuote { // clean quotes List <TQuote> historyBaseList = historyBase.Sort(); List <TQuote> historyEvalList = historyEval.Sort(); // validate parameters ValidatePriceRelative(historyBase, historyEval, lookbackPeriod, smaPeriod); // initialize List <PrsResult> results = new List <PrsResult>(historyEvalList.Count); // roll through history for interim data for (int i = 0; i < historyEvalList.Count; i++) { TQuote bi = historyBaseList[i]; TQuote ei = historyEvalList[i]; int index = i + 1; if (ei.Date != bi.Date) { throw new BadHistoryException(nameof(historyEval), ei.Date, "Date sequence does not match. Price Relative requires matching dates in provided histories."); } PrsResult r = new PrsResult { Date = ei.Date, Prs = (bi.Close == 0) ? null : ei.Close / bi.Close // relative strength ratio }; results.Add(r); if (lookbackPeriod != null && index > lookbackPeriod) { TQuote bo = historyBaseList[i - (int)lookbackPeriod]; TQuote eo = historyEvalList[i - (int)lookbackPeriod]; if (bo.Close != 0 && eo.Close != 0) { decimal pctB = (bi.Close - bo.Close) / bo.Close; decimal pctE = (ei.Close - eo.Close) / eo.Close; r.PrsPercent = pctE - pctB; } } // optional moving average of PRS if (smaPeriod != null && index >= smaPeriod) { decimal?sumRs = 0m; for (int p = index - (int)smaPeriod; p < index; p++) { PrsResult d = results[p]; sumRs += d.Prs; } r.PrsSma = sumRs / smaPeriod; } } return(results); }
// PRICE RELATIVE STRENGTH public static IEnumerable <PrsResult> GetPrs( IEnumerable <Quote> historyBase, IEnumerable <Quote> historyEval, int?lookbackPeriod = null, int?smaPeriod = null) { // clean quotes List <Quote> historyBaseList = Cleaners.PrepareHistory(historyBase).ToList(); List <Quote> historyEvalList = Cleaners.PrepareHistory(historyEval).ToList(); // validate parameters ValidatePriceRelative(historyBase, historyEval, lookbackPeriod, smaPeriod); // initialize List <PrsResult> results = new List <PrsResult>(); // roll through history for interim data for (int i = 0; i < historyEvalList.Count; i++) { Quote bi = historyBaseList[i]; Quote ei = historyEvalList[i]; if (ei.Date != bi.Date) { throw new BadHistoryException( "Date sequence does not match. Price Relative requires matching dates in provided histories."); } PrsResult r = new PrsResult { Index = (int)ei.Index, Date = ei.Date, Prs = ei.Close / bi.Close // relative strength ratio }; results.Add(r); if (lookbackPeriod != null && r.Index > lookbackPeriod) { Quote bo = historyBaseList[i - (int)lookbackPeriod]; Quote eo = historyEvalList[i - (int)lookbackPeriod]; if (bo.Close != 0 && eo.Close != 0) { decimal pctB = (bi.Close - bo.Close) / bo.Close; decimal pctE = (ei.Close - eo.Close) / eo.Close; r.PrsPercent = pctE - pctB; } } // optional moving average of PRS if (smaPeriod != null && r.Index >= smaPeriod) { decimal sumRs = 0m; for (int p = r.Index - (int)smaPeriod; p < r.Index; p++) { PrsResult d = results[p]; sumRs += (decimal)d.Prs; } r.Sma = sumRs / smaPeriod; } } return(results); }