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:
- 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`
- 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`.
- 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)`
- 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")
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).
- Bullish Confirmation: When price is in an uptrend, and RVI is consistently above 100 and preferably rising. This indicates that upward price movements (and their ranges) are more significant than downward ones.
- Bearish Confirmation: When price is in a downtrend, and RVI is consistently below 100 and preferably falling. This indicates that downward price movements are more significant than upward ones.
//@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.
- Bullish Reversal Signal: RVI crosses above 100, suggesting that upward volatility is beginning to dominate after a period of downward volatility dominance.
- Bearish Reversal Signal: RVI crosses below 100, suggesting that downward volatility is beginning to dominate after a period of upward volatility dominance.
//@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.
- Bullish Divergence: Price makes a lower low, but RVI makes a higher low (or fails to make a significantly lower low). This suggests that downside volatility is diminishing, even as price declines, hinting at a potential upward reversal.
- Bearish Divergence: Price makes a higher high, but RVI makes a lower high (or fails to make a significantly higher high). This suggests that upward volatility is diminishing, even as price rises, hinting at a potential downward 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:
- Parameter Tuning: The `length` parameter (commonly 14) influences the responsiveness of RVI. Shorter lengths will make it more sensitive to recent volatility shifts, potentially leading to more signals and noise. Longer lengths will smooth the indicator, providing a broader view of volatility dominance but with more lag. Experiment to find optimal settings for your asset and timeframe.
- Contextual Interpretation: RVI values are relative. What constitutes a "strong bullish bias" (e.g., RVI > 150 or 200) or "strong bearish bias" (e.g., RVI < 50) will vary significantly between different assets or market conditions. Analyze historical RVI ranges for your specific asset.
- Combine with Price Action: RVI is a volatility-based momentum indicator. Always confirm RVI signals with actual price action, such as candlestick patterns, breaks of support/resistance, or chart patterns, for higher conviction trades.
- Filter with Trend Indicators: To reduce false signals, especially around the 100-level, combine RVI with a separate trend-following indicator (e.g., a long-term moving average, ADX). For instance, only take bullish RVI signals in an established uptrend.
- Divergence Reliability: RVI divergence can be a powerful signal, especially for identifying trend exhaustion. These signals are often more reliable than simple crossovers.
Common Relative Volatility Index (RVI) Pitfalls
- Not a Direct Buy/Sell Signal: RVI primarily measures *relative volatility strength*, not necessarily an immediate buy/sell signal on its own. It's a contextual indicator.
- Lag: As it uses moving averages, RVI is a lagging indicator and will not perfectly pinpoint exact tops or bottoms.
- False Signals in Sideways Markets: In very tight ranges or choppy markets, RVI can fluctuate around the 100-level, generating ambiguous or false signals. It performs best in trending environments where there's a clear bias in volatility.
- Division by Zero: If `avgDownTr` is zero (meaning no down days in the lookback period, which is rare but possible in strong uptrends on very short timeframes), it can cause a division by zero error. The provided Pine Script code includes a check for this.
- Confusion with Relative Vigor Index: Be mindful that "RVI" can refer to two different indicators. Ensure you are using the correct calculation and interpretation.
- Not a Standalone Indicator: RVI should always be used as part of a comprehensive trading system, complementing other indicators and price action analysis.
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.