TradingView indicators

Disparity Index on TradingView: percentage distance from a moving average

Disparity Index measures 100 × (price − moving average) / moving average. With a positive average, +4 means price is 4% above it; −4 means 4% below. The Kairi Relative Index uses this same calculation when its price source and average match. The value measures distance, not the probability of a reversal.

Price 104 · SMA 100 → Disparity +4%

Hypothetical values. The three-bar example below shows exactly how the baseline is calculated, and why EMA or WMA gives a different answer.

Inspect and copy the Pine Script example

Deriving the percentage and checking the name

Start with a price P and moving average M on the same bar. P − M is a distance in price units. Dividing by M expresses that distance relative to the average; multiplying by 100 converts it to a percentage. Equivalently, the result is 100 × (P / M − 1). A ratio display of 100 × P / M would read 104 where this zero-centered version reads +4. Check which convention a script uses before comparing thresholds.

BiggWigg's published Disparity Index and the FXCM Kairi definition both use the percentage difference from a moving average. This supports covering the matching implementations together. It does not mean every community script with either name has the same smoothing, source or alert rules.

Disparity is not a Z-score: a Z-score divides deviation by a standard deviation, while disparity divides by the average. Price 104, mean 100 and standard deviation 2 give disparity +4% and Z-score +2. Neither the percentage alone nor its sign measures statistical significance. It also differs from a return, which compares price with an earlier price.

One price sequence, three different baselines

Assume three consecutive closes of 96, 100 and 104, a length of 3, and evaluation at the third close. For this isolated EMA example, initialize the first EMA at 96 and use α = 2 / (3 + 1) = 0.5. The EMA then moves to 98 and 101. An EMA with additional earlier history can differ from this short example.

Hypothetical third-bar calculations, rounded to four decimals
AverageBaseline calculationBaselineDisparity
SMA(3)(96 + 100 + 104) / 3100+4.0000%
EMA(3)0.5 × 104 + 0.5 × 98101+2.9703%
WMA(3)(1 × 96 + 2 × 100 + 3 × 104) / 6101.3333+2.6316%

Each percentage uses the full-precision baseline: for the SMA, 100 × (104 − 100) / 100 = 4. For the WMA, keep 608 / 6 until the final division. Changing the price source from close to hlc3 changes both the numerator and the average. Changing the timeframe changes which observations make up the window.

SMA weights all three closes equally. WMA assigns weights 1, 2 and 3 from oldest to newest. EMA retains earlier history through its recurrence. The example code waits for at least N chart bars for every option, but that waiting rule does not make EMA initialization identical to SMA initialization.

The same +5% can describe continuation or reversion

With price 105 and average 100, disparity is +5% in either context. If the average has risen from 98 to 100 and price continues making higher closes, +5% may describe an advancing trend. Selling merely because it is positive opposes that move. If the average stays near 100 while price oscillates around it, +5% may be a candidate for a mean-reversion rule. The indicator does not choose between those hypotheses.

A shrinking disparity need not mean a falling price. If price stays at 105 while the average rises from 100 to 102, disparity falls from +5% to about +2.9412%. The average has caught up. A declining oscillator alone therefore cannot establish a profitable short trade or a completed reversal.

Record the average slope and market context separately. Test a specific trigger, such as a confirmed crossing, with explicit exits and trading costs. The ±5% lines in the code are adjustable reference marks, not universal overbought or oversold levels. Percentage normalization removes price scale, not volatility: +5% on two instruments can have very different rarity.

Pine Script with explicit denominator and close rules

The default is close versus SMA(14). Select EMA or WMA to inspect a different baseline. The Data Window exposes the selected source and average for a manual calculation. The live line can move intrabar; markers and alerts wait for the chart bar to close. This is an indicator, with no strategy orders.

Pine Script v6
//@version=6
indicator("Disparity Index / Kairi: checked baseline", overlay=false, precision=4)

length = input.int(14, "Length in bars", minval=1, maxval=500)
source = input.source(close, "Source")
maType = input.string("SMA", "Moving average", options=["SMA", "EMA", "WMA"])
threshold = input.float(5.0, "Reference level (%)", minval=0.0)
sma = ta.sma(source, length)
ema = ta.ema(source, length)
wma = ta.wma(source, length)
base = maType == "SMA" ? sma : maType == "EMA" ? ema : wma
// Wait for at least length chart bars, including for the EMA option.
ready = bar_index >= length - 1 and not na(source) and not na(base) and base != 0
disparity = ready ? 100.0 * (source - base) / base : na

plot(disparity, "Disparity (%)", color=color.blue, linewidth=2, style=plot.style_linebr)
hline(0, "Zero", color=color.gray)
hline(threshold, "Upper reference", color=color.gray, linestyle=hline.style_dashed)
hline(-threshold, "Lower reference", color=color.gray, linestyle=hline.style_dashed)
plot(base, "Moving average baseline", display=display.data_window)
plot(source, "Selected source", display=display.data_window)

crossUp = ta.crossover(disparity, 0)
crossDown = ta.crossunder(disparity, 0)
positiveBases = base > 0 and base[1] > 0
confirmedUp = barstate.isconfirmed and positiveBases and crossUp
confirmedDown = barstate.isconfirmed and positiveBases and crossDown
plotshape(confirmedUp, "Confirmed cross up", shape.triangleup, location.bottom, color.green, size=size.tiny)
plotshape(confirmedDown, "Confirmed cross down", shape.triangledown, location.top, color.red, size=size.tiny)
alertcondition(confirmedUp, "Disparity above zero", "Disparity crossed above zero on a closed bar with positive baselines.")
alertcondition(confirmedDown, "Disparity below zero", "Disparity crossed below zero on a closed bar with positive baselines.")

Missing, zero and negative inputs

Missing source or average values produce na; the line leaves a gap. A zero average also returns na, since division by zero has no defined percentage. Do not substitute zero or an arbitrary small denominator: either would invent a reading. With source 1 and average 0.01, the valid arithmetic result is +9,900%, which shows why near-zero baselines need scrutiny.

With source −9 and average −10, the formula gives −10% even though −9 is numerically above −10. The example retains this arithmetic result but suppresses crossings unless the current and previous baselines are positive. For positive prices and length 1, all three averages equal the source, so disparity is zero. A missing-history gap is not a zero-line crossing.

Verify a value before creating an alert

  1. Paste the script into TradingView Pine Editor and add it to a standard candle chart. Set the source, average type and length.
  2. Inspect a closed bar in the Data Window. Compute 100 × (selected source − baseline) / baseline and compare after rounding.
  3. When matching another script, also match symbol, exchange feed, timeframe, session, adjustments and loaded history. Synthetic candle prices can differ from standard closes.
  4. Create an alert for the chosen zero-cross condition and select Once Per Bar Close. Recreate the alert after changing settings if the saved alert must use those changes.

A successful syntax check does not verify chart-data equivalence or trading performance. Compare actual TradingView values before using the output in a trading rule.

Turn the checked definition into your own script

Pineify's Pine Script AI Coding Agent accepts a written specification for generating or editing Pine Script. Include the formula, source, average type, initialization, denominator guard and bar-close condition in the request. Review the output and compare its values in TradingView before adding alerts.

Build a Disparity Index using close and SMA(14). Return na when the average is missing or zero. Expose the baseline in the Data Window. Alert only on confirmed zero crossings with positive current and previous baselines. Keep the live line visible and do not create strategy orders.
Open Pine Script AI Coding Agent

Educational calculations only. Indicator readings do not establish expected returns or provide investment advice.

Disparity Index and Kairi questions

They use the same percentage-distance calculation when the source, moving average, length and initialization match. This page uses a close-based SMA as its Kairi baseline and offers EMA and WMA alternatives. A script name alone does not establish identical values; inspect its settings and formula.

With a positive moving average, +5 means the selected price is 5% above that average. A price of 105 and average of 100 produce +5. It is not a 5% return over the lookback, a probability of reversal or a volatility-adjusted score.

A positive reading only establishes price above a positive baseline. A rising average can accompany trend continuation; a flat average may motivate a mean-reversion hypothesis. Neither interpretation supplies an entry by itself. Define the market filter, trigger, exit and costs before testing a trading rule.

Use the moving average required by the rule you intend to reproduce. SMA gives equal weight to its window, EMA uses recursive weighting, and WMA gives larger linear weights to recent bars. Their baselines can differ at the same length, so their percentage readings and thresholds are not interchangeable.

The percentage is undefined, so this example returns na and leaves a plot gap. Missing source or baseline values also produce na. A near-zero baseline can produce a very large result; a negative baseline reverses the usual above/below sign interpretation. The example suppresses crossing alerts unless both adjacent baselines are positive.

Yes. The live source and moving average update during the current candle, so a crossing can disappear before close. The example line updates live, but its markers and alert conditions require barstate.isconfirmed. Create an alert for the desired condition and choose Once Per Bar Close.

Sources and related definitions