Negative Volume Index (NVI)
Calculate the Negative Volume Index (NVI) for a given price series.
The Negative Volume Index is a cumulative index that only updates on days where volume decreases from the prior period, compounding that day’s percentage price change onto the running index; on days where volume increases (or stays flat), the index is carried forward unchanged. The premise, per Fosback, is that “smart money” tends to be active on low-volume (quiet) days, so tracking price behaviour specifically on those days isolates informed trading from the noise of high-volume, crowd-driven days.
The formula is as follows:
\[\operatorname{Index}(t) = \operatorname{Index}(t-1) \cdot (1 + (\operatorname{Close}(t) / \operatorname{Close}(t-1) - 1)) \text{if Volume} (t) < \operatorname{Volume}(t-1)\] \[\operatorname{Index}(t) = \operatorname{Index}(t-1) \text{otherwise}\]Also known as: NVI, Negative Volume Index.
Negative Volume Index (NVI) in Python or via the MCP
Install the Finance Toolkit with:
pip install financetoolkit -U
Then call get_negative_volume_index as shown below.
from financetoolkit import Toolkit
toolkit = Toolkit(
tickers=["SPY", "IWM"],
api_key="FINANCIAL_MODELING_PREP_KEY",
start_date="2021-01-01",
end_date="2025-12-31",
benchmark_ticker=None,
)
toolkit.technicals.get_negative_volume_index().tail(5)
Or, after setting up the Finance Toolkit MCP, ask:
How did the Negative Volume Index of SPY and IWM, counted from the start of 2021, develop from 24 to 31 December 2025?
Which returns:
| Date | SPY | IWM |
|---|---|---|
| 2025-12-24 | 5440.48 | 4501.78 |
| 2025-12-26 | 5440.48 | 4501.78 |
| 2025-12-29 | 5440.48 | 4501.78 |
| 2025-12-30 | 5433.84 | 4468.59 |
| 2025-12-31 | 5433.84 | 4468.59 |
Parameters
get_negative_volume_index accepts the following parameters.
| Parameter | Type | Description | Example |
|---|---|---|---|
period | str | The time period to consider for historical data. Can be “intraday”, “daily”, “weekly”, “monthly”, “quarterly” or “yearly”. Defaults to “daily”. | "weekly" |
close_column | str | The column name for closing prices in the historical data. Defaults to “Adj Close”. | "Close" |
start_value | float | The index value to start the series at. Defaults to 1000.0. | 100.0 |
rounding | int | None | The number of decimals to round the results to. Defaults to None, which uses the rounding of the Toolkit (4 unless set otherwise). | 2 |
growth | bool | Whether to calculate the growth of the Negative Volume Index. Defaults to False. | True |
lag | int | list[int] | The lag to use for the growth calculation. Defaults to 1. | 4 |
standardize | bool | Whether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False. | True |