Logo
OFFLINEPIXEL
/ pinescript-strategies / pine-script-negative-volume-index

$ Pinescript Negative Volume Index (NVI)

Master this unique volume-based indicator in TradingView's Pinescript, designed to track "smart money" activity, particularly on low-volume days, to confirm trends and anticipate price movements.

500+ Clients Helped
100% Satisfaction
Live Trading Ready
⚠️
Trading financial markets carries risk. All content (PineScript code, indicators, strategies) on this website is for educational purposes only. Past performance is not indicative of future results. By using any code or information from this site, you agree that you are solely responsible for your trading decisions. The author disclaims all liability for any losses incurred. To gain from experts experiences, You can always try our Invite Only Scripts
01

What is the Negative Volume Index (NVI)?

The Negative Volume Index (NVI) is a cumulative momentum indicator that focuses on periods of decreasing volume. Developed by Paul Dysart and popularized by Norman Fosback, the underlying theory behind NVI is that "smart money" (institutional or well-informed investors) tends to operate on low-volume days, while "uninformed money" operates on high-volume days. Therefore, changes in price action on low-volume days are considered more significant than changes on high-volume days.

The NVI essentially tracks a cumulative sum that is adjusted only when volume decreases from the previous day. If volume decreases, the NVI is adjusted by the percentage change in price. If volume increases, the NVI remains unchanged. A rising NVI suggests smart money is accumulating an asset, even on low volume, which often precedes price increases. A falling NVI suggests smart money is distributing. NVI is primarily used to:

  • Identify divergences: When price and NVI move in opposite directions, it can signal an impending trend reversal.
  • Confirm price trends: NVI's trend confirms the underlying strength of a price trend, particularly on low-volume days.
  • Gauge long-term sentiment: It's often used as a long-term indicator for the overall market or individual stocks.
02

Components and Calculation

The calculation of the Negative Volume Index is cumulative and depends on the relationship between current and previous volume:

  1. Initialize NVI: The starting value of NVI is usually set to 1000 (or some other arbitrary base value) to provide a convenient reference point.
  2. Conditional Update: For each period:
    • If Current Volume < Previous Volume: `NVI = Previous NVI + (Previous NVI * ((Close - Previous Close) / Previous Close))` Essentially, `NVI = Previous NVI * (1 + Price Percentage Change)` * Handle `Previous Close == 0` to avoid division by zero.
    • If Current Volume > Previous Volume: `NVI = Previous NVI` (NVI remains unchanged)
    • If Current Volume == Previous Volume: `NVI = Previous NVI` (NVI remains unchanged)
03

Basic Negative Volume Index (NVI) Implementation in Pinescript

pine-script@terminal
//@version=5
indicator("My Negative Volume Index (NVI)", overlay=false) // overlay=false to plot in a separate pane

// Input for NVI starting value (arbitrary, but common to start at 1000)
nviStartValue = input.float(1000, title="NVI Start Value")

// Calculate NVI using the built-in function
// ta.nvi() uses 'close' for price comparison and 'volume' for volume comparison
nviValue = ta.nvi(nviStartValue, close, volume)

// Plot the NVI line
plot(nviValue, title="NVI", color=color.blue, linewidth=2)

// Optional: Add a Moving Average of NVI (often a long-term EMA) as a signal line
// A common length for the NVI MA is 255 (representing roughly a year of trading days)
nviMALength = input.int(255, title="NVI MA Length", minval=1)
nviMA = ta.ema(nviValue, nviMALength)

// Plot the NVI Moving Average
plot(nviMA, title="NVI MA", color=color.orange, linewidth=1)
$ ✓ Compiled successfully
04

Smart Money Focus

Smart Money Focus

NVI specifically tracks activity on low-volume days, believing that these are the days when informed investors subtly position themselves.

05

Practical NVI Trading Strategies

06

1. NVI and Moving Average Crossovers (Trend Confirmation)

pine-script@terminal
//@version=5
strategy("NVI Crossover Strategy", overlay=true)

nviStartValue = input.float(1000, title="NVI Start Value")
nviMALength = input.int(255, title="NVI MA Length", minval=1) // Long-term MA

nviValue = ta.nvi(nviStartValue, close, volume)
nviMA = ta.ema(nviValue, nviMALength)

plot(nviValue, "NVI", color.blue, display=display.pane_only)
plot(nviMA, "NVI MA", color.orange, display=display.pane_only)

// Long entry: NVI crosses above its MA
longCondition = ta.crossover(nviValue, nviMA)

// Short entry: NVI crosses below its MA
shortCondition = ta.crossunder(nviValue, nviMA)

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

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

// Basic exit: opposite signal
strategy.close("Long NVI", when=shortCondition)
strategy.close("Short NVI", when=longCondition)
$ ✓ Compiled successfully
07

2. NVI Divergence (Key Reversal Signal)

pine-script@terminal
//@version=5
strategy("NVI Divergence Strategy", overlay=true)

nviStartValue = input.float(1000, title="NVI Start Value")
nviValue = ta.nvi(nviStartValue, close, volume)
nviMALength = input.int(255, title="NVI MA Length", minval=1)
nviMA = ta.ema(nviValue, nviMALength)

plot(nviValue, "NVI", color.blue, display=display.pane_only)
plot(nviMA, "NVI MA", color.orange, 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 NVI.

// Bullish Divergence: Price lower low, NVI higher low
bullishDiv = close < close[1] and close[1] < close[2] and nviValue > nviValue[1] and nviValue[1] > nviValue[2]

// Bearish Divergence: Price higher high, NVI lower high
bearishDiv = close > close[1] and close[1] > close[2] and nviValue < nviValue[1] and nviValue[1] < nviValue[2]

// Plot shapes on the chart to indicate divergence
plotshape(bullishDiv, title="Bullish NVI Divergence", location=location.belowbar, color=color.new(color.green, 0), style=shape.triangleup, size=size.small)
plotshape(bearishDiv, title="Bearish NVI Divergence", location=location.abovebar, color=color.new(color.red, 0), 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)
$ ✓ Compiled successfully
08

3. NVI as a Long-Term Trend Filter

pine-script@terminal
//@version=5
strategy("NVI Trend Filter Strategy", overlay=true)

nviStartValue = input.float(1000, title="NVI Start Value")
nviMALength = input.int(255, title="NVI MA Length", minval=1) // Long-term MA filter

nviValue = ta.nvi(nviStartValue, close, volume)
nviMA = ta.ema(nviValue, nviMALength)

plot(nviValue, "NVI", color.blue, display=display.pane_only)
plot(nviMA, "NVI MA", color.orange, display=display.pane_only)

// Define NVI trend direction
isNviUptrend = nviValue > nviMA
isNviDowntrend = nviValue < nviMA

// Example: Combine with a simple price EMA crossover strategy
fastPriceMALength = input.int(10, title="Fast Price MA Length", minval=1)
slowPriceMALength = input.int(20, title="Slow Price MA Length", minval=1)

fastPriceMA = ta.ema(close, fastPriceMALength)
slowPriceMA = ta.ema(close, slowPriceMALength)

longEntrySignal = ta.crossover(fastPriceMA, slowPriceMA)
shortEntrySignal = ta.crossunder(fastPriceMA, slowPriceMA)

// Only take long entries if NVI confirms a bullish trend
if (longEntrySignal and isNviUptrend)
    strategy.entry("Filtered Long", strategy.long)

// Only take short entries if NVI confirms a bearish trend
if (shortEntrySignal and isNviDowntrend)
    strategy.entry("Filtered Short", strategy.short)

// Exit on opposite price MA crossover, regardless of NVI filter for simplicity
strategy.close("Filtered Long", when=ta.crossunder(fastPriceMA, slowPriceMA))
strategy.close("Filtered Short", when=ta.crossover(fastPriceMA, slowPriceMA))

// Optional: Color background based on NVI trend
bgcolor(isNviUptrend ? color.new(color.lime, 95) : na, title="NVI Bullish Bias")
bgcolor(isNviDowntrend ? color.new(color.maroon, 95) : na, title="NVI Bearish Bias")
$ ✓ Compiled successfully
09

Optimizing Negative Volume Index (NVI) Performance

To get the most from the Negative Volume Index in Pinescript:

  • Smoothing is Crucial: NVI can be very volatile, especially on lower timeframes. Applying a long-term moving average (e.g., 255-period EMA for daily charts) is essential to smooth out noise and identify its underlying trend.
  • Focus on Divergence: Like other volume-based indicators, NVI's most powerful signals often come from divergences with price. These can provide early warnings of trend reversals as smart money deviates from the mainstream price action.
  • Timeframe Consideration: NVI is more suited for longer-term analysis (daily, weekly charts) due to its theory focusing on smart money's subtle, low-volume activity. It might be less effective or generate more noise on very short intraday timeframes.
  • Combine with Price Action: Always confirm NVI signals with price action. An NVI signal is more reliable if supported by clear candlestick patterns, breaks of support/resistance, or other price-based confirmations.
  • Context is Key: Interpret NVI in the context of the overall market or asset. Its absolute value is not important; what matters is its trend relative to its moving average, and its divergence from price.
10

Unmasking Smart Money

Unmasking Smart Money

NVI offers a rare glimpse into the actions of potentially more informed investors, as it attributes greater significance to price changes that occur on quiet, low-volume days.

11

Common NVI Pitfalls

  • Lag: As a cumulative indicator smoothed by a moving average, NVI inherently lags price action. Its signals are often for confirmation or long-term trend shifts rather than immediate entries.
  • False Signals: Like any indicator, it can generate false signals, especially in markets with erratic volume patterns or during periods of very low liquidity where volume changes might not truly reflect smart money activity.
  • Absolute Value Meaningless: The raw NVI value (e.g., starting at 1000) has no intrinsic meaning other than its relation to its past values and its moving average.
  • Limited on High Volume Days: By design, NVI ignores price action on high-volume days. This means it misses significant information, and should always be used alongside other indicators that capture high-volume moves.
  • Not a Standalone Indicator: NVI provides crucial insights but should never be used in isolation. It works best as a confirming or filtering indicator within a broader trading strategy.
12

Conclusion

Conclusion

The Negative Volume Index (NVI) is a unique and insightful technical indicator available in Pinescript for TradingView. By specifically focusing on price movements on low-volume days, it attempts to track the activity of "smart money" and provide a distinct perspective on underlying market sentiment. While its greatest strengths lie in confirming long-term trends and identifying powerful divergences with price (signaling potential trend reversals), it is most effective when smoothed with a moving average and integrated strategically with price action and other technical analysis tools. By understanding its calculation and thoughtfully utilizing its signals, you can leverage NVI to enhance your Pinescript strategies and gain a clearer understanding of market conviction, particularly from the perspective of informed investors.

Enhance Your Trading

Get a high-performance Pinescript analysis tool for actionable market insights, designed for traders on the move.

This strategy runs in live mode on TradingView, helping you identify potential opportunities.

Get Pinescript Strategy