// STOCHASTIC RSI public static IEnumerable <StochRsiResult> GetStochRsi <TQuote>( IEnumerable <TQuote> history, int rsiPeriod, int stochPeriod, int signalPeriod, int smoothPeriod = 1) where TQuote : IQuote { // validate parameters ValidateStochRsi(history, rsiPeriod, stochPeriod, signalPeriod, smoothPeriod); // initialize List <StochRsiResult> results = new List <StochRsiResult>(); // get RSI List <RsiResult> rsiResults = GetRsi(history, rsiPeriod).ToList(); // convert rsi to quote format List <Quote> rsiQuotes = rsiResults .Where(x => x.Rsi != null) .Select(x => new Quote { Date = x.Date, High = (decimal)x.Rsi, Low = (decimal)x.Rsi, Close = (decimal)x.Rsi }) .ToList(); // get Stochastic of RSI List <StochResult> stoResults = GetStoch(rsiQuotes, stochPeriod, signalPeriod, smoothPeriod).ToList(); // compose for (int i = 0; i < rsiResults.Count; i++) { RsiResult r = rsiResults[i]; int index = i + 1; StochRsiResult result = new StochRsiResult { Date = r.Date }; if (index >= rsiPeriod + stochPeriod) { StochResult sto = stoResults[index - rsiPeriod - 1]; result.StochRsi = sto.Oscillator; result.Signal = sto.Signal; } results.Add(result); } return(results); }
// RELATIVE STRENGTH INDEX public static IEnumerable <RsiResult> GetRsi(IEnumerable <Quote> history, int lookbackPeriod = 14) { // clean quotes history = Cleaners.PrepareHistory(history); // initialize decimal lastClose = history.First().Close; List <RsiResult> results = new List <RsiResult>(); // load gain data foreach (Quote h in history) { RsiResult result = new RsiResult { Index = (int)h.Index, Date = h.Date, Gain = (lastClose < h.Close) ? (float)(h.Close - lastClose) : 0, Loss = (lastClose > h.Close) ? (float)(lastClose - h.Close) : 0 }; results.Add(result); lastClose = h.Close; } // initialize average gain float avgGain = results.Where(x => x.Index <= lookbackPeriod).Select(g => g.Gain).Average(); float avgLoss = results.Where(x => x.Index <= lookbackPeriod).Select(g => g.Loss).Average(); // initial RSI for trend analysis float lastRSI = (avgLoss > 0) ? 100 - (100 / (1 + (avgGain / avgLoss))) : 100; // calculate RSI foreach (RsiResult r in results.Where(x => x.Index >= lookbackPeriod).OrderBy(d => d.Index)) { avgGain = (avgGain * (lookbackPeriod - 1) + r.Gain) / lookbackPeriod; avgLoss = (avgLoss * (lookbackPeriod - 1) + r.Loss) / lookbackPeriod; if (avgLoss > 0) { float rs = avgGain / avgLoss; r.Rsi = 100 - (100 / (1 + rs)); } else { r.Rsi = 100; } r.IsIncreasing = (r.Rsi >= lastRSI) ? true : false; lastRSI = (float)r.Rsi; } return(results); }
// CONNORS RSI /// <include file='./info.xml' path='indicator/*' /> /// public static IEnumerable <ConnorsRsiResult> GetConnorsRsi <TQuote>( IEnumerable <TQuote> history, int rsiPeriod = 3, int streakPeriod = 2, int rankPeriod = 100) where TQuote : IQuote { // convert history to basic format List <BasicData> bdList = history.ConvertToBasic("C"); // check parameter arguments ValidateConnorsRsi(bdList, rsiPeriod, streakPeriod, rankPeriod); // initialize List <ConnorsRsiResult> results = CalcConnorsRsiBaseline(bdList, rsiPeriod, rankPeriod); int startPeriod = Math.Max(rsiPeriod, Math.Max(streakPeriod, rankPeriod)) + 2; // RSI of streak List <BasicData> bdStreak = results .Where(x => x.Streak != null) .Select(x => new BasicData { Date = x.Date, Value = (decimal)x.Streak }) .ToList(); List <RsiResult> rsiStreakResults = CalcRsi(bdStreak, streakPeriod).ToList(); // compose final results for (int p = streakPeriod + 2; p < results.Count; p++) { ConnorsRsiResult r = results[p]; RsiResult k = rsiStreakResults[p - 1]; r.RsiStreak = k.Rsi; if (p + 1 >= startPeriod) { r.ConnorsRsi = (r.RsiClose + r.RsiStreak + r.PercentRank) / 3; } } return(results); }
private static IEnumerable <RsiResult> CalcRsi(List <BasicData> bdList, int lookbackPeriod = 14) { // check parameter arguments ValidateRsi(bdList, lookbackPeriod); // initialize decimal lastValue = bdList[0].Value; decimal avgGain = 0m; decimal avgLoss = 0m; int size = bdList.Count; List <RsiResult> results = new List <RsiResult>(size); decimal[] gain = new decimal[size]; // gain decimal[] loss = new decimal[size]; // loss // roll through history for (int i = 0; i < bdList.Count; i++) { BasicData h = bdList[i]; int index = i + 1; RsiResult r = new RsiResult { Date = h.Date }; results.Add(r); gain[i] = (h.Value > lastValue) ? h.Value - lastValue : 0; loss[i] = (h.Value < lastValue) ? lastValue - h.Value : 0; lastValue = h.Value; // calculate RSI if (index > lookbackPeriod + 1) { avgGain = (avgGain * (lookbackPeriod - 1) + gain[i]) / lookbackPeriod; avgLoss = (avgLoss * (lookbackPeriod - 1) + loss[i]) / lookbackPeriod; if (avgLoss > 0) { decimal rs = avgGain / avgLoss; r.Rsi = 100 - (100 / (1 + rs)); } else { r.Rsi = 100; } } // initialize average gain else if (index == lookbackPeriod + 1) { decimal sumGain = 0; decimal sumLoss = 0; for (int p = 1; p <= lookbackPeriod; p++) { sumGain += gain[p]; sumLoss += loss[p]; } avgGain = sumGain / lookbackPeriod; avgLoss = sumLoss / lookbackPeriod; r.Rsi = (avgLoss > 0) ? 100 - (100 / (1 + (avgGain / avgLoss))) : 100; } } return(results); }
// RELATIVE STRENGTH INDEX public static IEnumerable <RsiResult> GetRsi(IEnumerable <Quote> history, int lookbackPeriod = 14) { // 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 RSI. " + string.Format("You provided {0} periods of history when {1} is required. " + "Since this uses a smoothing technique, " + "we recommend you use at least 250 data points prior to the intended " + "usage date for maximum precision.", qtyHistory, minHistory)); } // initialize decimal lastClose = history.First().Close; List <RsiResult> results = new List <RsiResult>(); // load gain data foreach (Quote h in history) { RsiResult result = new RsiResult { Index = (int)h.Index, Date = h.Date, Gain = (lastClose < h.Close) ? (float)(h.Close - lastClose) : 0, Loss = (lastClose > h.Close) ? (float)(lastClose - h.Close) : 0 }; results.Add(result); lastClose = h.Close; } // initialize average gain float avgGain = results.Where(x => x.Index <= lookbackPeriod).Select(g => g.Gain).Average(); float avgLoss = results.Where(x => x.Index <= lookbackPeriod).Select(g => g.Loss).Average(); // initial RSI for trend analysis float lastRSI = (avgLoss > 0) ? 100 - (100 / (1 + (avgGain / avgLoss))) : 100; // calculate RSI foreach (RsiResult r in results.Where(x => x.Index >= lookbackPeriod).OrderBy(d => d.Index)) { avgGain = (avgGain * (lookbackPeriod - 1) + r.Gain) / lookbackPeriod; avgLoss = (avgLoss * (lookbackPeriod - 1) + r.Loss) / lookbackPeriod; if (avgLoss > 0) { float rs = avgGain / avgLoss; r.Rsi = 100 - (100 / (1 + rs)); } else { r.Rsi = 100; } r.IsIncreasing = (r.Rsi > lastRSI); lastRSI = (float)r.Rsi; } return(results); }
private static IEnumerable <RsiResult> CalcRsi(IEnumerable <BasicData> basicData, int lookbackPeriod = 14) { // clean data List <BasicData> bdList = Cleaners.PrepareBasicData(basicData).ToList(); // check parameters ValidateRsi(basicData, lookbackPeriod); // initialize decimal lastValue = bdList[0].Value; decimal avgGain = 0m; decimal avgLoss = 0m; List <RsiResult> results = new List <RsiResult>(); // roll through history for (int i = 0; i < bdList.Count; i++) { BasicData h = bdList[i]; RsiResult r = new RsiResult { Index = (int)h.Index, Date = h.Date, Gain = (h.Value > lastValue) ? h.Value - lastValue : 0, Loss = (h.Value < lastValue) ? lastValue - h.Value : 0 }; results.Add(r); lastValue = h.Value; // calculate RSI if (h.Index > lookbackPeriod + 1) { avgGain = (avgGain * (lookbackPeriod - 1) + r.Gain) / lookbackPeriod; avgLoss = (avgLoss * (lookbackPeriod - 1) + r.Loss) / lookbackPeriod; if (avgLoss > 0) { decimal rs = avgGain / avgLoss; r.Rsi = 100 - (100 / (1 + rs)); } else { r.Rsi = 100; } } // initialize average gain else if (h.Index == lookbackPeriod + 1) { decimal sumGain = 0; decimal sumLoss = 0; for (int p = 0; p < lookbackPeriod; p++) { RsiResult d = results[p]; sumGain += d.Gain; sumLoss += d.Loss; } avgGain = sumGain / lookbackPeriod; avgLoss = sumLoss / lookbackPeriod; r.Rsi = (avgLoss > 0) ? 100 - (100 / (1 + (avgGain / avgLoss))) : 100; } } return(results); }
private static IEnumerable <RsiResult> CalcRsi(IEnumerable <BasicData> basicData, int lookbackPeriod = 14) { // clean data List <BasicData> bdList = Cleaners.PrepareBasicData(basicData).ToList(); // check parameters ValidateRsi(basicData, lookbackPeriod); // initialize decimal lastValue = bdList[0].Value; List <RsiResult> results = new List <RsiResult>(); // load gain data for (int i = 0; i < bdList.Count; i++) { BasicData h = bdList[i]; RsiResult result = new RsiResult { Index = (int)h.Index, Date = h.Date, Gain = (h.Value > lastValue) ? h.Value - lastValue : 0, Loss = (h.Value < lastValue) ? lastValue - h.Value : 0 }; results.Add(result); lastValue = h.Value; } // initialize average gain decimal avgGain = results.Where(x => x.Index <= lookbackPeriod).Select(g => g.Gain).Average(); decimal avgLoss = results.Where(x => x.Index <= lookbackPeriod).Select(g => g.Loss).Average(); // initial first record decimal lastRSI = (avgLoss > 0) ? 100 - (100 / (1 + (avgGain / avgLoss))) : 100; RsiResult first = results.Where(x => x.Index == lookbackPeriod + 1).FirstOrDefault(); first.Rsi = lastRSI; // calculate RSI foreach (RsiResult r in results.Where(x => x.Index > (lookbackPeriod + 1))) { avgGain = (avgGain * (lookbackPeriod - 1) + r.Gain) / lookbackPeriod; avgLoss = (avgLoss * (lookbackPeriod - 1) + r.Loss) / lookbackPeriod; if (avgLoss > 0) { decimal rs = avgGain / avgLoss; r.Rsi = 100 - (100 / (1 + rs)); } else { r.Rsi = 100; } lastRSI = (decimal)r.Rsi; } return(results); }
private static IEnumerable <RsiResult> CalcRsi(IEnumerable <BasicData> basicData, int lookbackPeriod = 14) { // clean data basicData = Cleaners.PrepareBasicData(basicData); // check parameters ValidateRsi(basicData, lookbackPeriod); // initialize decimal lastValue = basicData.First().Value; List <RsiResult> results = new List <RsiResult>(); // load gain data foreach (BasicData h in basicData) { RsiResult result = new RsiResult { Index = (int)h.Index, Date = h.Date, Gain = (h.Value > lastValue) ? h.Value - lastValue : 0, Loss = (h.Value < lastValue) ? lastValue - h.Value : 0 }; results.Add(result); lastValue = h.Value; } // initialize average gain decimal avgGain = results.Where(x => x.Index <= lookbackPeriod).Select(g => g.Gain).Average(); decimal avgLoss = results.Where(x => x.Index <= lookbackPeriod).Select(g => g.Loss).Average(); // initial first record decimal lastRSI = (avgLoss > 0) ? 100 - (100 / (1 + (avgGain / avgLoss))) : 100; bool? lastIsIncreasing = null; RsiResult first = results.Where(x => x.Index == lookbackPeriod + 1).FirstOrDefault(); first.Rsi = lastRSI; // calculate RSI foreach (RsiResult r in results.Where(x => x.Index > (lookbackPeriod + 1)).OrderBy(d => d.Index)) { avgGain = (avgGain * (lookbackPeriod - 1) + r.Gain) / lookbackPeriod; avgLoss = (avgLoss * (lookbackPeriod - 1) + r.Loss) / lookbackPeriod; if (avgLoss > 0) { decimal rs = avgGain / avgLoss; r.Rsi = 100 - (100 / (1 + rs)); } else { r.Rsi = 100; } if (r.Rsi > lastRSI) { r.IsIncreasing = true; } else if (r.Rsi < lastRSI) { r.IsIncreasing = false; } else { // no change, keep trend r.IsIncreasing = lastIsIncreasing; } lastRSI = (decimal)r.Rsi; lastIsIncreasing = r.IsIncreasing; } return(results); }