OBV
On-Balance Volume
A cumulative volume line that rises and falls with the direction of each session — and sometimes diverges from price.
What is it?
Developed by Joseph Granville in 1963, OBV is a cumulative volume indicator. When price closes up, the full volume for that period is added to the running total; when price closes down, the full volume is subtracted. The absolute value of OBV is meaningless — what matters is the direction and slope of the OBV line relative to price. The core principle: volume precedes price. If OBV is rising while price is flat or falling, smart money is accumulating (bullish). If OBV is falling while price is flat or rising, smart money is distributing (bearish).
Common pitfalls
- OBV treats all volume equally regardless of where within the candle the volume occurred. A candle that closed up by 0.01% with massive volume adds the same as a 5% up candle.
- OBV is highly sensitive to the first data point — the starting value is arbitrary. Only the slope and relative changes matter, not the absolute level.
- On crypto exchanges, wash trading and artificial volume inflate OBV readings. Always cross-reference with on-chain volume data for major assets.
- OBV divergence can persist for weeks or months before price reacts. It is a warning reading, not a timing tool.
- OBV works best on assets with reliable, centralised volume data. For assets traded across dozens of DEXs, aggregated volume may be incomplete.
Indicator Rider — Volume Elevator
The Volume Elevator rises and falls with OBV momentum — green when accumulation is driving price, red when distribution is setting in.
Free code template
Paste directly into TradingView Pine Editor → Add to chart.
/indicator("OBV — DAI Template", shorttitle="DAI OBV", overlay=false)
obvVal = ta.obv
obvEma = ta.ema(obvVal, 20)
obvRising = obvVal > obvVal[1]
plot(obvVal, "OBV", color = obvRising ? #14b8a6 : #ef4444, linewidth=2)
plot(obvEma, "OBV EMA20", color=color.new(#f59e0b, 20), linewidth=1)
bullDiv = close < close[5] and obvVal > obvVal[5]
bearDiv = close > close[5] and obvVal < obvVal[5]
plotshape(bullDiv, "Bull Div", shape.labelup, location.bottom, #22c55e, text="OBV↑", size=size.small)
plotshape(bearDiv, "Bear Div", shape.labeldown, location.top, #ef4444, text="OBV↓", size=size.small)
alertcondition(bullDiv, "OBV Bull Divergence", "OBV rising while price falling")
alertcondition(bearDiv, "OBV Bear Divergence", "OBV falling while price rising")