This is a trend following strategy that combines the ATR indicator and the ADX indicator. It dynamically adjusts the ATR multiplier according to market trend conditions to achieve better trend tracking.
The strategy is mainly based on the ATR indicator and the ADX indicator.
Firstly, it calculates the True Range (ATR) and ADX. ATR reflects the volatility of the market while ADX judges the trend strength.
Secondly, it determines the current trend direction according to the difference between DI+ and DI- in the ADX indicator. If DI+ is higher than DI-, it is an uptrend. If DI- is higher than DI+, it is a downtrend.
Then, when ADX is rising, it uses a larger ATR multiplier (m1). When ADX is falling, it uses a smaller ATR multiplier (m2) to achieve dynamic adjustment. This is the core of the strategy.
Finally, combined with ATR and the midpoint of price, it calculates the upper and lower bands to determine the trend direction. When price breaks through the upper band, it goes long. When price breaks through the lower band, it goes short.
So the strategy incorporates ATR and ADX, and by dynamically adjusting ATR parameters, it can better capture trends for trading.
The strategy has several obvious advantages:
Therefore, this is a very practical trend following strategy with good drawdown control. Worth recommending.
The strategy also has some risks:
So parameter optimization and risk control need attention. Also, black swan events can have greater impact.
The strategy can be optimized in the following aspects:
So there is still much room for optimization by adjusting parameters and mechanisms according to the problems.
In general, this Adaptive ATR-ADX Trend Strategy V2 performs very well. By dynamically adjusting ATR parameters, it captures trends nicely. Also, combining two indicators in ATR and ADX makes it more robust. But we still need to pay attention to risk control and optimization to prevent lagging and oversized losses. Overall, the strategy is well worth learning and applying.
/*backtest start: 2022-11-28 00:00:00 end: 2023-12-04 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=2 // From mortdiggiddy's indicator to strategy // See also: https://www.tradingview.com/u/mortdiggiddy/ strategy(title = "Adaptive ATR-ADX Trend V2", shorttitle = "Adaptive ATR V2 Strategy", overlay = true) //Mode src = input(title = "Source", defval = hlc3) atrLen = input(title = "ATR", defval = 21, minval = 1, maxval = 100) m1 = input(title = "ATR Multiplier - ADX Rising", type = float, defval = 3.5, minval = 1, step = 0.1, maxval = 100) m2 = input(title = "ATR Multiplier - ADX Falling", type = float, defval = 1.75, minval = 1, step = 0.1, maxval = 100) adxLen = input(title = "ADX", defval = 14, minval = 1, maxval = 100) adxThresh = input(title = "ADX Threshold", defval = 30, minval = 1) aboveThresh = input(true, title = "ADX Above Threshold uses ATR Falling Multiplier Even if Rising?") useHeiken = input(false, title = "Use Heiken-Ashi Bars (Source will be ohlc4)") // DI-Pos, DI-Neg, ADX hR = change(high) lR = -change(low) dmPos = hR > lR ? max(hR, 0) : 0 dmNeg = lR > hR ? max(lR, 0) : 0 sTR = nz(sTR[1]) - nz(sTR[1]) / adxLen + tr sDMPos = nz(sDMPos[1]) - nz(sDMPos[1]) / adxLen + dmPos sDMNeg = nz(sDMNeg[1]) - nz(sDMNeg[1]) / adxLen + dmNeg DIP = sDMPos / sTR * 100 DIN = sDMNeg / sTR * 100 DX = abs(DIP - DIN) / (DIP + DIN) * 100 adx = sma(DX, adxLen) // Heiken-Ashi xClose = ohlc4 xOpen = (nz(xOpen[1]) + nz(close[1])) / 2 xHigh = max(high, max(xOpen, xClose)) xLow = min(low, min(xOpen, xClose)) // Trailing ATR v1 = abs(xHigh - xClose[1]) v2 = abs(xLow - xClose[1]) v3 = xHigh - xLow trueRange = max(v1, max(v2, v3)) atr = useHeiken ? rma(trueRange, atrLen) : atr(atrLen) m = rising(adx, 1) and (adx < adxThresh or not aboveThresh) ? m1 : falling(adx, 1) or (adx > adxThresh and aboveThresh) ? m2 : nz(m[1]) mUp = DIP >= DIN ? m : m2 mDn = DIN >= DIP ? m : m2 src_ = useHeiken ? xClose : src c = useHeiken ? xClose : close t = useHeiken ? (xHigh + xLow) / 2 : hl2 up = t - mUp * atr dn = t + mDn * atr TUp = max(src_[1], c[1]) > TUp[1] ? max(up, TUp[1]) : up TDown = min(src_[1], c[1]) < TDown[1] ? min(dn, TDown[1]) : dn trend = min(src_, min(c, close)) > TDown[1] ? 1 : max(src_, max(c, close)) < TUp[1]? -1 : nz(trend[1], 1) stop = trend == 1 ? TUp : TDown trendChange = change(trend) longCondition = (trendChange > 0) if (longCondition) strategy.entry("long", strategy.long) shortCondition = (trendChange < 0) if (shortCondition) strategy.entry("short", strategy.short) // Plot lineColor = not(trendChange) ? trend > 0 ? #00FF00DD : #FF0000DD : #00000000 shapeColor = trendChange ? trendChange > 0 ? #00FF00F8 : #FF0000F8 : #00000000 plot(stop, color = lineColor, style = line, linewidth = 1, title = "ATR Trend") plotshape(trendChange ? stop : na, style = shape.circle, size = size.tiny, location = location.absolute, color = shapeColor, title = "Change") alertcondition(trendChange > 0, title = "ATR-ADX Change Up", message = "ATR-ADX Change Up") alertcondition(trendChange < 0, title = "ATR-ADX Change Down", message = "ATR-ADX Change Down") // end