public void GetStochRsiSlowTest() { int rsiPeriod = 14; int stochPeriod = 14; int signalPeriod = 3; int smoothPeriod = 3; IEnumerable <StochRsiResult> results = Indicator.GetStochRsi( history, rsiPeriod, stochPeriod, signalPeriod, smoothPeriod); // assertions // proper quantities Assert.AreEqual(502, results.Count()); Assert.AreEqual(502 - rsiPeriod - stochPeriod - smoothPeriod + 2, results.Where(x => x.StochRsi != null).Count()); Assert.AreEqual(502 - rsiPeriod - stochPeriod - signalPeriod - smoothPeriod + 3, results.Where(x => x.Signal != null).Count()); // this series starts with 2 periods of topped Stochastic RSI, so no direction can be determined Assert.AreEqual(502 - rsiPeriod - stochPeriod - smoothPeriod + 2 - 2, results.Where(x => x.IsIncreasing != null).Count()); // sample value StochRsiResult r = results.Where(x => x.Date == DateTime.Parse("12/31/2018")).FirstOrDefault(); Assert.AreEqual((decimal)89.8385, Math.Round((decimal)r.StochRsi, 4)); Assert.AreEqual((decimal)73.4176, Math.Round((decimal)r.Signal, 4)); Assert.AreEqual(true, r.IsIncreasing); }
public void Convergence() { foreach (int qty in convergeQuantities.Where(x => x <= 502)) { IEnumerable <Quote> h = HistoryTestData.Get(110 + qty); IEnumerable <StochRsiResult> r = Indicator.GetStochRsi(h, 14, 14, 3, 1); StochRsiResult l = r.LastOrDefault(); Console.WriteLine("SRSI on {0:d} with {1,4} periods: {2:N8}", l.Date, h.Count(), l.StochRsi); } }
public void StochRsi() { foreach (int qty in QuotesQuantities.Where(x => x <= 502)) { IEnumerable <Quote> quotes = TestData.GetDefault(10 + qty); IEnumerable <StochRsiResult> r = quotes.GetStochRsi(14, 14, 3, 1); StochRsiResult l = r.LastOrDefault(); Console.WriteLine( "SRSI on {0:d} with {1,4} periods: {2:N8}", l.Date, quotes.Count(), l.StochRsi); } }
public void GetStochRsiTest() { int lookbackPeriod = 14; IEnumerable <StochRsiResult> results = Indicator.GetStochRsi(history, lookbackPeriod); // assertions // proper quantities // should always be the same number of results as there is history Assert.AreEqual(502, results.Count()); Assert.AreEqual(502 - 2 * lookbackPeriod + 1, results.Where(x => x.StochRsi != null).Count()); Assert.AreEqual(502 - 2 * lookbackPeriod + 1, results.Where(x => x.IsIncreasing != null).Count()); // sample value StochRsiResult result = results.Where(x => x.Date == DateTime.Parse("12/31/2018")).FirstOrDefault(); Assert.AreEqual((decimal)0.9752, Math.Round((decimal)result.StochRsi, 4)); Assert.AreEqual(true, result.IsIncreasing); }
public void FastRsi() { int rsiPeriods = 14; int stochPeriods = 14; int signalPeriods = 3; int smoothPeriods = 1; List <StochRsiResult> results = quotes.GetStochRsi(rsiPeriods, stochPeriods, signalPeriods, smoothPeriods) .ToList(); // assertions // proper quantities Assert.AreEqual(502, results.Count); Assert.AreEqual(475, results.Where(x => x.StochRsi != null).Count()); Assert.AreEqual(473, results.Where(x => x.Signal != null).Count()); // sample values StochRsiResult r1 = results[31]; Assert.AreEqual(93.3333m, Math.Round((decimal)r1.StochRsi, 4)); Assert.AreEqual(97.7778m, Math.Round((decimal)r1.Signal, 4)); StochRsiResult r2 = results[152]; Assert.AreEqual(0m, Math.Round((decimal)r2.StochRsi, 4)); Assert.AreEqual(0m, Math.Round((decimal)r2.Signal, 4)); StochRsiResult r3 = results[249]; Assert.AreEqual(36.5517m, Math.Round((decimal)r3.StochRsi, 4)); Assert.AreEqual(27.3094m, Math.Round((decimal)r3.Signal, 4)); StochRsiResult r4 = results[501]; Assert.AreEqual(97.5244m, Math.Round((decimal)r4.StochRsi, 4)); Assert.AreEqual(89.8385m, Math.Round((decimal)r4.Signal, 4)); }
public void SlowRsi() { int rsiPeriods = 14; int stochPeriods = 14; int signalPeriods = 3; int smoothPeriods = 3; List <StochRsiResult> results = Indicator.GetStochRsi(quotes, rsiPeriods, stochPeriods, signalPeriods, smoothPeriods) .ToList(); // assertions // proper quantities Assert.AreEqual(502, results.Count); Assert.AreEqual(473, results.Where(x => x.StochRsi != null).Count()); Assert.AreEqual(471, results.Where(x => x.Signal != null).Count()); // sample values StochRsiResult r1 = results[31]; Assert.AreEqual(97.7778m, Math.Round((decimal)r1.StochRsi, 4)); Assert.AreEqual(99.2593m, Math.Round((decimal)r1.Signal, 4)); StochRsiResult r2 = results[152]; Assert.AreEqual(0m, Math.Round((decimal)r2.StochRsi, 4)); Assert.AreEqual(20.0263m, Math.Round((decimal)r2.Signal, 4)); StochRsiResult r3 = results[249]; Assert.AreEqual(27.3094m, Math.Round((decimal)r3.StochRsi, 4)); Assert.AreEqual(33.2716m, Math.Round((decimal)r3.Signal, 4)); StochRsiResult r4 = results[501]; Assert.AreEqual(89.8385m, Math.Round((decimal)r4.StochRsi, 4)); Assert.AreEqual(73.4176m, Math.Round((decimal)r4.Signal, 4)); }
public void Removed() { int rsiPeriods = 14; int stochPeriods = 14; int signalPeriods = 3; int smoothPeriods = 3; List <StochRsiResult> results = Indicator.GetStochRsi(quotes, rsiPeriods, stochPeriods, signalPeriods, smoothPeriods) .RemoveWarmupPeriods() .ToList(); // assertions int removeQty = rsiPeriods + stochPeriods + smoothPeriods + 100; Assert.AreEqual(502 - removeQty, results.Count); StochRsiResult last = results.LastOrDefault(); Assert.AreEqual(89.8385m, Math.Round((decimal)last.StochRsi, 4)); Assert.AreEqual(73.4176m, Math.Round((decimal)last.Signal, 4)); }
public void GetStochRsiSlowTest() { int rsiPeriod = 14; int stochPeriod = 14; int signalPeriod = 3; int smoothPeriod = 3; IEnumerable <StochRsiResult> results = Indicator.GetStochRsi( history, rsiPeriod, stochPeriod, signalPeriod, smoothPeriod); // assertions // proper quantities Assert.AreEqual(502, results.Count()); Assert.AreEqual(502 - rsiPeriod - stochPeriod - smoothPeriod + 2, results.Where(x => x.StochRsi != null).Count()); Assert.AreEqual(502 - rsiPeriod - stochPeriod - signalPeriod - smoothPeriod + 3, results.Where(x => x.Signal != null).Count()); // sample value StochRsiResult r = results.Where(x => x.Index == 502).FirstOrDefault(); Assert.AreEqual(89.8385m, Math.Round((decimal)r.StochRsi, 4)); Assert.AreEqual(73.4176m, Math.Round((decimal)r.Signal, 4)); }
public static void Main() { // See ConsoleApp first. This is more advanced. /* This is a basic 20-year backtest-style analysis of * Stochastic RSI. It will buy-to-open (BTO) one share * when the Stoch RSI (%K) is below 20 and crosses over the * Signal (%D). The reverse Sell-to-Close (STC) and * Sell-To-Open (STO) occurs when the Stoch RSI is above 80 and * crosses below the Signal. * * As a result, there will always be one open LONG or SHORT * position that is opened and closed at signal crossover * points in the overbought and oversold regions of the indicator. */ // fetch historical quotes from data provider List <Quote> quotesList = GetHistoryFromFeed() .ToList(); // calculate Stochastic RSI List <StochRsiResult> resultsList = quotesList .GetStochRsi(14, 14, 3, 1) .ToList(); // initialize decimal trdPrice = 0; decimal trdQty = 0; decimal rlzGain = 0; Console.WriteLine(" Date Close StRSI Signal Cross Net Gains"); Console.WriteLine("-------------------------------------------------------"); // roll through history for (int i = 1; i < quotesList.Count; i++) { Quote q = quotesList[i]; StochRsiResult e = resultsList[i]; // evaluation period StochRsiResult l = resultsList[i - 1]; // last (prior) period string cross = string.Empty; // unrealized gain on open trade decimal trdGain = trdQty * (q.Close - trdPrice); // check for LONG event // condition: Stoch RSI was <= 20 and Stoch RSI crosses over Signal if (l.StochRsi <= 20 && l.StochRsi < l.Signal && e.StochRsi >= e.Signal && trdQty != 1) { // emulates BTC + BTO rlzGain += trdGain; trdQty = 1; trdPrice = q.Close; cross = "LONG"; } // check for SHORT event // condition: Stoch RSI was >= 80 and Stoch RSI crosses under Signal if (l.StochRsi >= 80 && l.StochRsi > l.Signal && e.StochRsi <= e.Signal && trdQty != -1) { // emulates STC + STO rlzGain += trdGain; trdQty = -1; trdPrice = q.Close; cross = "SHORT"; } if (cross != string.Empty) { Console.WriteLine( $"{q.Date,10:yyyy-MM-dd} " + $"{q.Close,10:c2}" + $"{e.StochRsi,7:N1}" + $"{e.Signal,7:N1}" + $"{cross,7}" + $"{rlzGain + trdGain,13:c2}"); } } }