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/

    RSI: moving thresholds signals

    General Code/Help
    2
    3
    890
    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.
    • N
      nicostro last edited by

      Hi everyone,

      I am fairly new to Python and Backtrader. I am testing out a simple RSI cross over strategy. Instead of having two hard-plugged thresholds for buy and sell signals, I’d like those thresholds to be moving across time series. For example, a buy signal would be triggered when current RSI is equal to the 10% minimum / lowest RSI over the last 24 hours, conversely a sell signal would be triggered when current RSI reaches the 90% highest RSI over the same period of time.

      As you can see on the code below, I haven’t been successful figuring out what to code in order to get those moving thresholds (10% lowest and 90% highest thresholds) that would trigger a trade signal.

      Any assistance or feedback would be greatly appreciated.

      class TestStrategy(bt.Strategy):

      params = (
          ('period',195),('threshold_Buy', 50),('threshold_Sell', 56),
          ) #tresholds here are hard plugged, the intent would be to have them as a percentage (for example 10% buy signal and 90% sell signal)
      
      def log(self, txt, dt=None):
          dt = dt or self.datas[0].datetime.date(0)
          print('%s, %s' % (dt.isoformat(), txt))
      
      def __init__(self):
          self.dataclose = self.datas[0].close
          self.order = None
          self.buyprice = None
          self.buycomm = None
      
          self.rsi = bt.indicators.RelativeStrengthIndex(self.datas[0], period=self.params.period) # simple RSI, period here has already been optimized for this particular stock
      
          self.smaRSI = bt.indicators.SimpleMovingAverage(self.rsi, period=288) #period here represents 24 hours cut into 5 minutes timeframe periods
      
      def notify_order(self, order):
          if order.status in [order.Submitted, order.Accepted]:
              # Buy/Sell order submitted/accepted to/by broker - Nothing to do
              return
      
          if order.status in [order.Completed]:
              if order.isbuy():
                  self.log(
                      'BUY EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
                      (order.executed.price,
                       order.executed.value,
                       order.executed.comm))
      
                  self.buyprice = order.executed.price
                  self.buycomm = order.executed.comm
              else:
                  self.log('SELL EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
                           (order.executed.price,
                            order.executed.value,
                            order.executed.comm))
      
              self.bar_executed = len(self)
      
          elif order.status in [order.Canceled, order.Margin, order.Rejected]:
              '''self.log('Order Canceled/Margin/Rejected')'''
      
          self.order = None
      
      def notify_trade(self, trade):
          if not trade.isclosed:
              return
      
          self.log('OPERATION PROFIT, GROSS %.2f, NET %.2f' %
                   (trade.pnl, trade.pnlcomm))
      
      def next(self):
      
          if self.order:
              return
      
          if not self.position:
      
              print('rsi', self.rsi[0], 'smaRSI', self.smaRSI[0])
      
              if self.rsi[0] < self.params.threshold_Buy:
                  self.order = self.buy()
      
          else:
      
              if self.rsi[0] > self.params.threshold_Sell:
                  self.order = self.sell()
      
      1 Reply Last reply Reply Quote 0
      • A
        ab_trader last edited by

        I would start from this script (didn't test):

        class TestStrategy(bt.Strategy):
        
            params = (('period',195), ('threshold_Buy', 10), ('threshold_Sell', 90),)
        
            def __init__(self):
        
                self.rsi = bt.indicators.RelativeStrengthIndex(period=self.p.period)
                self.rsiHHV = bt.indicators.Highest(self.rsi, period=288)
                self.rsiLLV = bt.indicators.Lowest(self.rsi, period=288)
        
                self.buysig = (self.rsi >= self.p.threshold_Buy * self.rsiHHV)
                self.sellsig = (self.rsi <= self.p.threshold_Sell * self.rsiLLV)
        
        • 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 1
        • N
          nicostro last edited by

          Great thanks, exactly what I needed.

          I just changed the buy / sell signals as per the below:

                  if self.rsi[0] <= (np.percentile([self.rsiLLV[0], self.rsiHHV[0]], self.p.threshold_Buy)):
                      self.order = self.buy()
          
           else:
          
                  if self.rsi[0] >= (np.percentile([self.rsiLLV[0], self.rsiHHV[0]], self.p.threshold_Sell)):
                      self.order = self.sell()
          

          Many thanks again

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