Backtrader Community

    • 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/

    Would appreciate some help with Connors RSI

    General Code/Help
    3
    6
    951
    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.
    • R
      Rudi last edited by Rudi

      Hi,

      I'm new to backorder and new to python, so please bare with me.
      I'm trying to implement an indicator for the ConnorsRSI. At a certain point in the algorithm I need to take the RSI of a line that I create, and it gives me back nan instead of an rsi value. I have no clue where I go wrong, and hope that somebody can point me in the right direction.
      Please feel free to give other hints and tips if I make obvious coding mistakes.
      The code for the indicator itself is:

      class ConnorsRSI(bt.Indicator):
          lines = ('crsi','rsi','streak','streak_rsi', 'prank')
          params = (
              ('rsi_length', 3),
              ('streak_length', 2),
              ('loopback_length', 100),
          )
      
          plotlines = dict(
              obv=dict(
                  _name='crsi',
                  color='purple',
                  alpha=0.50
              )
          )
      
          def updown(self):
              upday=False
              downday=False
      
              if self.data[0] > self.data[-1]:
                  upday = True
              else:
                  upday = False
      
              if self.data[0] < self.data[-1]:
                  downday = True
              else:
                  downday = False
      
              if upday and self.lines.streak[-1] >= 0:
                  self.lines.streak[0] = self.lines.streak[-1] + 1
              elif upday and self.lines.streak[-1] <= 0:
                  self.lines.streak[0] = 1
              elif downday and self.lines.streak[-1] <= 0:
                  self.lines.streak[0] = self.lines.streak[-1] - 1
              elif downday and self.lines.streak[-1] >= 0:
                  self.lines.streak[0] = -1
              elif self.data[0] == self.data[-1]:
                  self.lines.streak[0] = 0
              else:
                  self.lines.streak[0] = 0
      
          def __init__(self):
      
              # Plot a horizontal Line
              self.plotinfo.plotyhlines = [0]
      
              self.lines.rsi = bt.indicators.RSI(self.data, period=self.params.rsi_length)
              self.lines.prank = bt.indicators.PercentRank(self.data, period=self.params.loopback_length)
      
          def next(self):
              self.updown()
              self.lines.streak_rsi = bt.indicators.RSI(self.lines.streak, period=self.params.streak_length)
      
      
          def nextstart(self):
              self.lines.streak[0] = 0
      

      The issue is in the 'next', where I calculate (or want to calculate) the RSI value over the streaks. The output I get is:

      2016-05-25: Prev: 48.76: Close: 49.26, rsi: 79.21353438233095 Streak: 0.0 Streak_rsi: nan PercentRank: 59
      2016-05-26: Prev: 49.26: Close: 49.04, rsi: 68.50800494096566 Streak: -1.0 Streak_rsi: nan PercentRank: 56
      2016-05-27: Prev: 49.04: Close: 49.45, rsi: 77.14326450516853 Streak: 1.0 Streak_rsi: nan PercentRank: 64
      2016-05-31: Prev: 49.45: Close: 50.09, rsi: 86.08028735088246 Streak: 2.0 Streak_rsi: nan PercentRank: 70
      2016-06-01: Prev: 50.09: Close: 49.95, rsi: 76.29219423676898 Streak: -1.0 Streak_rsi: nan PercentRank: 69
      2016-06-02: Prev: 49.95: Close: 49.6, rsi: 53.48552312948757 Streak: -2.0 Streak_rsi: nan PercentRank: 65
      2016-06-03: Prev: 49.6: Close: 48.95, rsi: 29.183093574328538 Streak: -3.0 Streak_rsi: nan PercentRank: 52
      2016-06-06: Prev: 48.95: Close: 49.27, rsi: 46.97498518905785 Streak: 1.0 Streak_rsi: nan PercentRank: 57
      2016-06-07: Prev: 49.27: Close: 49.24, rsi: 45.37197817316539 Streak: -1.0 Streak_rsi: nan PercentRank: 56
      2016-06-08: Prev: 49.24: Close: 49.18, rsi: 41.15842240824419 Streak: -2.0 Streak_rsi: nan PercentRank: 55
      

      Thanks!

      1 Reply Last reply Reply Quote 0
      • A
        ab_trader last edited by backtrader

        You can't do this

        self.lines.streak_rsi = bt.indicators.RSI(self.lines.streak, period=self.params.streak_length)
        

        in the next(), only in __init()__.

        As a solution you may want to bring all calculations into the init() and use bt RSI or calculate RSI in the next() by yourself based on [x] notations. Or apply RSI to streak in a separate indicator.

        • 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
        R 1 Reply Last reply Reply Quote 0
        • R
          Rudi @ab_trader last edited by

          @ab_trader thanks for looking into this. I changed the code as below (calculating the RSI myself in the init(), but still getting the rsi over the streak back as a nan. Is this not what you meant?

          class ConnorsRSI(bt.Indicator):
              lines = ('crsi','rsi','streak', 'streak_rsi','prank')
              params = (
                  ('rsi_length', 3),
                  ('streak_length', 2),
                  ('loopback_length', 100),
              )
          
              plotlines = dict(
                  obv=dict(
                      _name='crsi',
                      color='purple',
                      alpha=0.50
                  )
              )
          
              def updown(self):
                  upday=False
                  downday=False
          
                  if self.data[0] > self.data[-1]:
                      upday = True
                  else:
                      upday = False
          
                  if self.data[0] < self.data[-1]:
                      downday = True
                  else:
                      downday = False
          
                  if upday and self.lines.streak[-1] >= 0:
                      self.lines.streak[0] = self.lines.streak[-1] + 1
                  elif upday and self.lines.streak[-1] <= 0:
                      self.lines.streak[0] = 1
                  elif downday and self.lines.streak[-1] <= 0:
                      self.lines.streak[0] = self.lines.streak[-1] - 1
                  elif downday and self.lines.streak[-1] >= 0:
                      self.lines.streak[0] = -1
                  elif self.data[0] == self.data[-1]:
                      self.lines.streak[0] = 0
                  else:
                      self.lines.streak[0] = 0
          
              def __init__(self):
          
                  # Plot a horizontal Line
                  self.plotinfo.plotyhlines = [0]
          
                  self.lines.rsi = bt.indicators.RSI(self.data, period=self.params.rsi_length)
                  self.lines.prank = bt.indicators.PercentRank(self.data, period=self.params.loopback_length)
          
                  # calculate rsi over streak
                  upday = bt.indicators.UpDay(self.lines.streak, period=self.params.streak_length)
                  downday = bt.indicators.DownDay(self.lines.streak, period=self.params.streak_length)
                  maup = bt.indicators.MovAv.Smoothed(upday, period=self.params.streak_length)
                  madown = bt.indicators.MovAv.Smoothed(downday, period=self.params.streak_length)
                  rs = maup / madown
                  self.lines.streak_rsi = 100.0 - 100.0 / (1.0 + rs)
          
          
              def next(self):
                  self.updown()
          
              def nextstart(self):
                  self.lines.streak[0] = 0
          

          Thanks for your support!

          A 1 Reply Last reply Reply Quote 0
          • A
            ab_trader @Rudi last edited by ab_trader

            @Rudi

            UpDay and DownDay indicators are applied to undefined self.lines.streak. I am not surprised that result is nan.

            You may want go deeper into code debugging by yourself with the logging of all interim calculations. Your indicator seems recursive, so this blog post might help

            Developing a Recursive Indicator (with a seed)

            • 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
            1 Reply Last reply Reply Quote 0
            • B
              backtrader administrators last edited by

              See: Community - Backtrader Cookbook

              R 1 Reply Last reply Reply Quote 1
              • R
                Rudi @backtrader last edited by

                Brilliant @backtrader ! I'll make sure to add indicators once I get the hang of creating them!

                1 Reply Last reply Reply Quote 0
                • 1 / 1
                • First post
                  Last post
                Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors