Last Updated on 23 July, 2024 by Trading System
Introduction
In this tutorial, we will implement a trading strategy using the ATR indicator. The first part will explain this indicator. Then, we will show a practical example in Python using the SPY data. Throughout this tutorial, we will implement various Python functions.
Average True Range
ATR is a volatility indicator that captures how much fluctuates the price in a day. It aims to identify periods with high uncertainty.
To calculate the ATR, the maximum, minimum, and closing prices are necessary. We calculate the True Range (TR) as follows:
Where:
H = Maximum price of the day
L = Minimum price of the day
= Previous day’s closing price
With the previous result, the ATR is:
The first ATR value is:
Practical Example in Python
Data and Financial instruments
In this tutorial, we will use the following financial instruments:
The start and end period of our analysis are “2021-01-01” and “2023-10-23″, respectively.
Data Download and Analysis:
As in our previous tutorials, we first import the Python libraries:
Next, we download the data using the following function:
The function download_data takes three arguments: stock_name, start, and end. In the function body, we download the data, and finally, the variable data is returned.
The implementation and results of the previous function are:
:
ATR Implementation
We will use the ta library to calculate the ATR. The following image shows the get_atr function, which takes two parameters: data and window. Inside the function, the AverageTrueRange method from the ta package estimates the Average True Range. Finally, the variable atr containing the data of this indicator is returned.
In the previous image, you can also see the implementation of get_atr with its first five results; note that the ATR has a 14-day window length.
In the following image, you can see the function that calculates the 14-day SMA using values from result[“ATR”]:
Price and ATR Chart
This section involves plotting both the closing price and ATR to draw insight from our data. We will plot the closing price at the top and ATR below it.
The following image shows the plot_data function, which has two parameters: data and ticker. Inside the function, you can see plt.subplots(2, 1, gridspec_kw={‘height_ratios’: [3, 1]}), the first two arguments indicate we want the two graphs in a vertical orientation. The height_ratios indicates that the first graph is three times larger than the second one. The NullFormatter() expression is used to hide the horizontal axis in the first graph. We have explained the other commands in other tutorials:
https://www.quantifiedstrategies.com/how-i-made-a-weighted-moving-average-strategy-using-python/
https://www.quantifiedstrategies.com/how-to-build-a-simple-sma-trading-strategy-using-python/
Implementing plot_data with parameters result and stock_name yields the following:
The image above shows high volatility throughout 2022, with periods of sharp price increases and decreases. When we observe the ATR series, we can see the highest values in the same period.
In addition, in the previous image, we computed a 14-day SMA with the ATR values, an essential component to find periods of high price variation. It is possible to observe that every time the ATR surpasses SMA, it is likely a sharp increase or decrease in the price.
Backtesting the Strategy
One of the key components of backtesting our strategy is the signals. The signals show the time for having a long or short position. To obtain these signals, we express the following trading rules.
The idea is simple: when ATR is higher than its SMA, it shows a sudden price movement. Meanwhile, the price change of the last 5 days identifies the trend, whether the price is decreasing or increasing.
In the following image, to estimate its function, a loop is necessary to get, for each day, the closing price, the closing price of the previous 5 days, and the ATR value.
The following image shows the get_signals function, which takes two arguments: data and size. Inside the function, the first step is to get the positions of the columns Close, ATR, and ATR_SMA with .get_loc. Then, the variable signal_ is created, showing a long position with 1 and a short position with -1. Subsequently, we create the values_list to record buy or sell operations. Inside the loop, you can see how the first size values are skipped. Then, the difference between closing prices, price_diff (in the example size=3, meaning three days) is calculated. Next, the ATR values and their averages in atr_value and atr_sma_value are obtained. It’s important to remember that .iloc[i, patr] means that we will find the value located in row i with column patr. Then, we implement the conditions price_diff < 0 and atr_value > atr_sma_value and price_diff > 0 and atr_value > atr_sma_value, indicating a buy (signal_=1) and a short position (signal_=-1), respectively.
Getting Returns and Results
The following image shows the return calculations, and plots them:
We explained the previous code in another article. You can find examples with similar codes in the following articles:
https://www.quantifiedstrategies.com/how-to-build-a-simple-sma-trading-strategy-using-python/
https://www.quantifiedstrategies.com/how-i-made-a-weighted-moving-average-strategy-using-python/
Our strategy generates a cumulative return of approximately 50%, which is higher than the return obtained from SPY. Similarly, our strategy’s returns grow steadily over time with less variation.
The same Strategy for Four ETFs
In this section, we will explore the utility of the functions created in Python. First, we create another function:
If we compare the equity_curve_2 function with equity_curve, we see they are similar but not identical. The new function uses plt.plot which plots multiple graphs on one chart.
The following image implements the previously created functions. First, we make a list with four ETFs. Inside the loop, we add the functions. Notice how we need only a few lines of code to obtain results for four ETFs.
Using the functions created, we can automatize the task of plotting the equity curve in less time and with fewer lines of code. You can add 10 or more financial tickers and analyze them with the previous function.
The following image shows the equity curve for the four ETFs:
FAQ
How is the ATR calculated, and what is its significance in trading?
The ATR is a volatility indicator that gauges how much a stock’s price fluctuates in a day. The ATR is calculated using the True Range values, and it represents the average price range over a specified period. It is significant in trading as it helps identify periods of high volatility, allowing traders to adjust their strategies accordingly.
How do you download financial instrument data in Python for analysis?
Financial instrument data can be downloaded in Python using the download_data function, which takes parameters such as stock name, start date, and end date. The function uses Python libraries like pandas and yfinance to fetch and return the financial data. There is a tutorial above that demonstrates a practical example using Python, where financial instrument data (SPY in this case) is downloaded and analyzed. Functions are implemented to calculate ATR, plot price and ATR charts, and backtest the strategy.
What trading rules are used for backtesting the ATR strategy?
The backtesting strategy involves buying when the ATR is higher than its SMA (Simple Moving Average) and the price change of the last 5 days indicates an upward trend. Conversely, selling occurs when the ATR is higher than its SMA, and the price change of the last 5 days indicates a downward trend.
How are signals generated for long or short positions in the backtesting strategy?
Signals for long or short positions are generated based on specific trading rules. The get_signals function calculates these signals by comparing the ATR values with their SMA and analyzing the price change over the last 5 days.