On-Balance Volume, or OBV, is one of the oldest and most intuitive volume indicators, and it rests on a single idea that is easy to state: volume should confirm price. If a market is rising on heavy volume, buyers are committing real money, and the move has weight behind it. If it is rising on thin volume, the advance may be hollow. OBV turns that idea into a running total you can plot and compare against price. This guide explains what OBV measures, why volume confirmation matters, and how to build it from scratch in Pine Script v6 on TradingView.
This is a coding tutorial, not trading advice. OBV is a way to express the relationship between price direction and volume in code, and building it yourself makes both its logic and its limits clear.
What OBV measures
The OBV calculation is refreshingly simple. It is a cumulative running total: on any bar where price closes higher than the previous bar, the whole of that bar's volume is added to the total, and on any bar where price closes lower, the whole of its volume is subtracted. On an unchanged close, the total stays put. Popularized by Joseph Granville in the 1960s, the method treats each up day as net buying pressure and each down day as net selling pressure, then accumulates the difference over time.
The exact number the OBV line reaches is meaningless in isolation; it depends entirely on where the calculation happened to start. What matters is the shape and direction of the line. A rising OBV means volume is flowing in on up days faster than it flows out on down days, and a falling OBV means the reverse. Because it is a pure accumulation, OBV is best read as a trend of its own, compared against the trend in price.
Why traders use it
The central use of OBV is confirmation and, more powerfully, divergence. When price and OBV rise together, the advance is backed by volume and looks healthy. The interesting case is when they disagree: if price grinds to a new high while OBV fails to, it suggests the latest push is happening on lighter volume than before, a hint that conviction is fading even though price has not turned. The mirror case, price making new lows while OBV holds up, is read as quiet accumulation beneath a declining surface.
| Price vs OBV | What it suggests |
|---|---|
| Both making new highs | Advance backed by volume |
| Price up, OBV flat or down | Bearish divergence, thin advance |
| Both making new lows | Decline backed by volume |
| Price down, OBV flat or up | Bullish divergence, quiet accumulation |
This divergence reading is why OBV is often described as a leading indicator, though that word oversells it. Divergences can persist far longer than they seem like they should, and a fading volume trend does not guarantee a price reversal any more than an overbought RSI does. OBV is best used as confirmation for a thesis you already hold, not as a standalone trigger.
Building the indicator
Pine Script exposes OBV as a built-in variable, ta.obv, so plotting the raw line takes almost no code. A common refinement is to add a moving average of OBV to smooth it and give a clearer sense of its direction. Here is the complete v6 indicator.
//@version=6
indicator("On-Balance Volume", overlay = false)
maLength = input.int(20, "OBV MA Length")
obvValue = ta.obv
obvMA = ta.sma(obvValue, maLength)
plot(obvValue, "OBV", color = color.blue, linewidth = 2)
plot(obvMA, "OBV MA", color = color.orange)Notice that ta.obv is used without parentheses, because it is a built-in series variable rather than a function you call with arguments. It already carries the full cumulative calculation, soobvValue = ta.obv gives you the running total directly. The ta.sma(obvValue, maLength) line smooths it into a moving average, and crossovers between the raw OBV and its average give a cleaner sense of when the volume trend is turning. Setting overlay = false keeps OBV in its own pane, since its scale has nothing to do with price. If you want to see the add-and-subtract accumulation done by hand, our OBV calculator walks through it with the Pine Script equivalent alongside.
A strategy using OBV as confirmation
Because OBV is best as confirmation, a sensible strategy uses it to filter a price signal rather than to generate one alone. Here is a version that takes a moving-average crossover only when OBV is also trending up, confirming that volume supports the move.
//@version=6
strategy("OBV-Confirmed Crossover", overlay = true, margin_long = 100, margin_short = 100)
maLength = input.int(20, "OBV MA Length")
obvValue = ta.obv
obvMA = ta.sma(obvValue, maLength)
fastMA = ta.ema(close, 9)
slowMA = ta.ema(close, 21)
crossUp = ta.crossover(fastMA, slowMA)
volumeRising = obvValue > obvMA
if crossUp and volumeRising
strategy.entry("Long", strategy.long)
if ta.crossunder(fastMA, slowMA)
strategy.close("Long")The gate here is volumeRising = obvValue > obvMA, which is true when OBV is above its own moving average, a simple way of saying the volume trend is pointing up. The price crossover only triggers an entry when volume confirms it, filtering out advances that are not backed by participation. Assigning crossUp to its own line before the if keeps the crossover running every bar, the same hoisting discipline we apply throughout. Because OBV depends on volume data, this script needs a symbol that reports volume; on one that does not, OBV cannot be computed.
The honest pitfalls
The first pitfall is reading the absolute OBV value as if it means something. It does not; only the direction and the divergences carry information, because the starting point is arbitrary. The second is treating a divergence as a timing signal. Volume can diverge from price for a long time before, or without, any reversal, so acting on divergence alone is a fast way to fight a trend that is not ready to turn.
The third, and easiest to overlook, is data quality. OBV is only as good as the volume feed behind it, and volume reporting varies by market. In fragmented markets like decentralized crypto venues or some forex feeds, the reported volume may not reflect the full picture, which quietly distorts OBV. Always know what volume your symbol is actually reporting, and judge any OBV-based strategy across a meaningful sample rather than a handful of clean-looking divergences. For a related price-and-volume oscillator that bounds its reading, see our Money Flow Index guide.
Building it faster
Coding OBV by hand is quick, and adding the moving average and confirmation logic is a good exercise in combining volume with price. When you already know how you want to use it, describing the rule in plain English is faster than wiring it up. A tool like PineScripter generates the v6 code and fixes compile errors automatically by reading TradingView's messages directly. You can compare it against other options in our roundup of the best AI Pine Script generators.
The takeaway
On-Balance Volume is a running total of volume added on up closes and subtracted on down closes, available in one built-in, ta.obv. Its value is not the number it reaches but the direction it travels and how that compares to price. Use it to confirm that a move has volume behind it and to spot when it does not, treat divergences as context rather than triggers, and always check that your symbol's volume data is trustworthy.
Disclaimer: PineScripter is a coding tool for Pine Script development. It does not provide financial advice and does not guarantee trading profits. Always backtest strategies thoroughly and understand the risks before live trading.