# Mathematical Intuition of the ADX Indicator: A Python Approach

You can use the Average Directional Index (ADX) indicator if you want to determine the intensity or strength of a trend. But why would you want to find the intensity of a trend? If you trade in a weaker trend then there is a high probability of reversal compared to a stronger trend. So combining your directional trades with a stronger trend will help you achieve higher hit ratio and higher average profitability per trade.

Here is an interesting fact, while the name is the Average Directional Index (ADX), it does not tell us the direction of the trend. While it may sound alarming, the reason for this is quite simple, The ADX indicator is always used in conjunction with the Positive directional indicator and the Negative directional indicator, which indicate the up and downtrend respectively. We will understand the ADX indicator and its use in this blog.

We will go through the following topics:

Welles Wilder created the directional movement indicator and the ADX indicator to determine the direction as well as the strength of the trend. According to Welles Wilder, the directional movement indicator is said to consist of the following components: the True Range, Smoothed Plus Directional Indicator (+DI) and Smoothed Minus Directional Indicator (-DI).

The ADX indicator is calculated as the smoothed average of the difference between the +DI indicator and the -DI indicator, thus telling us the strength of the trend.

The ADX indicator has a value between 0 and 100. It is generally agreed that if the ADX is above 25, it is a sign of a strong trend.

Before we move ahead with the ADX indicator-based strategies, let’s take a small example and see how the ADX indicator is calculated.

We have divided this section into the following steps:

• The True range
• Positive Directional Movement
• Negative Directional Movement
• Smoothed values
• The Positive Index Indicator and Negative Index Indicator

Let us say we have the following data.

 Date High Low Close 11/29/2019 90 82 87 12/2/2019 95 85 87 12/3/2019 105 93 97 12/4/2019 120 106 114 12/5/2019 140 124 133 12/6/2019 165 147 157 12/9/2019 195 175 186 12/10/2019 230 208 223 12/11/2019 270 246 264 12/12/2019 315 289 311 12/13/2019 365 337 350

Before we actually get to the ADX indicator, we have to go through a few other variables too. We have divided this section of the blog into a number of small parts and we begin by finding the true range of the stock price. Let’s get moving!

### The True range

The range for the first row is the difference between High and Low. That is 90 - 82, 8. Only truth shall set you free! While the previous statement is arbitrary, it is somewhat true too. If you look at the high and low data, you might miss the price action happening between the consecutive days. This is where the true range comes into the picture.

Simply put, we take the maximum value of the following three components:

(Current High - Current Low)

Absolute value of (Current High - Previous Close)

Absolute value of (Current Low - Previous Close)

In that respect, we find the actual range of the price action between the days.

If we have to calculate the True range of the above values, then for 2 December, the three values would be:

(Current High - Current Low) = 95 - 85 = 10

Absolute value of (Current High - Previous Close) = 95 - 87 = 8

Absolute value of (Current Low - Previous Close) = (85 - 87) = Absolute value of (-2) = 2

Thus, since the true range is the maximum of the three values, it would be 10.

Let’s fill the table now.

 Date High Low Close (High - Low)[1] (Today's High - Yesterday's Close)[2] (Today's Low - Yesterday's Close)[3] True Range 11/29/2019 90 82 87 - - - - 12/2/2019 95 85 87 10 8 2 10 12/3/2019 105 93 97 12 18 6 18 12/4/2019 120 106 114 14 23 9 23 12/5/2019 140 124 133 16 26 10 26 12/6/2019 165 147 157 18 32 14 32 12/9/2019 195 175 186 20 38 18 38 12/10/2019 230 208 223 22 44 22 44 12/11/2019 270 246 264 24 47 23 47 12/12/2019 315 289 311 26 51 25 51 12/13/2019 365 337 350 28 54 26 54

All right. Let's keep moving forward.

### Positive Directional Movement

We are going all the way up, my friend. As the name suggests, the Positive Directional Indicator is used to help us gauge the uptrend of the market. Of course, we pair it with the Negative Directional indicator to derive real meaning from the indicators.

But how do I know which way is up?

Intuitively, if everyday new high is made compared to previous day high then we can say that the prices are moving up.

We have a simple formula for that, which uses the famous "if-else" statement found both in English as well as programming.

If (Today's high - Yesterday's High) > (Yesterday's Low - Today's Low), then

+DM = (Today's high - Yesterday's High)

Otherwise, it's 0.

But why do we do that? We are checking if the price difference of the two “highs” is more than the difference between the two lows. This would indicate that there is a demand for the stock and a willingness to buy at a higher price than the previous high.

Let us move on to the next section.

### Negative Directional Movement

Just like life, which has its ups and downs, there will always be times when a stock is going down. As we discussed in the previous section, we are checking the selling pressure, which could show up if the investors are ready to sell the stock at a price lower than the previous day.

Thus, in the case of the Negative Directional indicator, the formula would be:

If (Yesterday's Low - Today's Low) >(Today's high - Yesterday's High), then

-DM = (Yesterday's Low - Today's Low)

Otherwise, it's 0.

We will use the formulae mentioned above and calculate the positive directional movement and the negative directional movement for the table.

 Date High Low Close True Range Positive DM Negative DM 11/29/2019 90 82 87 - - - 12/2/2019 95 85 87 10 5 0 12/3/2019 105 93 97 18 10 0 12/4/2019 120 106 114 23 15 0 12/5/2019 140 124 133 26 20 0 12/6/2019 165 147 157 32 25 0 12/9/2019 195 175 186 38 30 0 12/10/2019 230 208 223 44 35 0 12/11/2019 270 246 264 47 40 0 12/12/2019 315 289 311 51 45 0 12/13/2019 365 337 350 54 50 0

Thus, in this manner, we have understood the directional movements.

Before we move to the directional index indicators, we have to figure out what a smoothed version of a True range, Positive Directional movement and a Negative Directional movement is.

### Smoothed values

We should note that the smoothed version is sort of similar to moving average, as it is used to smoothen out the fluctuations, if any, from the data.

We will define a period as 5. This is arbitrarily chosen.

We will do the smoothed values of the positive directional movement. The first value is calculated by taking the sum of the first 5 values, ie (5 + 10 +15 + 20 + 25) = 75.

The next value is calculated by taking the previous smoothed value and subtract the average from it. Finally, add the current value of the positive directional movement.

Confused? Don’t worry, we have the example below.

First smoothed positive directional movement value = 75.

Average of the smoothed positive directional movement value = 75/5 = 15.

Current positive directional movement = 30 (Recall that it is the sixth value)

Thus, the second smoothed true range value = 75 - (75/5) + 30 = 75 - 15 + 30 = 90.

Let us create the table for the following:

 Date True Range Positive DM Negative DM Smoothed Positive DM 11/29/2019 - - - - 12/2/2019 10 5 0 - 12/3/2019 18 10 0 - 12/4/2019 23 15 0 - 12/5/2019 26 20 0 - 12/6/2019 32 25 0 75.0 12/9/2019 38 30 0 90.0 12/10/2019 44 35 0 107.0 12/11/2019 47 40 0 125.6 12/12/2019 51 45 0 145.5 12/13/2019 54 50 0 166.4

We would like to note that since the Negative DM was 0, the smoothed negative DM is also 0.

Similarly, the smoothed true range values are computed and filled in the following table:

 Date True Range Positive DM Negative DM Smoothed Positive DM Smoothed Negative DM Smoothed True range 11/29/2019 - - - - - - 12/2/2019 10 5 0 - - - 12/3/2019 18 10 0 - - - 12/4/2019 23 15 0 - - - 12/5/2019 26 20 0 - - - 12/6/2019 32 25 0 75.0 0.0 109.0 12/9/2019 38 30 0 90.0 0.0 125.2 12/10/2019 44 35 0 107.0 0.0 144.2 12/11/2019 47 40 0 125.6 0.0 162.3 12/12/2019 51 45 0 145.5 0.0 180.9 12/13/2019 54 50 0 166.4 0.0 198.7

Great! We have calculated quite a few variables. We now move on to the trinity, the Positive Directional Index indicator, the Negative Directional Index Indicator and the final boss, ie the Averaged Directional Index (ADX) indicator. Let’s move on, shall we?

### The Positive Directional Index Indicator and Negative Directional Index Indicator

We found out the Smoothed positive Directional movement as well as the Negative directional movement. On its own, either of the indicators has limited uses. But Wilder made use of both of them together so that their crossovers could be classified as a signal.

Now since each can have different magnitudes, we normalise them by dividing with the true range and expressing them as a percentage.

Thus, for the positive Directional Indicator, we take the value of Smoothed Positive DM ie 75 and divide it by the true range, 70 and get the value 75/70 = 1.07 and as a percentage, it will be 107.

Here, we should note that the Smoothed negative DM was always 0, hence the Negative Directional Index Indicator will be 0.

Great! We are just a few more steps away from the main point of this story, ie the ADX indicator.

Remember that we said the ADX Indicator tells us the strength of the trend and not the direction. To give a brief recap of the situation, so far we found out the positive directional indicator and the negative directional indicator. These would tell us the direction of the trend.

But let us step back and try to see if we can get more information from the indicators. What we have to check is how far are the two indicators from each other and this would give us a fair idea of how the market is behaving.

If we have a situation where both the indicators are close to each other, then it means there could be a weak trend, if there is.

But if there is a large difference between the two, it means we have a strong trend. Wilder quantified this by giving the formula for the directional index (DX) indicator. It is as follows:

DX = (Difference of positive and negative directional index indicator) / (sum of positive and negative directional indicator)

Thus, the DX value for 6 December would be:

DX = (75 - 0) / (75 + 0) = 1.

As we are expressing them in percentages, it will be multiplied by 100 to give us the value: 1 * 100 = 100.

And now, since we have to remove any fluctuations, we take the moving average of DX to get the Average directional Index (ADX) indicator.

Since we are taking the time period as 5, we take the average of the five values.

Thus, the updated table would be as follows:

 Date True Range Positive DM Negative DM Smoothed Positive DM Smoothed Negative DM Smoothed True range Positive Directional Indicator Negative Directional Indicator DX ADX 11/29/2019 - - - - - - - - - - 12/2/2019 10 5 0 - - - - - - - 12/3/2019 18 10 0 - - - - - - - 12/4/2019 23 15 0 - - - - - - - 12/5/2019 26 20 0 - - - - - - - 12/6/2019 32 25 0 75.0 0.0 109.0 68.80733945 0 100 - 12/9/2019 38 30 0 90.0 0.0 125.2 71.88498403 0 100 - 12/10/2019 44 35 0 107.0 0.0 144.2 74.22308546 0 100 - 12/11/2019 47 40 0 125.6 0.0 162.3 77.37420531 0 100 - 12/12/2019 51 45 0 145.5 0.0 180.9 80.43684038 0 100 100 12/13/2019 54 50 0 166.4 0.0 198.7 83.74053399 0 100 100

Since the value is 100, we will say that the ADX indicator is exhibiting a very strong trend. This can be also visually confirmed by the candlestick plot of the data shown above.

Considering that we took a simple example before, we have added another table below which gives the stock price of Apple and its corresponding ADX indicator.

 Date True Range Positive DM Negative DM Smoothed True range Smoothed Positive DM Smoothed Negative DM Positive Directional Indicator Negative Directional Indicator DX ADX 2017-04-28 1.03 0.14 0.00 6.10 1.00 0.38 16.45 6.25 44.96 32.36 2017-05-01 3.55 2.90 0.00 8.43 3.70 0.30 43.93 3.62 84.79 42.85 2017-05-02 1.51 0.00 1.88 8.25 2.96 2.12 35.89 25.74 16.48 37.57 2017-05-03 3.24 0.00 0.00 9.84 2.37 1.70 24.08 17.26 16.48 33.35 2017-05-04 1.33 0.00 1.54 9.20 1.90 2.90 20.60 31.50 20.93 30.87 2017-05-05 2.45 1.84 0.00 9.81 3.36 2.32 34.21 23.64 18.27 28.35 2017-05-08 4.74 4.72 0.00 12.59 7.41 1.86 58.82 14.74 59.93 34.67 2017-05-09 1.87 0.00 4.42 11.94 5.92 5.90 49.61 49.44 0.17 27.77 2017-05-10 1.88 0.00 0.00 11.43 4.74 4.72 41.45 41.31 0.17 22.25 2017-05-11 1.76 0.00 0.00 10.91 3.79 3.78 34.76 34.65 0.17 17.83 2017-05-12 2.47 0.00 2.36 11.20 3.03 5.38 27.09 48.08 27.92 19.85 2017-05-15 1.60 0.00 0.38 10.56 2.43 4.69 22.99 44.39 31.77 22.23 2017-05-16 1.34 0.00 0.00 9.79 1.94 3.75 19.84 38.31 31.77 24.14 2017-05-17 5.76 0.00 0.00 13.59 1.55 3.00 11.43 22.07 31.77 25.67 2017-05-18 3.09 0.00 0.00 13.96 1.24 2.40 8.90 17.19 31.77 26.89 2017-05-19 1.44 0.00 1.50 12.61 0.99 3.42 7.88 27.12 54.96 32.50 2017-05-22 1.67 0.60 0.00 11.76 1.40 2.74 11.87 23.27 32.45 32.49 2017-05-23 1.59 0.00 0.40 11.00 1.12 2.59 10.15 23.54 39.75 33.94 2017-05-24 1.50 0.00 0.00 10.30 0.89 2.07 8.67 20.11 39.75 35.10 2017-05-25 1.32 0.00 0.00 9.56 0.71 1.66 7.47 17.33 39.75 36.03

Here we can see a number of times the Positive Directional Indicator crossed over from under the Negative Directional Indicator. But, as we mentioned above, we check the ADX indicator level as well to ascertain the strength of the trend.

Let us take a few cases where we could use the ADX indicator as part of a trading strategy.

Earlier, we saw the process of finding the ADX indicator using a simple table. Now, to work on real-world data, we would take the help of Python to make life easier.

We will fetch the data from yahoo finance in the following manner.

import yfinance as yf
aapl = yf.download('AAPL', '2017-1-1','2019-12-18')

We have taken the stock of Apple and chose the period from 1 Jan 2017 to 18 Dec 2018 at random. We will use the adjusted values with the following code.

aapl['Adj Open'] = aapl.Open * aapl['Adj Close']/aapl['Close']
aapl.dropna(inplace=True)

You can easily compute the ADX indicator in Python with the following code

from ta.trend import ADXIndicator
aapl.tail()

The output will be as follows:

 Date Open High Low Close Adj Close Volume Adj Open Adj High Adj Low pos_directional_indicator neg_directional_indicator adx 12/11/2019 269 271 269 271 271 19,689,200 269 271 269 31 21 26 12/12/2019 268 273 267 271 271 34,327,600 268 273 267 31 19 26 12/13/2019 271 275 271 275 275 33,396,900 271 275 271 33 18 26 12/16/2019 277 281 277 280 280 32,046,500 277 281 277 39 16 28 12/17/2019 280 282 279 280 280 28,539,600 280 282 279 39 15 29

In Python, we use the “matplotlib” library to plot the graph in the following manner:

import matplotlib.pyplot as plt
def plot_graph(data,ylabel,xlabel):
plt.figure(figsize=(10,7))
plt.grid()
plt.plot(data)
plt.ylabel(ylabel)
plt.xlabel(xlabel)
plot_graph(aapl['adx'], 'Price', 'Date')

The output is as follows:

In this manner, we can compare the ADX indicator with the price and create your trading strategy.

But it looks confusing!

Don’t worry, we have got you covered. In the following code, we will plot the price data and highlights the parts where the ADX indicator is above 25, indicating a strong trend.

aapl['trend'] = np.where(aapl.adx>25,aapl['Adj Close'],np.nan)

plt.figure(figsize=(10,7))
plt.grid()
plt.plot(aapl['trend'])
plt.ylabel('Price')
plt.xlabel('Date')

As we had mentioned earlier, The ADX indicator tells us the strength of the trend and not the direction. Thus, if we take the example of the data from Oct 2018 to Jan 1, 2019, the ADX indicator has highlighted the price data signifying that there is a strong trend present. Further, when we see the price chart, we can see it is a downtrend and can take a short position.

But we see the data from Jan 2019 onwards, until May 2019, the price rose upwards with the ADX indicator above 25, signifying an uptrend and we can use this as a signal to go long.

If we were to use the ADX indicator as to the trading strategy, the returns would be plotted in the following manner.

aapl['direction'] = np.where(aapl.pos_directional_indicator>aapl.neg_directional_indicator,1,-1) * aapl['trend_signal']
plot_graph((aapl['strategy_returns']+1).cumprod(), 'Returns', 'Date')