Tutorial

ADX in Pine Script: Measuring Trend Strength

What the Average Directional Index measures, why it answers a different question than most indicators, and how to build it with +DI and -DI in Pine Script v6.

10 min read

Most indicators try to tell you which way price is going. The Average Directional Index, or ADX, is unusual because it does not care about direction at all. It answers a different and often more useful question: is there a trend worth trading, or is the market just chopping sideways? That makes ADX less a signal and more a filter, the tool that tells your other indicators when to speak up and when to sit down. This guide explains what ADX measures, why traders pair it with directional tools, and how to build it from scratch in Pine Script v6 on TradingView.

This is a coding tutorial, not trading advice. ADX is a way to express "how strong is the trend right now" in code, and understanding it is the key to knowing when trend-following logic is likely to work.

What ADX measures

ADX comes from the same directional movement system that J. Welles Wilder Jr. introduced in 1978, and it arrives as a trio. Two of the three lines are directional: +DI measures the strength of upward movement, and -DI measures the strength of downward movement. The ADX line itself is derived from how far apart those two directional lines are, then smoothed. When +DI and -DI are far apart, one direction is clearly dominating, so ADX is high. When they are tangled together, neither side is winning, so ADX is low.

The important consequence is that ADX rises in a strong trend regardless of whether that trend is up or down. A powerful downtrend produces a high ADX just as a powerful uptrend does, because ADX measures the strength of the move, not its sign. To know the direction, you read the two DI lines; to know whether the trend is strong enough to bother with, you read ADX. The conventional interpretation uses a few rough thresholds.

ADX readingInterpretation
Below 20Weak or absent trend, ranging
20 to 25Trend may be emerging
25 to 50Strong trend
Above 50Very strong trend

Why traders use it

ADX exists to solve a specific problem: trend-following indicators produce their worst results in range-bound markets, where they whipsaw endlessly. If you could reliably tell when a market is trending versus ranging, you could switch your trend tools on only when they have a chance of working. That is exactly what ADX offers. Many traders use it purely as a gate, allowing moving-average or Supertrend signals to fire only when ADX confirms a trend is present, and ignoring them when ADX is low.

The DI lines add a directional layer for those who want it. A crossover of +DI above -DI while ADX is rising is read as a strengthening uptrend, and the mirror as a strengthening downtrend. But the more common and arguably more robust use is the filter role, because ADX's real strength is telling you when not to trade a trend system rather than precisely when to enter.

Building the indicator

Pine Script provides the directional movement system through the ta.dmi() function, which returns +DI, -DI, and ADX together as a tuple. Here is the complete v6 indicator.

pine
//@version=6
indicator("ADX and DI", overlay = false)

diLength  = input.int(14, "DI Length")
adxSmooth = input.int(14, "ADX Smoothing")

[diPlus, diMinus, adx] = ta.dmi(diLength, adxSmooth)

plot(adx, "ADX", color = color.black, linewidth = 2)
plot(diPlus, "+DI", color = color.green)
plot(diMinus, "-DI", color = color.red)

hline(25, "Trend Threshold", color = color.gray, linestyle = hline.style_dashed)

The working line is [diPlus, diMinus, adx] = ta.dmi(diLength, adxSmooth). The ta.dmi() function takes two lengths, one for the directional indicators and one for smoothing the ADX, and returns all three series in a tuple that Pine unpacks into named variables. The three plot() calls draw the lines in their own pane, and the hline() at 25 marks the conventional threshold above which a trend is considered meaningful. Watching the black ADX line rise above and fall below that level is the core read the indicator provides.

Using ADX as a trend filter

ADX is at its best combined with a directional signal. Here is a strategy that takes a moving-average crossover, but only when ADX confirms a trend is actually present, which is the single most common way ADX is used in practice.

pine
//@version=6
strategy("MA Cross Filtered by ADX", overlay = true, margin_long = 100, margin_short = 100)

adxThreshold = input.int(25, "ADX Threshold")

[diPlus, diMinus, adx] = ta.dmi(14, 14)

fastMA = ta.ema(close, 9)
slowMA = ta.ema(close, 21)

crossUp    = ta.crossover(fastMA, slowMA)
trending   = adx > adxThreshold

if crossUp and trending
    strategy.entry("Long", strategy.long)

if ta.crossunder(fastMA, slowMA)
    strategy.close("Long")

The condition trending = adx > adxThreshold is the gate. The crossover entry only fires when ADX confirms a trend of some strength, which filters out the crossovers that happen during choppy, directionless stretches, exactly where a bare moving-average cross whipsaws most. Assigning crossUp to its own variable before the if keeps the crossover function running every bar, the same hoisting habit we stress across these guides. This pattern pairs naturally with our moving average crossover guide, which builds the entry signal ADX is filtering here.

The honest pitfalls

The first pitfall is expecting ADX to tell you direction. It will not; a high ADX in a downtrend looks identical to a high ADX in an uptrend. Always read the DI lines or a separate directional signal alongside it. The second is that ADX lags, because it is a smoothed measure of a smoothed measure. By the time ADX confirms a strong trend, a good part of the move has often already happened, so it is better at keeping you out of ranges than at getting you in early.

The thresholds are also conventions, not laws. The 25 line is a common dividing point between ranging and trending, but different markets and timeframes trend at different ADX levels, so treat it as a starting point to reason about rather than a fixed rule. As always, test any ADX-filtered strategy across a meaningful sample. To see the +DI, -DI, and ADX math computed step by step from OHLC data, our ADX calculator lays it out with the Pine Script equivalent alongside.

Building it faster

Coding ADX by hand is instructive because the directional movement system is one of the more involved calculations in technical analysis, and seeing it assembled from the DI lines demystifies it. When you already know how you want to use ADX, describing the rule in plain English is faster than wiring the tuple and thresholds together. A tool like PineScripter generates the v6 code and fixes compile errors automatically by reading TradingView's messages. You can compare it against other options in our roundup of the best AI Pine Script generators.

The takeaway

ADX measures trend strength, not direction, delivered alongside +DI and -DI by one function, ta.dmi(). Its real value is as a filter that tells your directional tools when a trend is strong enough to trade and when to stand aside. Build it, use it to gate a directional signal rather than as a signal on its own, and remember it answers how strong, never which way.


Disclaimer: PineScripter is a coding tool for Pine Script development. It does not provide financial advice and does not guarantee trading profits. Always backtest strategies thoroughly and understand the risks before live trading.