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