Indicator · Pine Script v6 · Own pane

Adaptive Regime Filter + Divergence (AER-VN) [KEYALGOS]

by Focal-QuantAI· code credited to KeyAlgos

This indicator calculates Kaufman's Efficiency Ratio normalized by an ATR ratio to create a dynamic volatility-adjusted threshold.

View on GitHub

GitHub stars1on the repository
Pine versionv6current
Lines of code163
Settings13inputs
LicenceNone statedfile: MPL-2.0
Last update6 months ago11 Apr 2026

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new indicator, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart, then adjust the settings with the gear icon next to its name.

Source Code

163 lines of Pine Script v6 from strategies/adaptive_regime_filter_divergence_aer_vn_keyalgos/8qT99GymFOSVb2bbAaMQ_code.pine, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

8qT99GymFOSVb2bbAaMQ_code.pine
// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © KeyAlgos
//@version=6
indicator("Adaptive Regime Filter + Divergence (AER-VN) [KEYALGOS]", shorttitle="AER+Div [KEYALGOS]", overlay=false, format=format.price, precision=2)

// ========================================================================= //
// =============================== INPUTS ================================== //
// ========================================================================= //
grp_er    = "Efficiency Ratio Settings"
length    = input.int(10, title="ER Lookback (N)", minval=2, group=grp_er)
baseEr    = input.float(0.25, title="Base ER Threshold", step=0.05, minval=0.05, maxval=0.8, group=grp_er)
maxErCap  = input.float(0.65, title="Max Threshold Cap", step=0.05, minval=0.1, maxval=0.99, group=grp_er)

grp_vol   = "Volatility Normalization"
atrLength = input.int(14, title="ATR Length", minval=1, group=grp_vol)
atrMeanLen= input.int(50, title="ATR Mean Lookback", minval=5, group=grp_vol)

grp_div   = "Divergence Settings"
divLength = input.int(10, title="Swing Definition Length", minval=3, group=grp_div)

// Marker Toggles
showReg   = input.bool(true, title="Show Regular Div Markers", group=grp_div)
showHid   = input.bool(true, title="Show Hidden Div Markers", group=grp_div)

// Line Toggles
showRegBearLine = input.bool(true, title="Line: Regular Bearish", group=grp_div)
showRegBullLine = input.bool(true, title="Line: Regular Bullish", group=grp_div)
showHidBearLine = input.bool(true, title="Line: Hidden Bearish", group=grp_div)
showHidBullLine = input.bool(true, title="Line: Hidden Bullish", group=grp_div)

grp_vis   = "Visuals"
showBars  = input.bool(true, title="Color Price Bars", group=grp_vis)

// ========================================================================= //
// ======================= CORE AER + VOLATILITY =========================== //
// ========================================================================= //

float displacement = math.abs(close - close[length])
float pathDistance = math.sum(math.abs(close - close[1]), length)
float er = pathDistance != 0 ? (displacement / pathDistance) : 0.0

float currentAtr = ta.atr(atrLength)
float meanAtr    = ta.sma(currentAtr, atrMeanLen)
float atrRatio   = meanAtr != 0 ? (currentAtr / meanAtr) : 1.0

float rawThreshold     = baseEr * atrRatio
float dynamicThreshold = math.min(rawThreshold, maxErCap)

// ========================================================================= //
// ======================= REGIME CLASSIFICATION =========================== //
// ========================================================================= //

bool isTrending  = er > dynamicThreshold
bool isUptrend   = isTrending and (close > close[length])
bool isDowntrend = isTrending and (close < close[length])

bool isNonTrending   = er <= dynamicThreshold
bool isChop          = isNonTrending and (currentAtr > meanAtr)
bool isConsolidation = isNonTrending and (currentAtr <= meanAtr)

color colUp   = color.new(color.teal, 0)
color colDown = color.new(color.maroon, 0)
color colChop = color.new(color.orange, 0)
color colCons = color.new(color.gray, 0)

color regimeColor = switch
    isUptrend       => colUp
    isDowntrend     => colDown
    isChop          => colChop
    isConsolidation => colCons
    => color.gray

barcolor(showBars ? regimeColor : na)

// ========================================================================= //
// ================== ZERO-LAG DIVERGENCE DETECTION ======================== //
// ========================================================================= //

bool swingHighConfirm = (close[1] == ta.highest(close, divLength)[1]) and (close < close[1])
bool swingLowConfirm  = (close[1] == ta.lowest(close, divLength)[1])  and (close > close[1])

var float lastHighPrice = na
var float lastHighER    = na
var int   lastHighBar   = na

var float lastLowPrice  = na
var float lastLowER     = na
var int   lastLowBar    = na

bool regBear = false
bool regBull = false
bool hidBear = false
bool hidBull = false

if swingHighConfirm
    float currentHighPrice = close[1]
    float currentHighER    = er[1]
    int   currentHighBar   = bar_index[1]
    
    if not na(lastHighPrice)
        // Reg Bearish: Price Higher High, ER Lower High
        if (currentHighPrice > lastHighPrice) and (currentHighER < lastHighER)
            regBear := true
            if showRegBearLine
                line.new(lastHighBar, lastHighER, currentHighBar, currentHighER, color=color.red, style=line.style_dotted, width=2)
                
        // Hidden Bearish: Price Lower High, ER Higher High
        if (currentHighPrice < lastHighPrice) and (currentHighER > lastHighER)
            hidBear := true
            if showHidBearLine
                line.new(lastHighBar, lastHighER, currentHighBar, currentHighER, color=color.orange, style=line.style_dotted, width=2)
            
    lastHighPrice := currentHighPrice
    lastHighER    := currentHighER
    lastHighBar   := currentHighBar

if swingLowConfirm
    float currentLowPrice = close[1]
    float currentLowER    = er[1]
    int   currentLowBar   = bar_index[1]
    
    if not na(lastLowPrice)
        // Reg Bullish: Price Lower Low, ER Higher Low
        if (currentLowPrice < lastLowPrice) and (currentLowER > lastLowER)
            regBull := true
            if showRegBullLine
                line.new(lastLowBar, lastLowER, currentLowBar, currentLowER, color=color.lime, style=line.style_dotted, width=2)
                
        // Hidden Bullish: Price Higher Low, ER Lower Low
        if (currentLowPrice > lastLowPrice) and (currentLowER < lastLowER)
            hidBull := true
            if showHidBullLine
                line.new(lastLowBar, lastLowER, currentLowBar, currentLowER, color=color.aqua, style=line.style_dotted, width=2)
            
    lastLowPrice := currentLowPrice
    lastLowER    := currentLowER
    lastLowBar   := currentLowBar

// ========================================================================= //
// ============================== PLOTTING ================================= //
// ========================================================================= //

// Base Oscillator
plot(er, title="Efficiency Ratio", color=regimeColor, linewidth=2, style=plot.style_line)
plot(dynamicThreshold, title="Dynamic Threshold", color=color.new(color.white, 50), linewidth=1, style=plot.style_cross)
hline(baseEr, title="Base Threshold", color=color.new(color.gray, 50), linestyle=hline.style_dotted)

// Divergence Visuals (Shapes exactly on the ER line, set to tiny)
plotshape(showReg and regBear ? er[1] : na, title="Regular Bearish", location=location.absolute, color=color.red, style=shape.circle, size=size.tiny, offset=-1)
plotshape(showReg and regBull ? er[1] : na, title="Regular Bullish", location=location.absolute, color=color.lime, style=shape.circle, size=size.tiny, offset=-1)

plotshape(showHid and hidBear ? er[1] : na, title="Hidden Bearish", location=location.absolute, color=color.orange, style=shape.circle, size=size.tiny, offset=-1)
plotshape(showHid and hidBull ? er[1] : na, title="Hidden Bullish", location=location.absolute, color=color.aqua, style=shape.circle, size=size.tiny, offset=-1)

// Dashboard States
plotchar(isUptrend, title="State: Uptrend", char="", color=colUp, display=display.data_window)
plotchar(isDowntrend, title="State: Downtrend", char="", color=colDown, display=display.data_window)
plotchar(isChop, title="State: Choppiness", char="", color=colChop, display=display.data_window)
plotchar(isConsolidation, title="State: Consol", char="", color=colCons, display=display.data_window)

// Alerts
alertcondition(regBear, title="Regular Bearish Divergence", message="ER Bearish Divergence Detected")
alertcondition(regBull, title="Regular Bullish Divergence", message="ER Bullish Divergence Detected")

Overview

Adaptive Regime Filter + Divergence (AER-VN) [KEYALGOS] classifies market states into uptrend, downtrend, choppy, or consolidation regimes and colors price chart bars accordingly. It also detects regular and hidden divergences based on configurable swing lookback lengths, drawing markers and divergence lines. The indicator plots in a separate pane, allowing traders to evaluate trend efficiency alongside price action. Key settings include lookback lengths, ATR smoothing, and visual toggles.

Details

Published by

Focal-QuantAI on GitHub

Code credit

KeyAlgos, as written in the script's header

Type

Indicator, Pine Script v6

Draws

Separate pane below the chart

Category

Trend, Volatility & bands, Divergence

Markets

Any symbol

Timeframes

Any timeframe

Risk Notes

No repainting, lookahead or stacked entries were found in its code or README. That says nothing about how well it works: test it first.

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
ER Lookback (N)int10length
Base ER Thresholdfloat0.25baseEr
Max Threshold Capfloat0.65maxErCap
ATR Lengthint14atrLength
ATR Mean Lookbackint50atrMeanLen
Swing Definition Lengthint10divLength
Show Regular Div MarkersbooltrueshowReg
Show Hidden Div MarkersbooltrueshowHid
Line: Regular BearishbooltrueshowRegBearLine
Line: Regular BullishbooltrueshowRegBullLine
Line: Hidden BearishbooltrueshowHidBearLine
Line: Hidden BullishbooltrueshowHidBullLine
Show all 13 settings
SettingTypeDefaultVariable
Color Price BarsbooltrueshowBars
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.

Similar Pine Scripts

QQE + AK Trend + EFI

by realanthonyc
2 stars

This indicator computes and plots a QQE histogram using RSI of the chosen source smoothed with Wilder's ATR method, alongside an AK Trend line derived from fast EMAs with dynamic scale factors adjusted by timeframe. It also calculates Elder Force Index with ad

Indicator v6 TrendOscillators & momentum
Updated 10 months ago · MPL-2.0 GitHub repository of QQE + AK Trend + EFI

Adaptive Fair Value Cloud calculates a volatility-adaptive fair value channel around a selectable centerline, such as KAMA, EMA, linear regression, or VWMA. It blends ATR and mean deviation with volatility percentiles and trend sensors, including ADX, Efficien

Indicator v6 Volatility & bandsTrend
Updated yesterday · MIT GitHub repository of Adaptive Fair Value Cloud [WavesUnchained]
2 stars

The Refined Multi-TF Crypto Analyzer plots technical analysis signals on the main price chart by combining multi-timeframe moving averages, RSI, ADX, and volume spikes. It checks for trend alignment between the chart timeframe and a higher timeframe, identifie

Indicator v6 TrendOscillators & momentum Repaints
Updated 1 year ago · None stated GitHub repository of Refined Multi-TF Crypto Analyzer

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

Indicator v5 TrendVolatility & bands
Updated 1 year ago · MPL-2.0 GitHub repository of Trend Following Setup - Sideways Market Skipper
330 stars

This indicator plots a TTM Squeeze momentum oscillator and a MACD line in a separate pane. It builds the squeeze oscillator from a linear regression of price against a high-low and simple moving average midpoint, and colors the area by slope and sign. Circles

Indicator v5 Oscillators & momentumVolatility & bands
Updated 2 months ago · None stated GitHub repository of TTM Squeeze + MACD line [Alorse]
147 stars

This indicator generates trade entry signals and target levels optimized for 1-hour timeframes, designed for external signal extraction. It calculates 7-period and 16-period EMAs alongside 10-period RSI and ATR filters. Long signals occur when the fast EMA cro

Indicator v5 TrendOscillators & momentum
Updated 6 weeks ago · MIT GitHub repository of Signal Strategy 100 Candles of 1H Timeframe

More indicators

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers