TradingView indicator guides

Volatility oscillator · Pine Script v6

Relative Volatility Index: formula and Pine Script

The Relative Volatility Index assigns rolling price standard deviation to directional branches, smooths them, and expresses the upper share on a 0-to-100 scale. This guide implements a close/EMA version with explicit initialization and a worked calculation. It is different from the Relative Vigor Index, which also uses the abbreviation RVI.

Choose the RVI version before comparing values

Donald Dorsey developed the Relative Volatility Index to describe volatility direction. The TradingView help article describes a high/low standard deviation formulation. The code here uses the close/EMA formulation found in the Pineify RVOI implementation; it is a defined teaching example, not a claim of exact parity with every built-in or community script.

Its two lengths do different jobs: 10 closes form each standard deviation window, while a 14-period EMA smooths each directional input. This is standard deviation of price levels. It is not standard deviation of returns, nor a separate standard deviation calculated only from up bars.

Version contract: close source, population standard deviation, EMA smoothing, unchanged closes assigned to the lower branch, first-valid-input seeds, zero denominator returning na, and zero plot offset.

Formula, smoothing, and boundary conditions

σ = sqrt(sum((close − mean(close, n))²) / n)

u = close > close[1] ? σ : 0

d = close > close[1] ? 0 : σ

α = 2 / (m + 1)

U = α × u + (1 − α) × U[1]

D = α × d + (1 − α) × D[1]

RVI = 100 × U / (U + D)

The EMA is a decaying accumulation of directional inputs, not a fixed rolling sum. The code seeds U and D with their first valid inputs, including zero. Both stay uninitialized until σ and the previous close are available. Invalid current inputs leave the stored EMA state unchanged and produce no RVI point.

When U + D is zero, the ratio is undefined. The script plots a gap instead of inventing a neutral 50. A constant series from the start stays undefined; one flat bar after changing prices may have positive σ and therefore still affect the lower branch. Returning 50 or sending flat bars to neither branch would be different, legitimate conventions that must be documented.

For nonnegative U and D with a positive total, RVI is bounded by 0 and 100. At 50 the components are equal. At 80, U = 4D. These are algebraic statements about the formula, not probabilities or estimates of future returns.

Worked example: a flat close still contributes

Demonstration only: closes are 100, 102, 101, 101, 103, 102. Set n = 3 and m = 3, so α = 0.5. Bars 1 and 2 are warmup. Values below are rounded to six decimals; calculations retain full precision.

Synthetic prices, no market or backtest results
BarCloseσInput branchUDRVI
31010.816497Lower00.8164970.000000
41010.471405Lower (flat)00.6439510.000000
51030.942809Upper0.4714050.32197559.417258
61020.816497Lower0.2357020.56923629.282032

At bar 3, mean(100, 102, 101) = 101, so σ = sqrt(2/3). The down close seeds U = 0 and D = σ. At bar 5, U = 0.5 × 0.942809 = 0.471405 and D = 0.5 × 0.643951 = 0.321975. Their ratio gives 59.417258. Bar 6 crosses back below 50 despite having the same σ as bar 3, because EMA history changes the ratio.

Copyable Pine Script with confirmed crossings

This indicator preserves the close/EMA calculation and makes the initial state explicit. It exposes U and D in the Data Window so you can check the intermediate values. It does not submit trades.

Pine Script v6
//@version=6
indicator("Relative Volatility Index: close / EMA example", overlay = false)

stdLength = input.int(10, "Close standard deviation length", minval = 2)
emaLength = input.int(14, "Directional EMA length", minval = 1)

sigma = ta.stdev(close, stdLength, true)
delta = ta.change(close)
ready = not na(sigma) and not na(delta)
// This variant assigns unchanged closes to the lower branch.
upInput = ready ? (delta > 0 ? sigma : 0.0) : na
downInput = ready ? (delta > 0 ? 0.0 : sigma) : na

// Explicit EMA seed: first valid directional input, including zero.
alpha = 2.0 / (emaLength + 1.0)
var float upper = na
var float lower = na
if ready
    upper := na(upper) ? upInput : alpha * upInput + (1.0 - alpha) * upper
    lower := na(lower) ? downInput : alpha * downInput + (1.0 - alpha) * lower

total = upper + lower
rvi = ready and not na(total) and total > 0 ? 100.0 * upper / total : na
plot(rvi, "RVI", color = color.purple, linewidth = 2, style = plot.style_linebr)
plot(upper, "Upper EMA", display = display.data_window)
plot(lower, "Lower EMA", display = display.data_window)
hline(80, "80 reference", color = color.gray)
hline(50, "Equal components", color = color.gray)
hline(20, "20 reference", color = color.gray)

crossUp = ta.crossover(rvi, 50)
crossDown = ta.crossunder(rvi, 50)
confirmedUp = crossUp and barstate.isconfirmed
confirmedDown = crossDown and barstate.isconfirmed
plotshape(confirmedUp, "Confirmed above 50", shape.triangleup, location.bottom, color.blue, size = size.tiny)
plotshape(confirmedDown, "Confirmed below 50", shape.triangledown, location.top, color.orange, size = size.tiny)
alertcondition(confirmedUp, "RVI above 50", "Relative Volatility Index crossed above 50 on a closed bar.")
alertcondition(confirmedDown, "RVI below 50", "Relative Volatility Index crossed below 50 on a closed bar.")

The purple line can move on an open bar. Blue and orange markers require a completed cross above or below 50 and bar confirmation. Create an alert from the corresponding condition after adding the script to your chart. This script makes no higher-timeframe requests.

Parameters and a repeatable TradingView check

SettingExample defaultWhat changes
Standard deviation length10, minimum 2The number of closes used to estimate price dispersion.
Directional EMA length14, minimum 1The decay factor of both components; m = 14 gives α = 2/15.
Reference levels20, 50, 80Only 50 drives the example alerts. 20 and 80 are display references.
  1. Paste the script into a new Pine Editor indicator, save it, and add it to a standard candlestick chart.
  2. Hold symbol, data feed, session, timeframe, and price adjustments fixed. Compare closed bars in the Data Window.
  3. Match price source, both lengths, smoothing type, flat-bar handling, and initialization before comparing another RVI.
  4. Check early history and a later interval separately. A different seed can cause a temporary mismatch even when subsequent formulas agree.
  5. Check a flat-price interval and an open bar. A missing ratio and a changing current value are expected under the stated rules.

Read the ratio without confusing it with trade performance

Above 50 means the upper EMA exceeds the lower EMA. It does not prove that absolute volatility is rising: multiplying both components by the same positive factor leaves RVI unchanged. ATR or the unnormalized standard deviation answers a different question about scale.

A crossing can be a condition to test, but it leaves position size, execution timing, costs, and exits unspecified. For a research specification, one possible rule is to evaluate an upward 50 cross only on a closed bar with close above its 200-bar EMA, then define the next-bar entry, a price-based stop, and a downward-cross exit separately. Those are proposed rules, not results from this example.

Repeated crossings around 50 can create frequent trades in a range. Divergence is also insufficient by itself: the oscillator can weaken while price continues rising. A high RVI does not set a stop distance, and 80 does not mean an 80% chance of a profitable trade. Educational calculation only, not investment advice.

Relative Volatility Index vs. ATR and Relative Vigor Index

IndicatorInput and calculationReadout
Relative Volatility IndexDirectional standard deviation components, smoothed and divided0 to 100 when defined; relative directional allocation
ATRSmoothed maximum of high-low and distances from the previous closeNonnegative price units; no directional sign
Relative Vigor IndexSmoothed close-open compared with smoothed high-lowZero-centered ratio; candle body relative to range
RSISmoothed upward and downward price changes0 to 100; changes rather than price dispersion

Keep the full indicator name in saved scripts and comparison notes. An RVI midpoint of 50 belongs to the volatility formulation here; applying it to Relative Vigor Index would use the wrong scale.

Turn a defined RVI variant into a script with Pineify

Give the Pineify Pine Script AI Coding Agent the calculation contract before asking for alerts or strategy rules. A concrete prompt is: "Use close-price population standard deviation over 10 bars, smooth directional inputs with a 14-period EMA seeded at the first valid input, assign flat closes to the lower branch, return na on a zero total, and confirm 50-level alerts at bar close."

Review the generated source and compare intermediate values bar by bar. If you request a strategy next, specify exits, sizing, fees, and slippage independently. A successful syntax check establishes that the code compiles; it does not establish useful trading performance.

Open Pine Script AI Coding Agent

Relative Volatility Index FAQ

Relative Volatility Index compares smoothed standard deviation contributions assigned by price direction. In this close/EMA example, an up close sends the whole rolling standard deviation to the upper branch; a down or unchanged close sends it to the lower branch. RVI is the upper component as a percentage of their total. It does not measure buying volume or the probability of a price rise.

The acronym is shared by two different indicators. Relative Volatility Index uses standard deviation and a 0-to-100 scale. Relative Vigor Index compares smoothed close-minus-open values with high-minus-low ranges and is centered on zero. Search for the full name before comparing formulas, settings, or signal lines.

Check the price source, standard deviation window, EMA versus Wilder smoothing, initialization, and treatment of unchanged closes. Some versions use separate high and low calculations. This example uses close prices, explicit EMA seeds, and assigns flat closes to the lower branch. A shared indicator name does not establish numerical equivalence.

This example sends its rolling standard deviation to the lower branch when close equals the previous close. Standard deviation can remain positive because earlier prices in the window differ. A version that puts zero in both branches will produce different results. For example, bar 4 in the demonstration has an unchanged close of 101 and a nonzero standard deviation of 0.471405.

There is no verified universal best setting. This example starts with a 10-bar standard deviation window and 14-bar directional EMA, matching the base lengths in the Pineify RVOI configuration. Compare candidate lengths on the same symbol, session, chart type, and timeframe. Keep evaluation data separate from parameter selection and include trading costs if you turn the indicator into a strategy.

No. With a positive total, 80 means the upper smoothed component is four times the lower component in this calculation. It does not establish that price must reverse, or that volatility is high in price units. The 20 and 80 lines are visual references; they do not place orders or define a tested trading system.

The script waits for enough close prices to calculate standard deviation and a valid previous close. It also returns na when both smoothed components sum to zero. The first valid directional inputs seed both EMAs. A finite first reading can still be sensitive to the starting history, so compare later closed bars as well as the initialization window.

Yes. The current close, standard deviation, and directional branch can change during the open bar. The plotted line updates with those inputs. This example only marks crossings and enables its alert conditions at bar confirmation on the chart timeframe. That restriction does not make a developing value fixed or specify confirmation for another timeframe.