예제 #1
0
        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);
        }
예제 #2
0
        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);
            }
        }
예제 #3
0
    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);
        }
    }
예제 #4
0
        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);
        }
예제 #5
0
    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));
    }
예제 #6
0
    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));
    }
예제 #7
0
    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));
        }
예제 #9
0
    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}");
            }
        }
    }