Structured indicators are the result of fusing two or more together to form a weighted or adjusted indicator that takes into account more variables. For example, we know that there is a Stochastic-RSI indicator which combines the two formulas together in an attempt to improve the signals, this article discusses the creation of an RSI-ATR indicator which adjusts the RSI for the average true range, a measure of volatility.
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.
Contrarian Trading Strategies in Python
Amazon.com: Contrarian Trading Strategies in Python: 9798434008075: Kaabar, Sofien: Bookswww.amazon.com
The Volatility-Adjusted RSI
The RSI is without a doubt the most famous momentum indicator out there, and this is to be expected as it has many strengths especially in ranging markets. It is also bounded between 0 and 100 which makes it easier to interpret. Also, the fact that it is famous, contributes to its potential. This is because the more traders and portfolio managers look at the RSI, the more people will react based on its signals and this in turn can push market prices. Of course, we cannot prove this idea, but it is intuitive as one of the basis of Technical Analysis is that it is self-fulfilling.
The RSI is calculated using a rather simple way. We first start by taking price differences of one period. This means that we have to subtract every closing price from the one before it. Then, we will calculate the smoothed average of the positive differences and divide it by the smoothed average of the negative differences. The last calculation gives us the Relative Strength which is then used in the RSI formula to be transformed into a measure between 0 and 100. This is for the momentum part. Let us proceed to the volatility part.
We sometimes measure volatility using the Average True Range. Although the ATR is considered a lagging indicator, it gives some insights as to where volatility is right now and where has it been last period (day, week, month, etc.). But before that, we should understand how the True Range is calculated (the ATR is just the average of that calculation).
The true range is simply the greatest of the three price differences:
High — Low
| High — Previous close |
| Previous close — Low |
Once we have gotten the maximum out of the above three, we simply take an average of n periods of the true ranges to get the Average True Range. Generally, since in periods of panic and price depreciation we see volatility go up, the ATR will most likely trend higher during these periods, similarly in times of steady uptrends or downtrends, the ATR will tend to go lower. One should always remember that this indicator is lagging and therefore has to be used with extreme caution. Now, it is time to create the Volatility-Adjusted RSI or what we will also call the ATR-Adjusted RSI.
The idea is to divide the values of the RSI by the ATR so that we find a measure adjusted by the recent volatility. However, by doing so, we will find unbounded values, which is why we will apply the RSI formula on the values we find. Therefore, to calculate the indicator, we follow these steps:
Calculate a 14-period RSI on the market price.
Calculate a 14-period ATR on the market price.
Divide the RSI by the ATR values.
Calculate a 14-period RSI on the results from the last step.
Coding the Volatility-Adjusted RSI in Pine Script
We want to create and plot the Volatility-Adjusted RSI on the AUDCAD values loaded on the TradingView platform. Note that you must create an account to be able to view the charts, the good news is that it is free. Locate the Chart button on the home screen and then choose any asset you would like to calculate the indicator on. Now, on the bottom of the screen, locate Pine Editor and warm up your fingers to do some coding.
The first step is to specify the version of Pine Script. In our case it is 5 which has some minor changes from the fourth version.
//@version = 5
The next step is to specify the name of the indicator by using the following syntax. We will call it the ATR-Adjusted RSI since the ATR is the proxy of volatility here.
indicator("ATR-Adjusted RSI")
Having done the introductory part, we can proceed calculating the RSI on the market price. In the fifth version of Pine Script, this is done using the ta.rsi() function as opposed to rsi() in the fourth version.
rsi = ta.rsi(close, 14)
The code above creates a variable called rsi which harbors the 14-period RSI values applied on the closing prices. We can say that it is a separate array if we want to simplify things.
Now, we will calculate the Average True Range on the market price. This is done using the ta.atr() function.
atr = ta.atr(14)
With the above function, you do not need to specify the source as it automatically assumes that it is applied on the market price. Let us now divide the RSI calculations by the ATR calculations to give us the first step of the indicator.
rsi_atr = rsi / atr
Finally, to get the ATR-Adjusted RSI, we apply the RSI’s formula on the values of the previous step.
rsi_atr_indicator = ta.rsi(rsi_atr, 14)
Let us plot the indicator. This is done using the plot() function. It takes a source and a color property as shown below. We can also use the hline() function to plot a horizontal line as a subjective barrier.
plot(rsi_atr_indicator, color = (rsi_atr_indicator > rsi_atr_indicator[1]) ? color.green : color.red)
hline(70)
hline(30)
The color function used has a special technique that helps us improve our visual interpretation. It states that if the indicator moves up, draw it in green and if it moves down, draw it in red.
The full code can be found below.
//@version=5
indicator("ATR-Adjusted RSI")
rsi = ta.rsi(close, 14)
atr = ta.atr(14)
rsi_atr = rsi / atr
rsi_atr_indicator = ta.rsi(rsi_atr, 14)
plot(rsi_atr_indicator, color = (rsi_atr_indicator > rsi_atr_indicator[1]) ? color.green : color.red)
hline(70)
hline(30)
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
Summary
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.