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



  • 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()


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


  • 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


Log in to reply
 

});