Navigation

    Backtrader Community

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

    Stochastic RSI indicator.

    Indicators/Strategies/Analyzers
    5
    10
    3903
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Nikolai
      Nikolai last edited by Nikolai

      Hi colleagues.
      I've finished stoch RSI indicator and i would like to share it. It has the same K & D values as the Tradingview stoch RSI.
      https://www.tradingview.com/wiki/Stochastic_RSI_(STOCH_RSI)

      My applauds to the Backtrader developers team - excellent platform. Any comments are welcome.

      from backtrader.indicators import Indicator, MovAv, RelativeStrengthIndex, Highest, Lowest
      class StochasticRSI(Indicator):
            """
            K - The time period to be used in calculating the %K. 3 is the default.
            D - The time period to be used in calculating the %D. 3 is the default.
            RSI Length - The time period to be used in calculating the RSI
            Stochastic Length - The time period to be used in calculating the Stochastic
        
            Formula:
            %K = SMA(100 * (RSI(n) - RSI Lowest Low(n)) / (RSI HighestHigh(n) - RSI LowestLow(n)), smoothK)
            %D = SMA(%K, periodD)
        
            """
            lines = ('fastk', 'fastd',)
        
            params = (
                ('k_period', 3),
                ('d_period', 3),
                ('rsi_period', 14),
                ('stoch_period', 14),
                ('movav', MovAv.Simple),
                ('rsi', RelativeStrengthIndex),
                ('upperband', 80.0),
                ('lowerband', 20.0),
            )
        
            plotlines = dict(percD=dict(_name='%D', ls='--'),
                             percK=dict(_name='%K'))
        
            def _plotlabel(self):
                plabels = [self.p.k_period, self.p.d_period, self.p.rsi_period, self.p.stoch_period]
                plabels += [self.p.movav] * self.p.notdefault('movav')
                return plabels
        
            def _plotinit(self):
                self.plotinfo.plotyhlines = [self.p.upperband, self.p.lowerband]
        
            def __init__(self):
                rsi_hh = Highest(self.p.rsi(period=self.p.rsi_period), period=self.p.stoch_period)
                rsi_ll = Lowest(self.p.rsi(period=self.p.rsi_period), period=self.p.stoch_period)
                knum = self.p.rsi(period=self.p.rsi_period) - rsi_ll
                kden = rsi_hh - rsi_ll
        
                self.k = self.p.movav(100.0 * (knum / kden), period=self.p.k_period)
                self.d = self.p.movav(self.k, period=self.p.d_period)
        
                self.lines.fastk = self.k
                self.lines.fastd = self.d
      
      Marx Babu 1 Reply Last reply Reply Quote 3
      • A
        ab_trader last edited by

        Thank you!

        What is the difference between your implementation and bt built-in implementation?

        • If my answer helped, hit reputation up arrow at lower right corner of the post.
        • Python Debugging With Pdb
        • New to python and bt - check this out
        Nikolai 1 Reply Last reply Reply Quote 0
        • Nikolai
          Nikolai @ab_trader last edited by

          @ab_trader
          I did not find StochRSI in bt. As i see, it has only Stochastic and RSI as a separate indicators. TA-lib StochRSI has K & D values other than Tradingview.
          Tradingview (TV) is a rapidly growing JS framwork. The goal was to receive exact the same values as TV.

          1 Reply Last reply Reply Quote 0
          • B
            backtrader administrators last edited by

            StochRSI is a well known indicator, not something which has been invented by Tradingview.

            • https://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:stochrsi

            You probably want to rewrite this

            @nikolai said in Stochastic RSI indicator.:

                  def __init__(self):
                      rsi_hh = Highest(self.p.rsi(period=self.p.rsi_period), period=self.p.stoch_period)
                      rsi_ll = Lowest(self.p.rsi(period=self.p.rsi_period), period=self.p.stoch_period)
                      knum = self.p.rsi(period=self.p.rsi_period) - rsi_ll
                      kden = rsi_hh - rsi_ll
              
                      self.k = self.p.movav(100.0 * (knum / kden), period=self.p.k_period)
                      self.d = self.p.movav(self.k, period=self.p.d_period)
              
                      self.lines.fastk = self.k
                      self.lines.fastd = self.d
            

            to look like this (and avoid unnecessary instantiation of multiple indicators and unneeded member attributes)

                def __init__(self):
                    rsi = bt.ind.RSI(period=self.p.rsi_period)
                    rsi_ll = bt.ind.Lowest(rsi, period=self.p.rsi_period)
                    rsi_hh = bt.ind.Highest(rsi, period=self.p.rsi_period)
                    stochrsi = (rsi - rsi_ll) / (rsi_hh - rsi_ll)
            
                    self.l.fastk = k = self.p.movav(100.0 * stochrsi, period=self.p.k_period)
                    self.l.fastd = self.p.movav(k, period=self.p.d_period)
            
            1 Reply Last reply Reply Quote 2
            • Nikolai
              Nikolai last edited by Nikolai

              @backtrader, thanks for help with the code. Tradingview didn't invent StochRSI of course. Their docs are a bit messy for this indicator. So, the goal was to get the same implementation.

              1 Reply Last reply Reply Quote 0
              • Marx Babu
                Marx Babu @Nikolai last edited by

                @nikolai Does this give output in pandas dataframe (dateseries format output).
                What is the input used here ohlc data of each day ,hour ?
                I am keen to try this out as i am trying to build the one that exactly gives tv matching output.

                Please reply back what shall be the changes here to be done to get the output as pandas data frame.

                my email mbmarx gmail if you wish to share the code snippet please help.

                Nikolai 1 Reply Last reply Reply Quote 0
                • B
                  backtrader administrators last edited by

                  @marx-babu said in Stochastic RSI indicator.:

                  Does this give output in pandas dataframe (dateseries format output)

                  No. For the simple reason that backtrader isn't pandas. You may execute backtrader on a step by step basis (needed for live trading of course), in which case it doesn't make any sense to get a dataframe as the output of anything, given the inflexibility of a dataframe to dynamically grow.

                  @marx-babu said in Stochastic RSI indicator.:

                  Please reply back what shall be the changes here to be done to get the output as pandas data frame.

                  There are no changes to be done. All you can do is run the complete backtest and then transform the data to be imported into a dataframe if you wish.

                  1 Reply Last reply Reply Quote 0
                  • Nikolai
                    Nikolai @Marx Babu last edited by Nikolai

                    @marx-babu This is all code you need. But it works only as backtrader indicator. Feel free to use it, but you will need to understand how backtrader framework works.

                    1 Reply Last reply Reply Quote 0
                    • T
                      Tomas last edited by

                      Im new to backtrader and still trying to get the hang of it. How would I go about calling the fastk and fastd lines in my strategy? Doing StochasticRSI.lines.fastk throws me an attribute error (AttributeError: 'NoneType' object has no attribute 'lines').

                      Nikolai 1 Reply Last reply Reply Quote 0
                      • Nikolai
                        Nikolai @Tomas last edited by Nikolai

                        @Tomas
                        Hi. I wrote an example strategy for you. You can access the indicator lines through the name in __init__ method.

                        class CryptoStochRSI(bt.Strategy):
                        
                            params = (
                                ('stoch_k_period', 3),
                                ('stoch_d_period', 3),
                                ('stoch_rsi_period', 14),
                                ('stoch_period', 14),
                                ('stoch_upperband', 80.0),
                                ('stoch_lowerband', 20.0),
                        
                                ('take_profit', 0.04),
                                ('stop_loss', 0.01),
                        
                                ('size', 20),
                                ('debug', False),
                            )
                        
                            def __init__(self):
                        
                                self.stoch = StochasticRSI(k_period=self.p.stoch_k_period,
                                                           d_period=self.p.stoch_d_period,
                                                           rsi_period=self.p.stoch_rsi_period,
                                                           stoch_period=self.p.stoch_period,
                                                           upperband=self.p.stoch_upperband,
                                                           lowerband=self.p.stoch_lowerband)
                        
                            def next(self):
                        
                                if not self.position:
                                    close = self.data.close[0]
                                    price1 = close
                                    price2 = price1 - self.p.stop_loss * close
                                    price3 = price1 + self.p.take_profit * close
                        
                                    if self.stoch.l.fastk[0] < 20:
                                        self.buy_bracket(price=price1, stopprice=price2, limitprice=price3, exectype=bt.Order.Limit)
                        
                                    if self.stoch.l.fastk[0] > 80:
                                        self.sell_bracket(price=price1, stopprice=price3, limitprice=price2, exectype=bt.Order.Limit)
                        
                        1 Reply Last reply Reply Quote 1
                        • 1 / 1
                        • First post
                          Last post
                        Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors