Skip to content
Open RaamTrade

PositiveVolumeIndex — Positive Volume Index

A cumulative index that changes only on rising-volume bars — the crowd’s index, the mirror of NVI. Read the two together: agreement is a broad move, divergence says the crowd and the quiet money disagree.

Signature

PositiveVolumeIndex(period, on=<source>)
Argument Type Required Notes
period int Param or literal Yes SMA smoothing of the index. 1 returns the raw index. Bounds 1–200.
on= symbol No Source symbol. Defaults to the trade symbol. Reads close and volume.

Formula

$$ \text{PVI}t = \begin{cases}\text{PVI}{t-1}\left(1 + \frac{C_t - C_{t-1}}{C_{t-1}}\right) & V_t > V_{t-1} \ \text{PVI}_{t-1} & \text{otherwise}\end{cases} $$

Warmup

Starts at 1000 and accumulates; resets per run.

Reading the value

pvi.value

Example

class CrowdFilter(Strategy):
"""Long while the crowd's index is above its own base."""
trade = Symbol()
sizing = FixedCapital()
def execute(self):
pvi = PositiveVolumeIndex(1, on=self.trade)
base = EMA(255, on=pvi)
if pvi.value > base.value and self.trade.is_flat:
self.buy(self.trade, reason="PVI above its base")
if pvi.value < base.value and self.trade.is_long:
self.sell(self.trade, self.trade.position, reason="PVI below its base")

Notes

  • Norman Fosback, Stock Market Logic (1976).