Indicator · Pine Script v5 · Own pane

DMS v2 Breadth Dispersion

by AssetWhisper

An indicator in a separate pane that compares a cap-weighted index with its equal-weighted counterpart, SPY and RSP by default, to gauge market breadth.

View on GitHub

GitHub stars1on the repository
Pine versionv5runs as is
Lines of code91
Settings7inputs
LicenceMPL-2.0
Last update7 weeks ago10 Sep 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

91 lines of Pine Script v5 from indicators/DMS_Breadth_Dispersion.pine, published under MPL-2.0. Keep the author's credit and licence lines when you reuse it.

DMS_Breadth_Dispersion.pine
//@version=5
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © AssetWhisper — https://assetwhisper.com/indicators/
// ============================================================================
//  DMS v2 — Breadth Dispersion (cap-weight vs equal-weight)
//  Idea: cuando el índice ponderado por capitalización sube pero su versión
//  equiponderada no acompaña, la subida la sostienen pocos valores (amplitud
//  estrecha): contexto frágil. El log-ratio EW/CW y su momentum miden la amplitud;
//  su z-score y percentil detectan extremos; las divergencias con el precio del
//  índice avisan de techos/suelos frágiles y los "thrusts" de amplitud confirman
//  giros. Es un panel de mercado: no depende del símbolo del gráfico.
//  Pares útiles: SPY/RSP, QQQ/QQEW, IWM/EWRS, o cualquier índice vs su equal-weight.
// ============================================================================
indicator("DMS v2 — Breadth Dispersion", shorttitle="DMS v2", overlay=false)

cwSym    = input.symbol("AMEX:SPY", "Cap-weighted index")
ewSym    = input.symbol("AMEX:RSP", "Equal-weighted index")
momLen   = input.int(20, "Ratio momentum (bars)", minval=5, maxval=120)
zLen     = input.int(100, "Z-score lookback", minval=30, maxval=500)
rankLen  = input.int(252, "Percentile lookback", minval=50, maxval=1000)
divLen   = input.int(20, "Divergence lookback", minval=10, maxval=100)
thrustTh = input.float(2.0, "Breadth thrust (% relative)", minval=0.5, maxval=10, step=0.5)

// === DATOS ===
cw = request.security(cwSym, timeframe.period, close, ignore_invalid_symbol=true)
ew = request.security(ewSym, timeframe.period, close, ignore_invalid_symbol=true)
dataOk = not na(cw) and not na(ew) and cw > 0 and ew > 0
ratio  = dataOk ? math.log(ew / cw) : na

// === AMPLITUD ===
ratioMom  = (ratio - ratio[momLen]) * 100          // % de rendimiento relativo EW vs CW
ratioMomS = ta.ema(ratioMom, 3)
zSd    = ta.stdev(ratioMom, zLen)
zRatio = zSd > 0 ? (ratioMom - ta.sma(ratioMom, zLen)) / zSd : 0.0
rankRatio = ta.percentrank(ratioMom, rankLen)
ratioFast = ta.ema(ratio, 20)
ratioSlow = ta.ema(ratio, 50)
breadthTrendUp = ratioFast > ratioSlow

// === DIVERGENCIAS Y THRUSTS ===
cwAtHigh    = cw >= ta.highest(cw, divLen)
cwAtLow     = cw <= ta.lowest(cw, divLen)
ratioAtHigh = ratio >= ta.highest(ratio, divLen)
ratioAtLow  = ratio <= ta.lowest(ratio, divLen)
bearDiv  = cwAtHigh and not ratioAtHigh and ratioMomS < 0      // índice en máximos con amplitud cayendo
bullDiv  = cwAtLow and not ratioAtLow and ratioMomS > 0        // índice en mínimos con amplitud mejorando
thrustUp = ta.crossover(ratioMomS, thrustTh)
thrustDn = ta.crossunder(ratioMomS, -thrustTh)
regime   = rankRatio >= 80 ? 1 : rankRatio <= 20 ? -1 : 0     // 1 = amplitud expandiéndose, -1 = concentración

regimeLabel = regime == 1 ? "BROAD (EW leads)" : regime == -1 ? "NARROW (CW leads)" : "NORMAL"
regimeColor = regime == 1 ? color.green : regime == -1 ? color.red : color.gray

// === VISUAL ===
hline(0, "Zero", color=color.gray)
hline(thrustTh, "Thrust +", color=color.new(color.green, 60), linestyle=hline.style_dashed)
hline(-thrustTh, "Thrust -", color=color.new(color.red, 60), linestyle=hline.style_dashed)
plot(ratioMomS, "EW-CW relative momentum %", style=plot.style_columns, color=ratioMomS >= 0 ? color.new(color.green, 40) : color.new(color.red, 40))
plot(zRatio, "Z-score", color=color.new(color.orange, 30), linewidth=2)
bgcolor(regime == 1 ? color.new(color.green, 93) : regime == -1 ? color.new(color.red, 93) : na, title="Breadth regime")
plotshape(bearDiv, "Bearish breadth divergence", style=shape.triangledown, location=location.top, color=color.red, size=size.small, text="DIV")
plotshape(bullDiv, "Bullish breadth divergence", style=shape.triangleup, location=location.bottom, color=color.green, size=size.small, text="DIV")
plotshape(thrustUp, "Breadth thrust up", style=shape.diamond, location=location.bottom, color=color.lime, size=size.tiny)
plotshape(thrustDn, "Breadth thrust down", style=shape.diamond, location=location.top, color=color.maroon, size=size.tiny)
plot(regime, "DMS regime (export: 1 broad / -1 narrow)", display=display.none)
plot(zRatio, "DMS z (export)", display=display.none)

var table t = table.new(position.top_right, 2, 8, bgcolor=color.new(color.black, 60))
table.cell(t, 0, 0, "BREADTH", text_color=color.white, text_size=size.small)
table.cell(t, 1, 0, dataOk ? regimeLabel : "NO DATA", bgcolor=color.new(regimeColor, 30), text_color=color.white, text_size=size.small)
table.cell(t, 0, 1, "Pair", text_color=color.white, text_size=size.small)
table.cell(t, 1, 1, ewSym + " / " + cwSym, text_color=color.gray, text_size=size.small)
table.cell(t, 0, 2, "Rel. momentum", text_color=color.white, text_size=size.small)
table.cell(t, 1, 2, str.tostring(ratioMomS, "#.##") + "% (" + str.tostring(momLen) + "b)", text_color=ratioMomS >= 0 ? color.lime : color.red, text_size=size.small)
table.cell(t, 0, 3, "Z-score", text_color=color.white, text_size=size.small)
table.cell(t, 1, 3, str.tostring(zRatio, "#.##"), text_color=math.abs(zRatio) > 2 ? color.orange : color.white, text_size=size.small)
table.cell(t, 0, 4, "Percentile", text_color=color.white, text_size=size.small)
table.cell(t, 1, 4, str.tostring(rankRatio, "#") + "%", text_color=regimeColor, text_size=size.small)
table.cell(t, 0, 5, "Ratio trend", text_color=color.white, text_size=size.small)
table.cell(t, 1, 5, breadthTrendUp ? "EW gaining" : "CW gaining", text_color=breadthTrendUp ? color.lime : color.red, text_size=size.small)
table.cell(t, 0, 6, "Signal", text_color=color.white, text_size=size.small)
table.cell(t, 1, 6, bearDiv ? "BEARISH DIV" : bullDiv ? "BULLISH DIV" : thrustUp ? "THRUST UP" : thrustDn ? "THRUST DOWN" : "-", text_color=bearDiv or thrustDn ? color.red : bullDiv or thrustUp ? color.lime : color.gray, text_size=size.small)
table.cell(t, 0, 7, "Read", text_color=color.white, text_size=size.small)
table.cell(t, 1, 7, regime == -1 ? "Rally fragile" : regime == 1 ? "Rally supported" : "Neutral", text_color=regimeColor, text_size=size.small)

// === ALERTAS ===
alertcondition(bearDiv, "DMS Bearish divergence", "DMS v2: index at highs while breadth deteriorates")
alertcondition(bullDiv, "DMS Bullish divergence", "DMS v2: index at lows while breadth improves")
alertcondition(thrustUp, "DMS Breadth thrust up", "DMS v2: equal-weight leading strongly")
alertcondition(thrustDn, "DMS Breadth thrust down", "DMS v2: equal-weight lagging strongly")
alertcondition(regime != regime[1], "DMS Regime change", "DMS v2: breadth regime changed")

Overview

DMS v2 Breadth Dispersion takes the log ratio of the two, then adds its momentum, a z-score, a percentile rank, divergences against the index price and a breadth thrust condition. It is a market panel that does not depend on the chart symbol and needs both symbols available. Lookback lengths and thresholds are inputs.

Details

Published by

AssetWhisper on GitHub

Draws

Separate pane below the chart

Markets

Indices, Stocks

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
Cap-weighted indexsymbolAMEX:SPYcwSym
Equal-weighted indexsymbolAMEX:RSPewSym
Ratio momentum (bars)int20momLen
Z-score lookbackint100zLen
Percentile lookbackint252rankLen
Divergence lookbackint20divLen
Breadth thrust (% relative)float2.0thrustTh
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

This indicator scans a pasted list of symbols for RSI directional momentum and shows matching long and short signals in a table in a separate pane. The user chooses continuous break, continuous retracement, flip break, flip retracement, divergence, or hidden d

Indicator v6 Oscillators & momentumDivergence
Updated 1 year ago · MPL-2.0 GitHub repository of Momentum Setup - RSI Directional Momentum Scanner
228 stars

This indicator calculates the Relative Strength Index (RSI) across four user-selected timeframes and plots the results in a separate pane. It identifies regular bullish and bearish divergences between price pivot points and the primary timeframe RSI value. Add

Indicator v6 Oscillators & momentumDivergence
Updated 3 months ago · None stated GitHub repository of Multi-Timeframe RSI with Divergence

Oscillator Suite

by TamaraKGreen
46 stars

Oscillator Suite plots a normalised price oscillator in a separate pane and overlays a signal line that can use SMA, EMA, WMA, HMA, RMA, VWMA, T3, ZEMA, KAMA, or GKEMA. It marks bullish and bearish divergences, a smoothed money-flow series, confluence areas an

Indicator v5 Oscillators & momentumDivergence
Updated 7 weeks ago · None stated GitHub repository of Oscillator Suite
11 stars

This indicator plots a smoothed Z-score of cumulative volume delta in a separate pane, showing whether buying or selling pressure is dominant and when the reading enters extreme zones. It marks spot accumulation, climax or exhaustion, and pivot-based price-vol

Indicator v6 Oscillators & momentumVolume Repaints
Updated 7 weeks ago · MIT GitHub repository of CVD Z-Score [NeuNue]
9 stars

This indicator plots a heuristic volume-balance oscillator in a separate pane. It estimates signed volume from the close location inside each bar, multiplies that by volume, and sums the proxy over a rolling window. The sum is scaled between minus one and plus

Indicator v6 VolumeOscillators & momentum
Updated 2 days ago · MIT GitHub repository of CVD Bias [WavesUnchained]

KARPUZLU-RSI

by Kalumur
4 stars

Calculates a custom-period Relative Strength Index alongside an Exponential Moving Average of the RSI in a separate pane. It identifies pivot highs and lows directly on the RSI plot to highlight trendlines and potential divergence patterns. The area between th

Indicator v5 Oscillators & momentumMoving averages
Updated 2 years ago · None stated GitHub repository of KARPUZLU-RSI

More Divergence scripts

Related on ForexR

Trade Your Charts With a Regulated Broker

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

Compare brokers