by damianpitt· code credited to Capital41 | MIT License
This indicator calculates the Average Directional Index alongside positive and negative directional movement lines to assess market trend strength and direction.
// Copyright (c) 2026 Capital41 | MIT License
// CAPITAL41 ADX FILTER v3
// What it does:
// - Shows ADX trend strength with DI+ and DI- directional indicators.
// - Background highlight when trend strength exceeds threshold.
// - DI crossover detection for trend direction changes.
// - Status badge and comprehensive alerts.
//
// v2 changes (expanded from 34-line original):
// - ADDED: DI+ and DI- lines with directional fill.
// - ADDED: ADX color changes by trend direction (DI+ > DI- = bull, DI- > DI+ = bear).
// - ADDED: Strong trend threshold zone.
// - ADDED: Status badge showing ADX value, DI+/DI-, and direction.
// - ADDED: Alert conditions (ADX threshold crosses, DI crossovers, strong trend).
//
// v3 changes:
// - FIXED: DI crossovers and ADX threshold crosses gated by barstate.isconfirmed,
// so alerts fire on bar close instead of flickering intra-bar.
//
// TradingView setup:
// 1) Open TradingView -> Pine Editor.
// 2) Paste this script, Save, and Add to chart.
// 3) Use 30m or 4h on BTC or US stocks.
//
// Usage guide (30m/4h):
// - Only take trades when ADX is above threshold (default 20).
// - DI+ > DI- = bullish trend direction; DI- > DI+ = bearish.
// - DI crossovers signal potential trend direction changes.
// - Strong trend zone (35+) indicates powerful trending conditions.
// - Combine with Fusion Scalp, Confluence, or Regime Matrix signals.
//@version=6
indicator("Capital41 ADX Filter v3", overlay = false, max_labels_count = 50)
// Inputs
adxLen = input.int(14, "DI length", minval = 2)
adxSmooth = input.int(14, "ADX smoothing", minval = 1)
threshold = input.int(20, "Trend threshold", minval = 5, maxval = 50)
strongThresh = input.int(35, "Strong trend threshold", minval = 20, maxval = 60)
showDI = input.bool(true, "Show DI+/DI- lines")
showFill = input.bool(true, "Show DI fill")
showBg = input.bool(true, "Highlight trending")
showBadge = input.bool(true, "Show status badge")
colorBull = color.new(color.lime, 0)
colorBear = color.new(color.red, 0)
colorNeutral = color.new(color.gray, 80)
// Compute DI+, DI-, and ADX via ta.dmi
[diPlus, diMinus, adxVal] = ta.dmi(adxLen, adxSmooth)
// Trend direction
bullDir = diPlus > diMinus
bearDir = diMinus > diPlus
// Trend strength classification
trending = adxVal >= threshold
strongTrend = adxVal >= strongThresh
// ADX color based on direction and strength
adxColor = not trending ? color.new(color.gray, 0) : bullDir ? colorBull : colorBear
// Plots
plot(adxVal, title = "ADX", color = adxColor, linewidth = 2)
diPlusPlot = plot(showDI ? diPlus : na, title = "DI+", color = color.new(colorBull, 30), linewidth = 1)
diMinusPlot = plot(showDI ? diMinus : na, title = "DI-", color = color.new(colorBear, 30), linewidth = 1)
plot(threshold, title = "Threshold", color = color.new(color.gray, 60), style = plot.style_line)
plot(strongThresh, title = "Strong", color = color.new(color.orange, 60), style = plot.style_line)
// Fill between DI lines
fill(diPlusPlot, diMinusPlot,
color = showFill and showDI ? (bullDir ? color.new(colorBull, 88) : color.new(colorBear, 88)) : na)
// Background
color bgColor = na
if showBg and strongTrend
bgColor := bullDir ? color.new(colorBull, 85) : color.new(colorBear, 85)
else if showBg and trending
bgColor := color.new(color.green, 92)
bgcolor(bgColor)
// DI crossovers and ADX threshold crosses (confirmed: lines can cross and
// uncross several times within one bar)
diCrossUp = ta.crossover(diPlus, diMinus) and barstate.isconfirmed
diCrossDown = ta.crossunder(diPlus, diMinus) and barstate.isconfirmed
adxCrossUp = ta.crossover(adxVal, threshold) and barstate.isconfirmed
adxCrossDown = ta.crossunder(adxVal, threshold) and barstate.isconfirmed
adxCrossHigh = ta.crossover(adxVal, strongThresh) and barstate.isconfirmed
// Status badge
var table status = table.new(position.bottom_left, 4, 1, border_width = 1)
if barstate.islast
if showBadge
adxText = " ADX " + str.tostring(adxVal, "#.0") + " "
diPText = " DI+ " + str.tostring(diPlus, "#.0") + " "
diMText = " DI- " + str.tostring(diMinus, "#.0") + " "
dirText = bullDir ? " BULL " : bearDir ? " BEAR " : " FLAT "
adxBg = strongTrend ? color.new(color.orange, 60) : trending ? color.new(color.green, 70) : colorNeutral
table.cell(status, 0, 0, adxText, bgcolor = adxBg, text_color = color.white, text_size = size.tiny)
table.cell(status, 1, 0, diPText, bgcolor = color.new(colorBull, 70), text_color = color.white, text_size = size.tiny)
table.cell(status, 2, 0, diMText, bgcolor = color.new(colorBear, 70), text_color = color.white, text_size = size.tiny)
table.cell(status, 3, 0, dirText, bgcolor = bullDir ? color.new(colorBull, 65) : bearDir ? color.new(colorBear, 65) : colorNeutral, text_color = color.white, text_size = size.tiny)
else
for i = 0 to 3
table.cell(status, i, 0, "", bgcolor = color.new(color.black, 100), text_color = color.new(color.black, 100))
// Alerts
alertcondition(adxCrossUp, title = "ADX Above Threshold",
message = "ADX Filter: ADX crossed above threshold on {{ticker}} ({{interval}})")
alertcondition(adxCrossDown, title = "ADX Below Threshold",
message = "ADX Filter: ADX crossed below threshold on {{ticker}} ({{interval}})")
alertcondition(diCrossUp, title = "DI+ Crossover",
message = "ADX Filter: DI+ crossed above DI- (bullish) on {{ticker}} ({{interval}})")
alertcondition(diCrossDown, title = "DI- Crossover",
message = "ADX Filter: DI- crossed above DI+ (bearish) on {{ticker}} ({{interval}})")
alertcondition(adxCrossHigh, title = "Strong Trend",
message = "ADX Filter: ADX crossed into strong trend zone on {{ticker}} ({{interval}})")
Overview
Displayed in a separate pane, it plots the ADX line, directional lines, and horizontal threshold levels with directional cloud fills and background color highlights. Directional movement crossovers and threshold breaches generate signals for trend state transitions. User inputs adjust the directional movement length, smoothing period, and threshold values, while toggling visual elements like fills and badges. As an indicator, it provides analytical filtering without automated trade execution rules.
The inputs you can change from the gear icon on the chart. Defaults are the author's.
Setting
Type
Default
Variable
DI length
int
14
adxLen
ADX smoothing
int
14
adxSmooth
Trend threshold
int
20
threshold
Strong trend threshold
int
35
strongThresh
Show DI+/DI- lines
bool
true
showDI
Show DI fill
bool
true
showFill
Highlight trending
bool
true
showBg
Show status badge
bool
true
showBadge
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.
This indicator plots the Schaff Trend Cycle in a separate pane. It subtracts a slow exponential moving average from a fast one, applies a stochastic cycle twice, and smooths each result to form a 0–100 oscillator. Line color follows the slope, or the upper and
This indicator plots a Supertrend-based trend-following setup in a separate pane and skips conditions it treats as a sideways market. A volatility range is built from an ATR value, with RMA, SMA, EMA, or WMA smoothing, or from a fixed point distance. Optional
This indicator calculates a modified MACD oscillator and signal line alongside a trend EMA filter, plotting the output as a stylized column histogram in a separate pane. Instead of plotting true MACD distance, it quantifies positive and negative histogram mome
This indicator plots the Average Directional Index in a separate pane and colors the line teal or maroon according to whether plus DI is above minus DI. A horizontal key level and a silver background mark periods when ADX exceeds that threshold. With labels en
Standardized Trend Map calculates series momentum relative to active price range across 40 distinct lookback periods ranging from 2 to 80 bars on an exponential moving average source. Each standardized calculation rounds to an integer values of -1, 0, or 1 to
Multi-Timeframe Analysis Suite calculates trend direction and momentum conditions across five user-selected timeframes using moving averages, RSI, and Stochastic oscillators. It evaluates moving average slope and oscillator levels to compute trend alignment, m