Smoothed On-Balance Volume (OBV) — Volume Drop
On-Balance Volume is the oldest volume-trend tool there is, but a raw cumulative line is noisy and hard to read against price. This drop wraps Granville's classic OBV in an EMA signal line and an optional smoothing pass so you get a clean, color-coded trigger instead of a jagged tally.
## What it does
- Builds the cumulative Granville OBV: adds full bar volume on up-closes, subtracts it on down-closes, holds flat on unchanged closes
- Plots an EMA signal line (default 20) over the OBV for a tradeable cross trigger
- Color-codes the OBV line green/red by its position relative to the signal
- Optional pre-smoothing EMA on the OBV itself for cleaner divergence reading
- Fires arrows, a status label, and bull/bear alerts on every signal cross
## Recommended settings
- Signal EMA length: 20
- OBV smoothing length: 1 (raw) — bump to 3-5 on noisy intraday charts
- Show signal line: on
- Show cross arrows: on
- Show status label: on
## Ideal timeframe
Works on any timeframe; shines on daily and 1H swing charts where accumulation/distribution builds over many bars.
## How to use
Watch the OBV line relative to its signal: above and green confirms buyers are pressing, below and red flags distribution. Cross arrows mark momentum shifts in the volume tape — but the real edge is divergence. When price makes a new high while OBV refuses to, sellers are quietly stepping in; the reverse warns of exhausted selling. Treat the signal cross as a trigger and the divergence as the thesis.
## thinkScript code
```thinkscript
# ─────────────────────────────────────────────
# │ MarketFragments.com | DNA & Market │
# │ info@marketfragments.com │
# │ www.marketfragments.com │
# ─────────────────────────────────────────────
# Time →
# │
# █ █ █│ █
# █ █ █ │ █ █
# █ █ █ │ █ █ █ ╭─╮
# █ █ █ │ █ █ █ █ ╭─╯ ╰─╮
# █ █ █ │ █ █ █ █ █ █ ╭─╯ ╰─╮
# █ █ █ │ █ █ █ █ █ █ █ █ ╭─╯ ╰─╮
# █ █ █ │ █ █ █ █ █ █ █ █ █ █╭─╯ ╰─╮
# █ █ █ │ █ █ █ █ █ █ █ █ ╰─╮ ╭─╯
# █ █ █ │ █ █ █ █ █ █ ╰─╮ ╭─╯
# █ █ █ │ █ █ █ █ ╰─╮ ╭─╯
# █ █ █ │ █ █ ╰─╮ ╭─╯
# █ █ █ │ █ ╰─────╯
# ──────┴──────────────────────────────────────────────────────────────
# T1 T2 T3 T4 T5 T6
#
# ============================================================
# Smoothed On-Balance Volume (OBV) | Volume category
# ------------------------------------------------------------
# Classic Granville OBV: cumulative volume that adds full bar
# volume on up-closes and subtracts it on down-closes. An EMA
# signal line turns the running tally into a tradeable trigger,
# and an optional smoothing EMA tames the raw line for cleaner
# divergence reading against price.
#
# - OBV line color-coded by position vs. its signal
# - EMA signal line (default 20)
# - Optional pre-smoothing EMA on OBV itself
# - Cross arrows + status label + bull/bear alerts
#
# Free for non-commercial use. Attribution appreciated.
# ============================================================
declare lower;
input signalLength = 20; # EMA length for the signal line
input smoothLength = 1; # 1 = raw OBV; >1 applies an EMA to OBV
input showSignal = yes;
input showCrossArrows = yes;
input showLabel = yes;
def vol = volume;
# Cumulative Granville OBV
def rawOBV = CompoundValue(1,
if close > close[1] then rawOBV[1] + vol
else if close < close[1] then rawOBV[1] - vol
else rawOBV[1],
vol);
def obv = if smoothLength <= 1 then rawOBV else ExpAverage(rawOBV, smoothLength);
def signal = ExpAverage(obv, signalLength);
plot OBV = obv;
OBV.SetLineWeight(2);
OBV.AssignValueColor(if obv >= signal then Color.GREEN else Color.RED);
plot Signal = if showSignal then signal else Double.NaN;
Signal.SetDefaultColor(Color.GRAY);
Signal.SetLineWeight(1);
def bullCross = obv crosses above signal;
def bearCross = obv crosses below signal;
plot BullArrow = if showCrossArrows and bullCross then obv else Double.NaN;
BullArrow.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
BullArrow.SetDefaultColor(Color.CYAN);
BullArrow.SetLineWeight(3);
plot BearArrow = if showCrossArrows and bearCross then obv else Double.NaN;
BearArrow.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
BearArrow.SetDefaultColor(Color.MAGENTA);
BearArrow.SetLineWeight(3);
AddLabel(showLabel,
"OBV " + (if obv >= signal then "ABOVE" else "BELOW") + " signal",
if obv >= signal then Color.GREEN else Color.RED);
Alert(bullCross, "OBV bullish cross", Alert.BAR, Sound.Ding);
Alert(bearCross, "OBV bearish cross", Alert.BAR, Sound.Ding);
```
Drop your tweaks, screenshots, and questions below — that's how the library gets better.

