Breakout Confirmation Using the RSI in Python
How to Confirm a New Trend Using a Strategy on the RSI
The relative strength index is a known contrarian indicator but can also be used to confirm a new trend by either surpassing its neutral zone or even by exiting the oversold and overbought levels. This article discusses the latter method in detail.
I have released a new book after the success of my previous one “Trend Following Strategies in Python”. It features advanced contrarian indicators and strategies with a GitHub page dedicated to the continuously updated code. If you feel that this interests you, feel free to visit the below Amazon link (which contains a sample), or if you prefer to buy the PDF version, you could check the link at the end of the article.
The Relative Strength Index
First introduced by J. Welles Wilder Jr., the RSI is one of the most popular and versatile technical indicators. Mainly used as a contrarian indicator where extreme values signal a reaction that can be exploited. Typically, we use the following steps to calculate the default RSI:
Calculate the change in the closing prices from the previous ones.
Separate the positive net changes from the negative net changes.
Calculate a smoothed moving average on the positive net changes and on the absolute values of the negative net changes.
Divide the smoothed positive changes by the smoothed negative changes. We will refer to this calculation as the Relative Strength — RS.
Apply the normalization formula shown below for every time step to get the RSI.
The above chart shows the hourly values of the GBPUSD in black with the 13-period RSI. We can generally note that the RSI tends to bounce close to 25 while it tends to pause around 75. To code the RSI in Python, we need an OHLC array composed of four columns that cover open, high, low, and close prices.
def adder(data, times): for i in range(1, times + 1): new = np.zeros((len(data), 1), dtype = float) data = np.append(data, new, axis = 1)
def deleter(data, index, times): for i in range(1, times + 1): data = np.delete(data, index, axis = 1)
return data def jump(data, jump): data = data[jump:, ] return data
def ma(data, lookback, close, where): data = adder(data, 1) for i in range(len(data)): try: data[i, where] = (data[i - lookback + 1:i + 1, close].mean()) except IndexError: pass data = jump(data, lookback) return data
def ema(data, alpha, lookback, what, where): alpha = alpha / (lookback + 1.0) beta = 1 - alpha data = ma(data, lookback, what, where)
data[lookback + 1, where] = (data[lookback + 1, what] * alpha) + (data[lookback, where] * beta)
for i in range(lookback + 2, len(data)): try: data[i, where] = (data[i, what] * alpha) + (data[i - 1, where] * beta) except IndexError: pass return data
def rsi(data, lookback, close, where): data = adder(data, 5) for i in range(len(data)): data[i, where] = data[i, close] - data[i - 1, close] for i in range(len(data)): if data[i, where] > 0: data[i, where + 1] = data[i, where] elif data[i, where] < 0: data[i, where + 2] = abs(data[i, where]) lookback = (lookback * 2) - 1 # From exponential to smoothed data = ema(data, 2, lookback, where + 1, where + 3) data = ema(data, 2, lookback, where + 2, where + 4)
data[:, where + 5] = data[:, where + 3] / data[:, where + 4] data[:, where + 6] = (100 - (100 / (1 + data[:, where + 5])))
data = deleter(data, where, 6) data = jump(data, lookback)
The Barrier Exit Strategy
One way of confirming the new trend using the RSI is to wait for the exit from the extreme level. We need to define what are extreme levels first.
An oversold level is typically below 30 and refers to a state of the market where selling activity was a bit extreme.
An overbought level is typically above 70 and refers to a state of the market where buying activity was a bit extreme.
Therefore, the barrier exit strategy has the following conditions:
Whenever the RSI exits the 30 level after having been below it, a bullish signal is generated.
Whenever the RSI exits the 70 level after having been above it, a bearish signal is generated.
def signal(Data, rsi_col, buy, sell): Data = adder(Data, 10) for i in range(len(Data)): if Data[i, rsi_col] > lower_barrier and Data[i - 1, rsi_col] < lower_barrier and Data[i - 2, buy] == 0 and Data[i - 3, buy] == 0 and Data[i - 4, buy] == 0 and Data[i - 5, buy] == 0 : Data[i, buy] = 1 elif Data[i, rsi_col] < upper_barrier and Data[i - 1, rsi_col] > upper_barrier and Data[i - 2, sell] == 0 and Data[i - 3, sell] == 0 and Data[i - 4, sell] == 0 and Data[i - 5, sell] == 0 : Data[i, sell] = -1 return Data
The above signal chart shows the trades generated on the EURUSD hourly values using the barrier exit strategy. One of the disadvantages of the strategy is that it can be a little later than the extremes strategy, however, the confirmation part may make up for it in case the market stays overbought/oversold a long time.
The strategy can be confirmed by many other indicators such as moving averages and other indicators.
Remember to always do your back-tests. You should always believe that other people are wrong. My indicators and style of trading may work for me but maybe not for you.
I am a firm believer of not spoon-feeding. I have learnt by doing and not by copying. You should get the idea, the function, the intuition, the conditions of the strategy, and then elaborate (an even better) one yourself so that you back-test and improve it before deciding to take it live or to eliminate it. My choice of not providing specific Back-testing results should lead the reader to explore more herself the strategy and work on it more.
To summarize up, what I am trying to do is to simply contribute to the world of objective technical analysis which is promoting more transparent techniques and strategies that need to be back-tested before being implemented. This way, technical analysis will get rid of the bad reputation of being a subjective and scientifically unfounded.
I recommend you always follow the the below steps whenever you come across a trading technique or strategy:
Have a critical mindset and get rid of any emotions.
Back-test it using real life simulation and conditions.
If you find potential, try optimizing it and running a forward test.
Always include transaction costs and any slippage simulation in your tests.
Always include risk management and position sizing in your tests.
Finally, even after making sure of the above, stay careful and monitor the strategy because market dynamics may shift and make the strategy unprofitable.
For the PDF alternative, the price of the book is 9.99 EUR. Please include your email in the note before paying so that you receive it on the right address. Also, once you receive it, make sure to download it through google drive.