What it measures
On-Balance Volume is a running total of volume that adds a bar's volume when the close is higher than the previous close and subtracts it when the close is lower. The idea behind it is that volume tends to lead price: if a market rises on heavy volume and falls on light volume, OBV climbs.
Joseph Granville popularised OBV in his 1963 book on stock market timing. It's one of the simplest volume indicators, and its absolute value means nothing: only its direction and its shape relative to price matter.
The formula in words
- Compare the close with the previous close.
- If it's higher, OBV = previous OBV + this bar's volume. If it's lower, OBV = previous OBV − this bar's volume. If it's unchanged, OBV stays the same.
- Repeat for every bar.
The whole bar's volume counts, however small the price change: a close one tick higher on heavy volume moves OBV as much as a much larger rise on the same volume. The total also depends on where the calculation started, which is why OBV on one chart can show a different number from the same symbol on a chart with more history loaded.
How traders read it
- Confirmation. OBV making new highs together with price is read as volume supporting the move. OBV flat or falling while price rises suggests the rally has little volume behind it.
- Divergence. Price makes a higher high while OBV makes a lower high. Like any divergence, it describes the past and needs a trigger.
- OBV breakouts. Some traders watch for OBV breaking above its own recent range before price breaks out. The script marks the first bar on which OBV exceeds its highest value of the previous 50 bars.
- Signal line. A moving average of OBV turns the line into crosses: OBV above its average means recent volume has come mostly on up closes.
Common settings
| Setting | Typical value | Notes |
|---|---|---|
| Signal line | 20-period EMA | 10 or 30 periods, or an SMA, are also used. |
| Breakout lookback | 20 to 50 bars | How far back a "new OBV high" is measured. |
| Timeframe | Any with real volume | Daily charts are the classic use. |
OBV has no length of its own. All the settings above belong to the extra lines built on top of it.
Pine Script v6 code
The complete, self-contained script is below. Copy it into a new indicator in TradingView's Pine Editor, or download the .pine file.
//@version=6
indicator("On-Balance Volume (OBV) with signal line", shorttitle = "OBV", format = format.volume)
sigType = input.string("EMA", "Signal line type", options = ["EMA", "SMA"], group = "Signal line")
sigLen = input.int(20, "Signal line length", minval = 1, group = "Signal line")
brkLen = input.int(50, "New high/low lookback (bars)", minval = 2, group = "Breakouts")
vol = nz(volume)
// Add the bar's volume on an up close, subtract it on a down close, ignore it when the close is unchanged.
obv = ta.cum(math.sign(nz(ta.change(close))) * vol)
sigEma = ta.ema(obv, sigLen)
sigSma = ta.sma(obv, sigLen)
signal = sigType == "EMA" ? sigEma : sigSma
crossUp = ta.crossover(obv, signal)
crossDown = ta.crossunder(obv, signal)
// OBV beyond its own range of the previous brkLen bars.
prevHigh = ta.highest(obv, brkLen)[1]
prevLow = ta.lowest(obv, brkLen)[1]
newHigh = obv > prevHigh
newLow = obv < prevLow
firstNewHigh = newHigh and not newHigh[1]
firstNewLow = newLow and not newLow[1]
plot(obv, "OBV", color = obv >= signal ? color.new(color.teal, 0) : color.new(color.red, 0), linewidth = 2)
plot(signal, "Signal", color = color.new(color.orange, 0))
plotshape(firstNewHigh, "OBV new high", shape.triangleup, location.bottom, color.new(color.teal, 0), size = size.tiny)
plotshape(firstNewLow, "OBV new low", shape.triangledown, location.top, color.new(color.red, 0), size = size.tiny)
alertcondition(crossUp, "OBV crosses above signal", "OBV crossed above its signal line on {{ticker}} ({{interval}})")
alertcondition(crossDown, "OBV crosses below signal", "OBV crossed below its signal line on {{ticker}} ({{interval}})")
alertcondition(firstNewHigh, "OBV new high", "OBV made a new high for the lookback on {{ticker}} ({{interval}})")
alertcondition(firstNewLow, "OBV new low", "OBV made a new low for the lookback on {{ticker}} ({{interval}})")
totalVol = ta.cum(vol)
if barstate.islast and totalVol == 0
runtime.error("This symbol has no volume data, so OBV can't be calculated.")The script computes OBV from its definition with ta.cum() and math.sign(), so you can see exactly how it's built. OBV is drawn green while it's above its signal line and red below, with triangles on the first new high or low for the lookback.
Alert conditions cover signal-line crosses and new OBV highs and lows. On symbols with no volume data the script stops with a clear message instead of drawing a flat line.
Add it to your chart
- Open any chart on TradingView and open the Pine Editor.
- Create a new indicator, delete the template code and paste the script.
- Click Save, then Add to chart. Change lengths and levels from the indicator's settings.
Stuck on an error? See how to add a Pine Script indicator to TradingView.
Pitfalls
- Reading the number. OBV's level depends on the first bar loaded. Compare its direction and its highs and lows with price, never the value itself.
- Tick volume. Spot forex and many CFD feeds report tick volume, the number of price changes. OBV still draws, but it measures activity, not traded size.
- One big bar. A single heavy-volume session, such as an index rebalance or an earnings release, can shift OBV for good. Check what caused a jump before drawing conclusions.
- Divergence as timing. OBV can disagree with price for a long time. Use it as context, with a separate entry rule.
Related reading
- Pine Script alerts: alertcondition() vs alert(), messages, webhooks and frequency
- 8 backtesting mistakes that make a strategy look better than it is
- Position Size Calculator (free tool)
- Risk/Reward Calculator (free tool)
The script is an educational example: test it on your own markets before relying on it. Indicators describe the past; they don't predict the future. Trading involves substantial risk of loss and is not suitable for every investor. Edgoro is a software tool, not a broker or financial adviser: nothing it produces is investment advice, and past or backtested performance does not guarantee future results.