In this article, we will implement a simple trading strategy using the ATR indicator.
From the discussion in the previous post, ATR itself does not provide indication about price trend. Instead, it is used to measure market volatility. A stock with a high level of volatility usually has a higher ATR, and similarly, a stock with a lower volatility has a lower ATR.
An old trading saying that "Market take the stairs up and the elevator down." This phenomenon is explained by the fear factor from Behavioral Finance, which is the way how the equity market has been functioning for centuries. As seen from the chart below, during downtrends, the ATR indicator tends to post higher volatility than during up trend.
Thus, we can use ATR as a stop loss indicator for order exit and to protect downside risk (so called Chandelier Exit). The chandelier exit places a trailing stop under the highest high the stock reached since you entered the trade. The distance between the highest high and the stop level is defined as some multiple of the ATR. For example,
- if you buy a stock at $100 and the ATR value is 3, you may place a stop loss at 2 x ATR below the entry price. i.e. 100-2*3 = $94,
- if you short-sell a stock at $100 and the ATR is 3, you may place a stop loss at 2 x ATR above the entry price. i.e. 100+2*3 = $106
- when the market price continues to rise (drop for a sell order), we will revise the stop loss level upward (downward) with the newly calculated ATR multiple
Suppose we use RSI(14) for order entry (refer to Technical Indicator - Relative Strength Index (RSI)) and ATR(14) for order exit, and apply this strategy to the daily closing price of Nikkei 225 Index CFD (i.e. JPXJPY) over the year of 2020.
- Based on a sliding window approach to collect the previous 14 closing price
- Calculate the latest ATR and RSI values
- Order open conditions:
- if we have NO outstanding position,
- if RSI value < 30, we open a buy order with stoploss level set to current price - 2*ATR
- if RSI value > 70, we open a sell order with stoploss level set to current price + 2*ATR
- Order close conditions:
- if we have outstanding position,
- if we previously submit a buy order, update the stop-loss level to the maximum of the previous stop-loss and (current price - 2*ATR)
- if we previously submit a sell order, update the stop-loss level to the minimum of the previous stop-loss and (current price + 2*ATR)
- Repeat the process until the backtest period end
Now, let's write down our trading algorithm step-by-step.
Step 1. Calculate RSI and ATR value
First of all, we define 'RSI_period', 'ATR_period' and 'instrument' at initialization.
We use the API function getHistoricalBar to collect historical observations. Then, we apply a python library 'talib.RSI', 'talib.ATR' to calculate the latest RSI and ATR value.
Step 2. Order Entry Conditions
We further define 'rsi_overbought', 'rsi_oversold' and 'ATR_multiple' at initialization.
We also create a function 'open_order' to handle order submissions.
Now, we update the system's function 'on_marketdatafeed' for order open logic.
Step 3. Order Close Condition
For order closing logic, we recalculate and update the new stop loss level in 'on_marketdatafeed' function. (refer to line 36 - 49)
Full Source Code
Combining all above, the full script is presented below.
Now, we are prepared to backtest this strategy.
- Instrument: JPXJPY
- Period: 2020.01 - 2020.12
- Initial Capital: US$10,000
- Data Interval: 1-day bar
- Leverage: 100
- Allow Shortsell: True
Some highlights for applying ATR in a trading strategy as below:
- ATR is mainly used to determine order exit condition, but not for order entry
- Multi-period ATRs (eg. 5 and 14) could be used to compare and have a sense about the recent "market volatility"
- The rule of thumb for ATR period is 14
- Is there any better choice?
- Can this value be dynamically changing?
- Will it be generally applicable to other financial instruments/ asset classes?