Pine Script Relative Volatility Index (RVI)

Master this unique volatility indicator in TradingView's Pine Script that measures the relative strength of upward price volatility against downward price volatility to assess trend health and potential reversals.

Last Updated on: Expertise: Advanced

What is the Relative Volatility Index (RVI)?

The Relative Volatility Index (RVI) is a technical indicator that quantifies the relative strength of upward price volatility versus downward price volatility over a specific period. It is distinct from the more commonly known Relative Vigor Index (also abbreviated RVI) and aims to show whether volatility during upward price moves is stronger than volatility during downward price moves, or vice-versa. This can provide insights into the underlying conviction of a trend and potential turning points.

RVI is an unbounded ratio, typically calculated by summing the True Range (TR) on "up" days and "down" days separately, and then taking a ratio of their smoothed values. A high RVI value suggests that upward volatility is dominant, indicating a healthy uptrend or potential for reversal upwards. A low RVI value indicates that downward volatility is dominant, suggesting a healthy downtrend or potential for reversal downwards.

In Pine Script, the Relative Volatility Index can be a valuable tool for advanced traders looking for nuanced signals regarding market strength and weakness beyond just price direction.

Components and Calculation

The calculation of the Relative Volatility Index (RVI) involves the following steps:

  1. True Range (TR): For each period, calculate the True Range, which is the greatest of:
    • `Current High - Current Low`
    • `Absolute value of Current High - Previous Close`
    • `Absolute value of Current Low - Previous Close`
    `TR = ta.tr`
  2. Up Day / Down Day True Range:
    • `Up TR Sum = TR` if `Current Close > Previous Close`, else `0`.
    • `Down TR Sum = TR` if `Current Close < Previous Close`, else `0`.
  3. Smoothed Up / Down True Range: Calculate a Simple Moving Average (SMA) or other smoothing average of the `Up TR Sum` and `Down TR Sum` over a specified `length` (e.g., 14 periods).
    • `Avg Up TR = SMA(Up TR Sum, length)`
    • `Avg Down TR = SMA(Down TR Sum, length)`
  4. RVI Formula: The ratio of `Avg Up TR` to `Avg Down TR`, often multiplied by 100 for scaling.
    `RVI = (Avg Up TR / Avg Down TR) * 100` (ensure `Avg Down TR` is not zero to prevent division by zero errors).

A common `length` for RVI is 14 periods.

Basic Relative Volatility Index (RVI) Implementation in Pine Script

Pine Script v5 does not have a direct built-in function for the Relative Volatility Index (RVI), so we will implement it manually using `ta.tr` and `ta.sma`.

//@version=5
indicator("My Relative Volatility Index (RVI)", overlay=false) // overlay=false to plot in a separate pane

// Input for RVI length
length = input.int(14, title="RVI Length", minval=1)

// Calculate True Range (TR)
tr = ta.tr

// Determine if it's an 'Up Day' or 'Down Day' based on close vs previous close
// Use a small epsilon to avoid false signals on exact same close prices
isUpDay = close > close[1]
isDownDay = close < close[1]

// Accumulate True Range for Up Days and Down Days separately
// If it's not an up/down day, the value is 0.0
upTrValue = isUpDay ? tr : 0.0
downTrValue = isDownDay ? tr : 0.0

// Smooth the accumulated True Ranges using a Simple Moving Average (SMA)
avgUpTr = ta.sma(upTrValue, length)
avgDownTr = ta.sma(downTrValue, length)

// Calculate Relative Volatility Index
// Add a small epsilon to the denominator to prevent division by zero,
// which can happen if there are no down days in the lookback period.
rviValue = avgDownTr != 0 ? (avgUpTr / avgDownTr) * 100 : 0.0

// Plot the RVI line
plot(rviValue, title="Relative Volatility Index", color=color.blue, linewidth=2)

// Optional: Add reference levels. These are subjective and depend on the asset.
// 100 means equal upward and downward volatility.
// Values > 100 mean upward volatility is dominant.
// Values < 100 mean downward volatility is dominant.
hline(100, "Equilibrium (100)", color.gray, linestyle=hline.style_dotted)
hline(150, "Bullish Bias Ref (150)", color.green, linestyle=hline.style_dashed)
hline(50, "Bearish Bias Ref (50)", color.red, linestyle=hline.style_dashed)

// Highlight background zones for visual clarity
bgcolor(rviValue > 150 ? color.new(color.green, 90) : na, title="Strong Bullish Volatility")
bgcolor(rviValue < 50 ? color.new(color.red, 90) : na, title="Strong Bearish Volatility")
Volatility Ratio: RVI helps assess which side (buyers or sellers) is generating more volatility, giving insight into underlying market conviction.

Practical RVI Trading Strategies

1. Trend Confirmation and Strength

RVI can be used to confirm the strength of an existing trend. In a healthy uptrend, upward volatility should dominate (RVI > 100 and rising). In a healthy downtrend, downward volatility should dominate (RVI < 100 and falling).

//@version=5
strategy("RVI Trend Confirmation Strategy", overlay=true)

length = input.int(14, title="RVI Length", minval=1)
rviBullishThreshold = input.float(150, title="RVI Bullish Threshold", minval=100)
rviBearishThreshold = input.float(50, title="RVI Bearish Threshold", maxval=100)

tr = ta.tr
isUpDay = close > close[1]
isDownDay = close < close[1]
upTrValue = isUpDay ? tr : 0.0
downTrValue = isDownDay ? tr : 0.0
avgUpTr = ta.sma(upTrValue, length)
avgDownTr = ta.sma(downTrValue, length)
rviValue = avgDownTr != 0 ? (avgUpTr / avgDownTr) * 100 : 0.0

plot(rviValue, "RVI", color.blue, display=display.pane_only)
hline(100, "Equilibrium", color.gray, linestyle=hline.style_dotted, display=display.pane_only)
hline(rviBullishThreshold, "Bullish Threshold", color.green, linestyle=hline.style_dashed, display=display.pane_only)
hline(rviBearishThreshold, "Bearish Threshold", color.red, linestyle=hline.style_dashed, display=display.pane_only)

// Simple trend filter (e.g., using a long-term EMA)
trendEMA = ta.ema(close, 50)
isUptrend = close > trendEMA
isDowntrend = close < trendEMA

// Long Entry: Uptrend confirmed by price and RVI showing strong upward volatility bias
longCondition = isUptrend and rviValue > rviBullishThreshold and rviValue > rviValue[1]

// Short Entry: Downtrend confirmed by price and RVI showing strong downward volatility bias
shortCondition = isDowntrend and rviValue < rviBearishThreshold and rviValue < rviValue[1]

if (longCondition)
    strategy.entry("Long Confirmed", strategy.long)

if (shortCondition)
    strategy.entry("Short Confirmed", strategy.short)

// Basic exit: trend reversal or RVI weakening
strategy.close("Long Confirmed", when=close < trendEMA or rviValue < 100)
strategy.close("Short Confirmed", when=close > trendEMA or rviValue > 100)

2. Trend Reversal Signals (Zero/Equilibrium Line Crossovers)

A crossover of the 100-level (the equilibrium point) can signal a shift in the dominant volatility, potentially indicating a trend reversal or a pause in the current trend.

//@version=5
strategy("RVI Reversal Strategy", overlay=true)

length = input.int(14, title="RVI Length", minval=1)

tr = ta.tr
isUpDay = close > close[1]
isDownDay = close < close[1]
upTrValue = isUpDay ? tr : 0.0
downTrValue = isDownDay ? tr : 0.0
avgUpTr = ta.sma(upTrValue, length)
avgDownTr = ta.sma(downTrValue, length)
rviValue = avgDownTr != 0 ? (avgUpTr / avgDownTr) * 100 : 0.0

plot(rviValue, "RVI", color.blue, display=display.pane_only)
hline(100, "Equilibrium (100)", color.gray, linestyle=hline.style_dotted, display=display.pane_only)

// Conditions for entries based on 100-level crossover
longSignal = ta.crossover(rviValue, 100)
shortSignal = ta.crossunder(rviValue, 100)

if (longSignal)
    strategy.entry("Long RVI Cross", strategy.long)

if (shortSignal)
    strategy.entry("Short RVI Cross", strategy.short)

3. Divergence with Price

Divergence between price and RVI can be a strong indication of weakening underlying conviction in the current trend, potentially leading to a reversal.

//@version=5
indicator("RVI Divergence Scanner", overlay=true)

length = input.int(14, title="RVI Length", minval=1)

tr = ta.tr
isUpDay = close > close[1]
isDownDay = close < close[1]
upTrValue = isUpDay ? tr : 0.0
downTrValue = isDownDay ? tr : 0.0
avgUpTr = ta.sma(upTrValue, length)
avgDownTr = ta.sma(downTrValue, length)
rviValue = avgDownTr != 0 ? (avgUpTr / avgDownTr) * 100 : 0.0

plot(rviValue, "Relative Volatility Index", color.blue)
hline(100, "Equilibrium (100)", color.gray, linestyle=hline.style_dotted)

// Simple divergence detection (conceptual, robust detection requires advanced pivot logic)
// This is a simplified example focusing on price vs RVI divergence.

// Bullish Divergence (Price lower low, RVI higher low or less negative)
bullishDivergence = close[2] > close[1] and close[1] > close and rviValue[2] < rviValue[1] and rviValue[1] < rviValue

// Bearish Divergence (Price higher high, RVI lower high or less positive)
bearishDivergence = close[2] < close[1] and close[1] < close and rviValue[2] > rviValue[1] and rviValue[1] > rviValue

plotshape(bullishDivergence, title="Bullish Divergence", location=location.belowbar, color=color.green, style=shape.triangleup, size=size.small)
plotshape(bearishDivergence, title="Bearish Divergence", location=location.abovebar, color=color.red, style=shape.triangledown, size=size.small)

alertcondition(bullishDivergence, "Bullish RVI Divergence", "Potential bullish reversal based on RVI divergence.")
alertcondition(bearishDivergence, "Bearish RVI Divergence", "Potential bearish reversal based on RVI divergence.")

Optimizing Relative Volatility Index (RVI) Performance

To get the most from the Relative Volatility Index in Pine Script:

Beyond Price-Only: RVI adds a unique dimension to momentum analysis by incorporating volatility into the calculation, offering a different perspective than traditional momentum oscillators.

Common Relative Volatility Index (RVI) Pitfalls

Conclusion

The Relative Volatility Index (RVI) is an advanced and insightful technical indicator in Pine Script for TradingView. By quantifying the dominance of upward versus downward price volatility, it provides a unique perspective on underlying market conviction and trend health. Whether used for confirming the strength of a trend, identifying potential shifts around the 100-level, or spotting powerful reversals through divergence, RVI adds a valuable layer to your technical analysis. By understanding its calculation, thoughtfully tuning its parameters, and integrating it strategically with directional indicators and robust price action analysis, you can leverage the RVI to enhance your trading decisions and gain a deeper understanding of the market's dynamic forces.