What is Volume Rate of Change (Volume ROC)?
Volume Rate of Change (Volume ROC) is a momentum oscillator that measures the percentage change in trading volume over a specified number of periods. Unlike indicators that calculate the rate of change of price, Volume ROC specifically focuses on volume momentum, indicating whether volume is increasing or decreasing relative to its past levels.
The core idea behind Volume ROC is that volume often precedes price, and changes in volume can provide early signals of shifts in market interest and trend strength. A positive Volume ROC indicates that current volume is higher than the volume `N` periods ago, suggesting increasing participation. A negative Volume ROC indicates current volume is lower, suggesting decreasing participation.
Volume ROC is primarily used to:
- Confirm price trends: Rising Volume ROC supports the current price trend, while falling Volume ROC suggests a lack of conviction.
- Spot breakouts: A significant surge in Volume ROC often accompanies valid price breakouts.
- Identify divergences: When price makes new highs/lows but Volume ROC does not, it can signal a weakening trend and potential reversal.
In Pine Script, Volume ROC provides a clear way to quantify volume surges and contractions, adding another layer of analysis to trend and momentum strategies.
Components and Calculation
The calculation of Volume Rate of Change is straightforward:
- Volume refers to the current bar's trading volume.
- Previous Volume refers to the trading volume from `length` periods ago.
- Volume ROC Formula:
`Volume ROC = ((Current Volume - Volume[length]) / Volume[length]) * 100`
* Handle `Volume[length] == 0` to avoid division by zero.
A common `length` for Volume ROC is 14 periods, but this can be adjusted.
Basic Volume Rate of Change (Volume ROC) Implementation in Pine Script
Pine Script v5 provides a built-in function `ta.roc()` that can be applied to `volume` to calculate Volume ROC.
//@version=5
indicator("My Volume Rate of Change (Volume ROC)", overlay=false, format=format.percent) // overlay=false to plot in a separate pane
// Input for Volume ROC length
length = input.int(14, title="Volume ROC Length", minval=1)
// Calculate Volume ROC using ta.roc applied to volume
// Add a check to prevent division by zero if volume[length] is 0
volumeRocValue = volume[length] != 0 ? ta.roc(volume, length) : 0.0
// Plot the Volume ROC line
plot(volumeRocValue, title="Volume ROC", color=color.blue, linewidth=2)
// Plot the Zero Line as a key reference point
hline(0, "Zero Line", color=color.gray, linestyle=hline.style_dotted)
// Optional: Add reference levels for visual clarity, e.g., +50% and -50%
// These are subjective and depend on the asset and typical Volume ROC values.
hline(50, "Upper Ref (+50%)", color=color.green, linestyle=hline.style_dashed)
hline(-50, "Lower Ref (-50%)", color=color.red, linestyle=hline.style_dashed)
// Highlight areas where Volume ROC is significantly high (volume surge)
bgcolor(volumeRocValue > 50 ? color.new(color.lime, 90) : na, title="High Volume ROC")
Practical Volume ROC Trading Strategies
1. Trend Confirmation
Volume ROC is excellent for confirming the conviction behind a price trend. Ideally, price and Volume ROC should move in the same direction.
- Uptrend Confirmation: Price is in an uptrend, and Volume ROC is consistently positive (or making higher lows). This indicates that the uptrend is supported by increasing buying interest.
- Downtrend Confirmation: Price is in a downtrend, and Volume ROC is consistently negative (or making lower highs). This indicates that the downtrend is supported by increasing selling interest.
- Lack of Confirmation: If price is trending but Volume ROC is flat or moving in the opposite direction, it suggests the trend lacks underlying conviction and may be vulnerable.
//@version=5
strategy("Volume ROC Trend Confirmation", overlay=true)
length = input.int(14, title="Volume ROC Length", minval=1)
volumeRocValue = volume[length] != 0 ? ta.roc(volume, length) : 0.0
plot(volumeRocValue, "Volume ROC", color=color.blue, display=display.pane_only)
hline(0, "Zero Line", color=color.gray, linestyle=hline.style_dotted, display=display.pane_only)
// Price trend filter (e.g., using a long-term EMA)
priceMALength = input.int(50, title="Price MA Length", minval=1)
priceMA = ta.ema(close, priceMALength)
// Conditions for trend confirmation
// Long: Price above MA, and Volume ROC is positive and rising
longConfirm = close > priceMA and volumeRocValue > 0 and volumeRocValue > volumeRocValue[1]
// Short: Price below MA, and Volume ROC is negative and falling
shortConfirm = close < priceMA and volumeRocValue < 0 and volumeRocValue < volumeRocValue[1]
if (longConfirm)
strategy.entry("Long Confirm", strategy.long)
if (shortConfirm)
strategy.entry("Short Confirm", strategy.short)
// Basic exit: Price crosses back over price MA or Volume ROC weakens
strategy.close("Long Confirm", when=close < priceMA or volumeRocValue < 0)
strategy.close("Short Confirm", when=close > priceMA or volumeRocValue > 0)
2. Breakout Confirmation
A sudden surge in Volume ROC often provides strong confirmation for a price breakout. When price breaks out of a consolidation or a significant support/resistance level, a corresponding sharp increase in Volume ROC suggests the move has strong institutional backing.
- Bullish Breakout Confirmation: Price breaks above resistance, and Volume ROC simultaneously surges to high positive levels (e.g., above 50% or 100%).
- Bearish Breakout Confirmation: Price breaks below support, and Volume ROC simultaneously drops to significant negative levels (e.g., below -50% or -100%).
//@version=5
strategy("Volume ROC Breakout Confirmation", overlay=true)
length = input.int(14, title="Volume ROC Length", minval=1)
volumeRocValue = volume[length] != 0 ? ta.roc(volume, length) : 0.0
plot(volumeRocValue, "Volume ROC", color=color.blue, display=display.pane_only)
hline(0, "Zero Line", color=color.gray, linestyle=hline.style_dotted, display=display.pane_only)
bullishRocThreshold = input.float(75, title="Bullish ROC Threshold (%)", minval=10, step=5)
bearishRocThreshold = input.float(-75, title="Bearish ROC Threshold (%)", maxval=-10, step=5)
hline(bullishRocThreshold, "Bullish Threshold", color=color.green, linestyle=hline.style_dashed, display=display.pane_only)
hline(bearishRocThreshold, "Bearish Threshold", color=color.red, linestyle=hline.style_dashed, display=display.pane_only)
// Price breakout conditions (simplified, use proper S/R or channel breaks in real strategy)
// Here, we'll use a simple highest/lowest price breakout for demonstration
priceLookback = input.int(20, title="Price Breakout Lookback", minval=5)
isBullishPriceBreakout = close > ta.highest(high, priceLookback)[1]
isBearishPriceBreakout = close < ta.lowest(low, priceLookback)[1]
// Combined conditions for confirmed breakout
longBreakoutConfirmed = isBullishPriceBreakout and volumeRocValue > bullishRocThreshold
shortBreakoutConfirmed = isBearishPriceBreakout and volumeRocValue < bearishRocThreshold
if (longBreakoutConfirmed)
strategy.entry("Long Breakout", strategy.long)
if (shortBreakoutConfirmed)
strategy.entry("Short Breakout", strategy.short)
// Basic exit: trend reversal or fixed percentage
strategy.exit("Long Breakout Exit", from_entry="Long Breakout", profit=close*0.03, loss=close*0.015)
strategy.exit("Short Breakout Exit", from_entry="Short Breakout", profit=close*0.03, loss=close*0.015)
3. Divergence (Key Reversal Signal)
Divergence between price and Volume ROC suggests that the underlying volume momentum is not supporting the current price trend, often preceding a reversal.
- Bullish Divergence: Price makes a lower low, but Volume ROC makes a higher low (or fails to make a significantly lower low). This implies selling exhaustion, hinting at a potential upward reversal.
- Bearish Divergence: Price makes a higher high, but Volume ROC makes a lower high (or fails to make a significantly higher high). This implies buying exhaustion, hinting at a potential downward reversal.
//@version=5
strategy("Volume ROC Divergence", overlay=true)
length = input.int(14, title="Volume ROC Length", minval=1)
volumeRocValue = volume[length] != 0 ? ta.roc(volume, length) : 0.0
plot(volumeRocValue, "Volume ROC", color=color.blue, display=display.pane_only)
hline(0, "Zero Line", color=color.gray, linestyle=hline.style_dotted, display=display.pane_only)
// Simple divergence detection (conceptual, robust detection requires advanced pivot logic)
// This example looks for recent higher/lower swings in price and Volume ROC.
// Bullish Divergence: Price lower low, Volume ROC higher low
bullishDiv = close < close[1] and close[1] < close[2] and volumeRocValue > volumeRocValue[1] and volumeRocValue[1] > volumeRocValue[2]
// Bearish Divergence: Price higher high, Volume ROC lower high
bearishDiv = close > close[1] and close[1] > close[2] and volumeRocValue < volumeRocValue[1] and volumeRocValue[1] < volumeRocValue[2]
// Plot shapes on the chart to indicate divergence
plotshape(bullishDiv, title="Bullish Vol ROC Divergence", location=location.belowbar, color=color.green, style=shape.triangleup, size=size.small)
plotshape(bearishDiv, title="Bearish Vol ROC Divergence", location=location.abovebar, color=color.red, style=shape.triangledown, size=size.small)
if (bullishDiv)
strategy.entry("Long Divergence", strategy.long)
if (bearishDiv)
strategy.entry("Short Divergence", strategy.short)
// Basic exit after a few bars or on opposite signal
strategy.exit("Long Divergence Exit", from_entry="Long Divergence", profit=close*0.02, loss=close*0.01)
strategy.exit("Short Divergence Exit", from_entry="Short Divergence", profit=close*0.02, loss=close*0.01)
Optimizing Volume Rate of Change (Volume ROC) Performance
To get the most from Volume Rate of Change in Pine Script:
- Focus on Divergence: Like other ROC indicators, Volume ROC's most reliable and actionable signals often come from divergences with price. These can provide early warnings of trend reversals.
- Parameter Tuning: The `length` parameter (commonly 10 to 20 periods) influences the responsiveness of Volume ROC. Shorter lengths make it more sensitive to recent volume changes, potentially generating more signals. Longer lengths smooth the indicator, providing a broader view of volume momentum.
- Combine with Price Action: Always confirm Volume ROC signals with price action. A strong surge in Volume ROC is more meaningful if it aligns with a price breakout from a significant chart pattern (e.g., triangle, rectangle).
- Context is Key: Interpret Volume ROC in the context of the overall price trend. A positive Volume ROC in an uptrend confirms buying pressure, while a negative one in a downtrend confirms selling pressure.
- Thresholds: Experiment with positive and negative thresholds (e.g., +50% and -50%) to identify significant surges or contractions in volume momentum that are relevant to the asset you are trading.
- Volume Data Quality: Volume ROC is highly dependent on accurate and reliable volume data. Ensure the asset you are analyzing has consistent volume reporting.
Common Volume Rate of Change (Volume ROC) Pitfalls
- Lag: As a momentum indicator derived from historical data, Volume ROC can still exhibit some lag, especially during sharp reversals.
- False Signals: In very choppy or low-volume markets, Volume ROC can be erratic, generating ambiguous or false signals.
- No Fixed Overbought/Oversold Levels: Unlike oscillators like RSI, Volume ROC does not have predefined overbought/oversold zones. Its interpretation relies on its trend, zero-line crossovers, and divergence from price.
- Sensitivity to Volume Spikes: Isolated, large volume spikes (e.g., due to news releases) can cause extreme readings in Volume ROC that may not represent sustained changes in market participation.
- Division by Zero: If `volume[length]` is zero, the calculation can result in a division by zero error. The provided Pine Script code includes a check for this.
- Not a Standalone Indicator: Volume ROC is a powerful analytical tool but should never be used in isolation. It works best as a confirming indicator within a broader trading strategy.
Conclusion
Volume Rate of Change (Volume ROC) is an insightful technical indicator available in Pine Script for TradingView that focuses specifically on volume momentum. By quantifying the percentage change in trading volume over time, it provides traders with valuable insights into the underlying conviction behind price movements, aiding in trend confirmation, breakout detection, and identifying potential reversals through divergence. While it requires careful interpretation and combination with price action, mastering Volume ROC can significantly enhance your pine script strategies by providing a clearer understanding of market participation and the efficiency of price trends.