To calculate the ATR, perform the following steps:
N
days, usually the last 20 days.N = 5 h = h[-N:] l = l[-N:]
previousclose = c[-N -1: -1]
For each day, we calculate the following:
The daily range—the difference between the high and low price:
h – l
The difference between the high and previous close:
h – previousclose
The difference between the previous close and the low price:
previousclose – l
max()
function returns the maximum of an array. Based on those three values, we calculate the so-called true range, which is the maximum of these values. We are now interested in the element-wise maxima across arrays—meaning the maxima of the first elements in the arrays, the second elements in the arrays, and so on. Use the NumPy maximum()
function instead of the max()
function for this purpose:truerange = np.maximum(h - l, h - previousclose, previousclose - l)
atr
array of size N
and initialize its values to 0
:atr = np.zeros(N)
truerange
array:atr[0] = np.mean(truerange)
Calculate the other values with the following formula:
Here, PATR is the previous day's ATR; TR is the true range:
for i in range(1, N): atr[i] = (N - 1) * atr[i - 1] + truerange[i] atr[i] /= N
We formed three arrays, one for each of the three ranges—daily range, the gap between the high of today and the close of yesterday, and the gap between the close of yesterday and the low of today. This tells us how much the stock price moved and, therefore, how volatile it is. The algorithm requires us to find the maximum value for each day. The max()
function that we used before can give us the maximum value within an array, but that is not what we want here. We need the maximum value across arrays, so we want the maximum value of the first elements in the three arrays, the second elements, and so on. In preceding Time for action section, we saw that the maximum()
function can do this. After this, we computed a moving average of the true range values (see atr.py
):
from __future__ import print_function
import numpy as np
h, l, c = np.loadtxt('data.csv', delimiter=',', usecols=(4, 5, 6), unpack=True)
N = 5
h = h[-N:]
l = l[-N:]
print("len(h)", len(h), "len(l)", len(l))
print("Close", c)
previousclose = c[-N -1: -1]
print("len(previousclose)", len(previousclose))
print("Previous close", previousclose)
truerange = np.maximum(h - l, h - previousclose, previousclose - l)
print("True range", truerange)
atr = np.zeros(N)
atr[0] = np.mean(truerange)
for i in range(1, N):
atr[i] = (N - 1) * atr[i - 1] + truerange[i]
atr[i] /= N
print("ATR", atr)
In the following sections, we will learn better ways to calculate moving averages.