Discover more from All About Trading!
Transforming the RSI Into a Candlestick Indicator Using Python
Candlestick charting does not have to be limited to price data. What if it can be used on technical indicators so that start testing some new pattern recognition techniques? In this article, the RSI is looked at from the perspective of a simple candlestick chart where trading signals are derived. The basic idea is to start thinking about finding a robust strategy that uses the technique of applying candlesticks to technical indicators in order to find either hidden patterns or trend reversal confirmation signals.
If you are interested by trend following indicators and strategies then my book could interest you. It features advanced trend-following indicators and strategies with a GitHub page dedicated to the continuously updated code. Also, this book features the original colors after having optimized for printing costs. If you feel that this interests you, feel free to visit the below Amazon link, or if you prefer to buy the PDF version, you could contact me on LinkedIn.
Trend Following Strategies in Python: How to Use Indicators to Follow the Trend.
Amazon.com: Trend Following Strategies in Python: How to Use Indicators to Follow the Trend.: 9798756939620: Kaabar…www.amazon.com
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.
import numpy as np
def add_column(data, times): for i in range(1, times + 1): new = np.zeros((len(data), 1), dtype = float) data = np.append(data, new, axis = 1) return data
def delete_column(data, index, times): for i in range(1, times + 1): data = np.delete(data, index, axis = 1) return data
def delete_row(data, number): data = data[number:, ] return data
def ma(data, lookback, close, position): data = add_column(data, 1) for i in range(len(data)): try: data[i, position] = (data[i - lookback + 1:i + 1, close].mean()) except IndexError: pass data = delete_row(data, lookback) return data
def smoothed_ma(data, alpha, lookback, close, position): lookback = (2 * lookback) - 1 alpha = alpha / (lookback + 1.0) beta = 1 - alpha data = ma(data, lookback, close, position) data[lookback + 1, position] = (data[lookback + 1, close] * alpha) + (data[lookback, position] * beta) for i in range(lookback + 2, len(data)): try: data[i, position] = (data[i, close] * alpha) + (data[i - 1, position] * beta) except IndexError: pass return data
def rsi(data, lookback, close, position): data = add_column(data, 5) for i in range(len(data)): data[i, position] = data[i, close] - data[i - 1, close] for i in range(len(data)): if data[i, position] > 0: data[i, position + 1] = data[i, position] elif data[i, position] < 0: data[i, position + 2] = abs(data[i, position]) data = smoothed_ma(data, 2, lookback, position + 1, position + 3) data = smoothed_ma(data, 2, lookback, position + 2, position + 4) data[:, position + 5] = data[:, position + 3] / data[:, position + 4] data[:, position + 6] = (100 - (100 / (1 + data[:, position + 5]))) data = delete_column(data, position, 6) data = delete_row(data, lookback) return data
Getting healthier means changing your lifestyle. Noom Weight helps users lose weight in a sustainable way through behavioral change psychology. It's a no-brainer.
Candlestick charts are among the most famous ways to analyze the time series visually. They contain more information than a simple line chart and have more visual interpretability than bar charts. Many libraries in Python offer charting functions but being someone who suffers from malfunctioning import of libraries and functions alongside their fogginess, I have created my own simple function that charts candlesticks manually with no exogenous help needed.
OHLC data is an abbreviation for Open, High, Low, and Close price. They are the four main ingredients for a timestamp. It is always better to have these four values together so that our analysis reflects more the reality. Here is a table that summarizes the OHLC data of hypothetical security:
Our job now is to plot the data so that we can visually interpret what kind of trend is the price following. We will start with the basic line plot before we move on to candlestick plotting.
Note that you can download the data manually or using Python. In case you have an excel file that has OHLC only data starting from the first row and column, you can import it using the below code snippet:
import numpy as np import pandas as pd
# Importing the Data my_ohlc_data = pd.read_excel('my_ohlc_data.xlsx')
# Converting to Array my_ohlc_data = np.array(my_ohlc_data)
Plotting basic line plots is extremely easy in Python and requires only one line of code. We have to make sure that we have imported a library called matplotlib and then we will call a function that plots the data for us.
# Importing the necessary charting library import matplotlib.pyplot as plt
# The syntax to plot a line chart plt.plot(my_ohlc_data, color = 'black', label = 'EURUSD')
# The syntax to add the label created above plt.legend()
# The syntax to add a grid plt.grid()
Now that we have seen how to create normal line charts, it is time to take it to the next level with candlestick charts. The way to do this with no complications is to think about vertical lines. Here is the intuition (followed by an application of the function below):
Select a lookback period. This is the number of values you want to appear on the chart.
Plot vertical lines for each row representing the highs and lows. For example, on OHLC data, we will use a matplotlib function called vlines which plots a vertical line on the chart using a minimum (low) value and a maximum (high value).
Make a color condition which states that if the closing price is greater than the opening price, then execute the selected block of code (which naturally contains the color green). Do this with the color red (bearish candle) and the color black (Doji candle).
Plot vertical lines using the conditions with the min and max values representing closing prices and opening prices. Make sure to make the line’s width extra big so that the body of the candle appears sufficiently enough that the chart is deemed a candlestick chart.
def ohlc_plot(Data, window, name): Chosen = Data[-window:, ] for i in range(len(Chosen)): plt.vlines(x = i, ymin = Chosen[i, 2], ymax = Chosen[i, 1], color = 'black', linewidth = 1) if Chosen[i, 3] > Chosen[i, 0]: color_chosen = 'green' plt.vlines(x = i, ymin = Chosen[i, 0], ymax = Chosen[i, 3], color = color_chosen, linewidth = 4) if Chosen[i, 3] < Chosen[i, 0]: color_chosen = 'red' plt.vlines(x = i, ymin = Chosen[i, 3], ymax = Chosen[i, 0], color = color_chosen, linewidth = 4) if Chosen[i, 3] == Chosen[i, 0]: color_chosen = 'black' plt.vlines(x = i, ymin = Chosen[i, 3], ymax = Chosen[i, 0], color = color_chosen, linewidth = 4) plt.grid() plt.title(name)
# Using the function ohlc_plot(my_ohlc_data, 50, '')
The Candlestick RSI will be a regular 13-period RSI applied to the open prices and the closing prices, thus forming a simplistic type of candles where we can start seeing the psychology of the move. We can also add the high and low calculations so that we add them later into the signal. Therefore, the first step into creating the indicator is the following syntax:
lookback = 13
# Calculating a 13-period RSI on opening prices my_data = rsi(my_data, lookback, 0, 5, genre = 'Smoothed')
# Calculating a 13-period RSI on high prices my_data = rsi(my_data, lookback, 1, 6, genre = 'Smoothed')
# Calculating a 13-period RSI on low prices my_data = rsi(my_data, lookback, 2, 7, genre = 'Smoothed')
# Calculating a 13-period RSI on closing prices my_data = rsi(my_data, lookback, 3, 8, genre = 'Smoothed')
The below chart shows the candlestick RSI in the first panel with the EURUSD hourly values in the second panel.
The above chart is a bit unusual, as we are used to putting the market price in the first panel. This time, we have switched and put the Candlestick-RSI above. We are now ready to derive the trading conditions based on a choice of candlestick patterns and the usual extremes strategy on the RSI.
The above chart shows an example on the USDCAD where barriers of 20 and 80 are more suited to the Candlestick RSI. Note that the word barriers refer to the oversold/overbought levels.
Applying the Pattern Recognition Strategy
By fetching the conditions from candlestick pattern recognition and the RSI’s contrarian methods, we can develop the following trading rules:
Go long (Buy) whenever the current RSI (Based on closing prices) is greater than the current RSI (Based on opening prices) while simultaneously the current RSI (Based on low prices) is lower than the lower barrier of 20 (or 30 in the case of certain currency pairs).
Go short (Sell) whenever the current RSI (Based on closing prices) is lower than the current RSI (Based on opening prices) while simultaneously the current RSI (Based on high prices) is higher than the upper barrier of 80 (or 70 in the case of certain currency pairs).
def signal(Data): Data = adder(Data, 20) for i in range(len(Data)): if Data[i, 8] > Data[i, 5] and Data[i, 7] < lower_barrier and Data[i - 1, 9] == 0: Data[i, 9] = 1 elif Data[i, 8] < Data[i, 5] and Data[i, 6] > upper_barrier and Data[i - 1, 10] == 0: Data[i, 10] = -1 return Data
If you want to see how to create all sorts of algorithms yourself, feel free to check out Lumiwealth. From algorithmic trading to blockchain and machine learning, they have hands-on detailed courses that I highly recommend.
Learn Algorithmic Trading with Python Lumiwealth
Learn how to create your own trading algorithms for stocks, options, crypto and more from the experts at Lumiwealth. Click to learn more
To sum 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 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.