Skip to content

Free TradingView indicator

OBV Signal

On-Balance Volume with an EMA or SMA signal line, a spread histogram and confirmed cross signals with alerts.

Volumev1.0TradingView (Pine Script v6) Non-repainting signals Alerts

What it does

On-Balance Volume (OBV) is a running total of volume that adds a bar's volume when price closes higher and subtracts it when price closes lower. The absolute value of OBV has no meaning; what matters is its direction. A rising OBV suggests volume is heavier on up bars, a falling OBV suggests it is heavier on down bars.

This indicator adds a signal line and marks the bars where OBV crosses it. It deliberately uses only crosses: there is no automatic divergence detection, so every signal follows one clear rule that you can check by eye.

How it works

  1. If the close is higher than the previous close, the bar's volume is added to OBV. If lower, it is subtracted. If unchanged, OBV stays the same.
  2. Signal line = EMA or SMA of OBV over the signal length.
  3. Histogram = OBV − signal line.
  4. A bullish cross is a closed bar where OBV moves from at or below the signal line to above it. A bearish cross is the opposite.
  5. With "Min bars between signals" above zero, a cross is ignored if the previous accepted cross happened within that many bars.

How to use it

Think of the OBV cross as a volume-flow version of a moving-average cross. A bullish cross says OBV has moved above its own recent average, meaning volume has been leaning toward up closes; a bearish cross says the opposite.

Ways to use it:

  • As a confirmation filter: take long setups from your main method only while OBV is above its signal line.
  • To check breakouts: a price breakout with OBV crossing up in the same bar or shortly before is often treated as better supported than one where OBV is falling.
  • On higher timeframes such as H4 and D1, where each bar holds more volume and the line is less noisy.

The technical analysis basics lesson covers how indicators like this fit into a broader process.

Settings

InputDefaultWhat it changes
Signal typeEMAEMA reacts faster, SMA is smoother.
Signal length20Longer = fewer crosses.
Min bars between signals0Thins out back-to-back crosses in sideways markets.
Show OBV minus signal histogramonShows the spread as columns.
Show cross markersonDots on the signal line at crosses.

Limitations

  • OBV assigns a bar's entire volume to one side based only on the close-to-close change. A bar that closes one tick higher counts the same as a strong rally.
  • On spot forex, TradingView volume is usually tick volume from one feed, so OBV reflects activity on that feed only.
  • OBV starts at zero on the first loaded bar, so its level depends on how much history is loaded. Only its shape and crosses are meaningful.
  • Crosses lag price and can whipsaw when OBV moves sideways around the signal line.
  • The script stops with an error on symbols with no volume data.

Pine Script source

In TradingView open Pine Editor, paste the code, click Save and then Add to chart.

FXP_OBVSignal.pine

56 lines

// © FXPIPS ONLINE — https://fxpips.online/tradingview-indicators/obv-signal/
// License: MIT. Educational tool — not financial advice. Trading involves substantial risk.
//@version=6
indicator("FXP OBV Signal", shorttitle = "FXP OBV", overlay = false, format = format.volume)

// ── Inputs ─────────────────────────────────────────────────────────────
grpS     = "Signal line"
maType   = input.string("EMA", "Signal type", options = ["EMA", "SMA"], group = grpS)
sigLen   = input.int(20, "Signal length", minval = 1, group = grpS)
minBars  = input.int(0, "Min bars between signals", minval = 0, group = grpS, tooltip = "0 = every cross is shown. Raise it to thin out crosses in sideways markets.")

grpVis   = "Display"
showHist = input.bool(true, "Show OBV minus signal histogram", group = grpVis)
showSig  = input.bool(true, "Show cross markers", group = grpVis)
upCol    = input.color(color.teal, "Bullish color", group = grpVis)
dnCol    = input.color(color.red, "Bearish color", group = grpVis)

// ── Calculation ────────────────────────────────────────────────────────
// OBV adds the bar's volume when close rises, subtracts it when close falls, ignores unchanged closes.
float chg     = ta.change(close)
float signed  = chg > 0 ? nz(volume) : chg < 0 ? -nz(volume) : 0.0
float obv     = ta.cum(signed)
float obvEma  = ta.ema(obv, sigLen)
float obvSma  = ta.sma(obv, sigLen)
float signal  = maType == "EMA" ? obvEma : obvSma
float spread  = obv - signal

bool rawUp = ta.crossover(obv, signal)
bool rawDn = ta.crossunder(obv, signal)

var int lastSigBar = na
bool crossUp = false
bool crossDn = false
if barstate.isconfirmed and (rawUp or rawDn)
    bool spaced = na(lastSigBar) or bar_index - lastSigBar > minBars
    if spaced
        crossUp := rawUp
        crossDn := rawDn
        lastSigBar := bar_index

float cumVol = ta.cum(nz(volume))
if barstate.islast and cumVol == 0
    runtime.error("This symbol provides no volume data, so OBV cannot be calculated.")

// ── Plots ──────────────────────────────────────────────────────────────
plot(showHist ? spread : na, "OBV - signal", style = plot.style_columns, color = spread >= 0 ? color.new(upCol, 75) : color.new(dnCol, 75))
plot(obv, "OBV", color = obv >= signal ? upCol : dnCol, linewidth = 2)
plot(signal, "Signal", color = color.new(color.gray, 10))

plotshape(showSig and crossUp ? signal : na, "Bullish cross", shape.circle, location.absolute, upCol, size = size.tiny)
plotshape(showSig and crossDn ? signal : na, "Bearish cross", shape.circle, location.absolute, dnCol, size = size.tiny)

// ── Alerts ─────────────────────────────────────────────────────────────
alertcondition(crossUp, "OBV crossed above signal", "FXP OBV: OBV crossed above its signal line on {{ticker}} {{interval}}")
alertcondition(crossDn, "OBV crossed below signal", "FXP OBV: OBV crossed below its signal line on {{ticker}} {{interval}}")

Key inputs

Key inputs of OBV Signal
InputDefaultDescription
Signal typeEMAMoving average type for the signal line.
Signal length20Bars used for the signal line.
Min bars between signals0Suppresses crosses that come too soon after the previous one.
Show OBV minus signal histogramtrueColumns showing the distance between OBV and its signal line.

Educational tools, not advice. Indicators and Expert Advisors describe price; they do not predict it, and past behaviour does not guarantee future results. Test everything on a demo account first and never risk money you cannot afford to lose. See our disclaimer.

Keep exploring

Related tradingview indicators