0bps

Strategy vault / Trend following

Super ATR Trend Following Strategy

The Super ATR Trend Following Strategy is an ATR indicator based trend following strategy. It uses the ATR indicator to measure market volatility and sets stop loss based on multiple ATRs to track trends.

Author
ChaoZhang
Complexity
Intermediate · 54 lines
Parameters
11
Backtest bar
1d · swing
Tested on
BTC/USDT · futures

IMG

Overview

The Super ATR Trend Following Strategy is an ATR indicator based trend following strategy. It uses the ATR indicator to measure market volatility and sets stop loss based on multiple ATRs to track trends.

Strategy Logic

The strategy first calculates the ATR indicator, which is the moving average of the price volatility over the past N days, to represent market risk and volatility. The strategy allows us to change the ATR calculation method, either regular ATR or SMA.

Then the upper and lower bands are calculated based on ATR value multiplied by a factor, ie: close - Multiplier * ATR for upper band; close + Multiplier * ATR for lower band. This forms an ATR based trend channel.

We then judge if the current price breaks through the upper or lower band of the channel. If price breaks through the upper band, it is judged as entering a downtrend; if price breaks through the lower band, it is judged as entering an uptrend. When there is a trend breakout, we make the corresponding buy and sell.

In addition, the strategy has set a trading time window to only trade in the specified date time range.

Advantage Analysis

This indicator channel based trend following strategy has the following advantages:

  1. Using ATR indicator to automatically adjust stop loss position effectively controls risks
  2. ATR considers price volatility, more reasonable stop loss
  3. Increase entry precision by channel breakout
  4. Allows adjustment of ATR calculation method, more flexible
  5. Setting trading window avoids strategy failure during significant events

In general, this is a simple and practical trend following strategy that can effectively control risks and obtain good returns.

Risk Analysis

There are also some risks to this strategy:

  1. Market may have violent changes that ATR fails to react timely, resulting in too loose stop loss
  2. Price may range in channel when sentiment diverges, increasing trading risk
  3. Fixed multiple may not suit all products, needs adjustment accordingly
  4. setWindow limits trading opportunities, may miss good trades if not set properly

To control these risks, we can take the following measures:

  1. Combine other indicators to determine market condition, avoid solely relying on ATR
  2. Add filters to avoid invalid breakout introducing trade risk
  3. Select proper multiplier according to historical characteristics of different products
  4. Optimize and test setWindow parameters to ensure proper setup

Optimization

There is room for further optimization of this strategy:

  1. Introduce machine learning algorithms to dynamically optimize multiplier
  2. Incorporate sentiment indicators etc to optimize channel range
  3. Add volume or volatility confirmation to avoid invalid breakout
  4. Utilize advanced time based strategy framework for backtest

These optimizations can further improve the stability and profitability of the strategy.

Conclusion

Overall this is a very practical trend following strategy. It builds an adaptive channel using ATR indicator and determines entries by channel breakouts. The strategy is simple and effective to control risks, suitable for tracking mid-long term trends. We also proposed further risk control and optimization suggestions to make the strategy more robust.

Parameters

NameDefaultWhat it controls
v_input_110ATRtimeframe
v_input_2_hl20Price data source: hl2 | high | low | open | close | hlc3 | hlcc4 | ohlc4
v_input_float_13ATR Multiplier
v_input_3trueChange ATR calculation method
v_input_4falseShow buy/sell signals
v_input_int_19From Month
v_input_int_2trueFrom Day
v_input_int_32018From Year
v_input_int_4trueTo Month
v_input_int_5trueTo Day
v_input_int_69999To Year

Source Pine Script

/*backtest
start: 2023-02-12 00:00:00
end: 2024-02-18 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
strategy('BFactory Manager @Super Trend Simplified Optimized Version', overlay=true)
Periods = input(title='ATRtimeframe', defval=10)
src = input(hl2, title='Price data source')
Multiplier = input.float(title='ATR Multiplier', step=0.1, defval=3.0)
changeATR = input(title='Change ATR calculation method', defval=true,tooltip = 'Default is art otherwise sma(ta.tr,ATR period)')
showsignals = input(title='Show buy/sell signals', defval=false)
atr2 = ta.sma(ta.tr, Periods)
atr = changeATR ? ta.atr(Periods) : atr2
up = src - Multiplier * atr
up1 = nz(up[1], up)
up := close[1] > up1 ? math.max(up, up1) : up
dn = src + Multiplier * atr
dn1 = nz(dn[1], dn)
dn := close[1] < dn1 ? math.min(dn, dn1) : dn
trend = 1
trend := nz(trend[1], trend)
trend := trend == -1 and close > dn1 ? 1 : trend == 1 and close < up1 ? -1 : trend
upPlot = plot(trend == 1 ? up : na, title='Uptrend', style=plot.style_linebr, linewidth=2, color=color.new(color.green, 0))
buySignal = trend == 1 and trend[1] == -1
plotshape(buySignal and showsignals ? up : na, title='Buy some', text='Buy some', location=location.absolute, style=shape.labelup, size=size.tiny, color=color.new(color.green, 0), textcolor=color.new(color.white, 0))
dnPlot = plot(trend == 1 ? na : dn, title='Downtrend', style=plot.style_linebr, linewidth=2, color=color.new(color.red, 0))
sellSignal = trend == -1 and trend[1] == 1
plotshape(sellSignal and showsignals ? dn : na, title='Selling Points', text='Selling Points', location=location.absolute, style=shape.labeldown, size=size.tiny, color=color.new(color.red, 0), textcolor=color.new(color.white, 0))
FromMonth = input.int(defval=9, title='From Month', minval=1, maxval=12)
FromDay = input.int(defval=1, title='From Day', minval=1, maxval=31)
FromYear = input.int(defval=2018, title='From Year', minval=999)
ToMonth = input.int(defval=1, title='To Month', minval=1, maxval=12)
ToDay = input.int(defval=1, title='To Day', minval=1, maxval=31)
ToYear = input.int(defval=9999, title='To Year', minval=999)
start = timestamp(FromYear, FromMonth, FromDay, 00, 00)
finish = timestamp(ToYear, ToMonth, ToDay, 23, 59)
window() =>
    time >= start and time <= finish ? true : false
longCondition = buySignal
if longCondition and window()
    strategy.entry('BUY', strategy.long, comment = 'go long')
shortCondition = sellSignal
if shortCondition and window()
    strategy.entry('SAL', strategy.short, comment = 'go short')

buy1 = ta.barssince(buySignal)
sell1 = ta.barssince(sellSignal)
color1 = buy1[1] < sell1[1] ? color.green : buy1[1] > sell1[1] ? color.red : na

Published by ChaoZhang on the FMZ strategy square · last modified 2024-02-19. Collected in the Quant Trading Vault. Unvalidated research: re-test with your own data and costs before trusting it.

Build this with AgenKit

A spec is not a trading system. Paste this into your coding agent and AgenKit runs a specialist team — architecture, test-first build, risk gates, review — with paper trading on by default.

in Claude Code, Cursor, Codex & 4 more
/agenkit build a production-grade trading bot with a backtest engine, risk controls and paper trading by default from strategies/Super-ATR-Trend-Following-Strategy.md
  1. npx agenkit install engineering-kit in your project
  2. Paste the command into your agent and approve each phase
  3. Get tests, backtest, risk controls and a paper-trading switch

Understand it first

Before you run this, read the lesson behind the idea and how to backtest it honestly. Specs like this one are the survivors of an unknown number of trials; deflate their results accordingly.

Related specs

esc

Try , , or .

↑↓ move↵ open