TradingView indicator guides

OBV Oscillator: Rolling Volume Residual and Pine Script | Pineify

This OBV oscillator subtracts an EMA from a rolling sum of signed volume. Its zero line compares that sum with its own smoothed history. A positive output does not mean the sum itself is positive, and neither value identifies buyers, sellers, or institutional activity.

Inspect the Pine Script

The actual calculation

For valid price observations, define q as current volume when the selected source rises, negative volume when it falls, and zero when it is unchanged. Let S be the sum of the latest N contributions. The EMA E uses the same N, with alpha = 2/(N + 1). The plotted oscillator is O = S − E.

This is not cumulative OBV minus its EMA. On complete observations, S equals cumulative OBV minus its value N bars earlier. Subtracting E then adds another transformation. Different scripts called OBV Oscillator may use different definitions, so compare the source before comparing values.

The copy below fixes source to close and N to 20. There are no input controls. It draws one opaque teal line and a dashed zero reference. It contains no divergence detector, markers, alert conditions, trade orders, or timeframe requests.

TradingView documents the original OBV calculation and Granville’s 1963 publication. That history does not establish that this particular rolling-sum oscillator was invented in 1963.

A positive oscillator with a negative signed-volume sum

Use N = 3 for a short hypothetical calculation. Begin with a settled sequence of contributions −100, so S and E both equal −300 and O is zero. Each new contribution displaces the oldest one; alpha is 0.5. These are invented volume units, not market observations.

Rolling window and EMA calculated separately
StepNew qRemoved qSEO
120-100-180-24060
2-80-100-160-20040
3-120-100-180-19010
4-2020-220-205-15

At step 1, O is +60 although the rolling sum is −180. At step 2, the new contribution is negative, yet S rises because an even more negative observation leaves the window. O remains positive at +40. Neither result proves net buying or an increase in current price.

For complete windows, S[t] − S[t−1] = q[t] − q[t−N]. This expiry effect explains why watching only the newest volume bar is insufficient. At step 4, O crosses below zero because S falls below E; S was already negative on every row.

Zero-centered does not mean bounded or guaranteed to revert

The output retains volume units. Scaling every volume observation by a positive factor scales S, E, and O by that factor on matching history and initialization. There is no fixed upper or lower bound comparable to RSI or MFI. A reading of 500 on two feeds is not automatically comparable.

If every contribution is +100 for a settled complete window, S becomes 100 × N and O approaches zero while cumulative OBV continues increasing by 100 each bar. Conversely, if S keeps rising at a constant rate, an EMA can retain a persistent lag and O can stay positive. Subtracting an EMA removes a constant component; it does not prove a stochastic mean-reverting process or require frequent zero crossings.

At N = 1, EMA(S, 1) equals S wherever valid, so O is zero. A shorter length therefore does not universally increase crossover frequency. Changing N changes both the rolling sum and EMA, not just a smoothing knob. Twenty daily bars are twenty sessions or observations, not a fixed calendar month.

Missing volume and live-bar behavior

The exact source uses zero times volume on an equal-price bar. With missing volume, that expression remains missing rather than becoming a fabricated zero. Pine’s math.sum ignores missing source observations and counts N non-missing values, so a window can span more than N chart bars. The helper has no explicit validity flag, no feed-quality warning, and no custom reset rule.

A missing price comparison takes the fallback branch; with valid volume, that produces zero. Thus the script does not strictly reject every invalid price pair. Decide whether to preserve these built-in semantics or require consecutive valid observations before adapting it.

Reported zero volume is a numeric observation. A zero-filled feed can yield zero values without proving an absence of trading pressure. Tick volume counts price updates rather than traded quantity. Confirm symbol, venue, session, and volume units against TradingView’s volume-data limitations.

Current price direction and accumulated volume change during an open bar. If price crosses the previous close, its entire current volume contribution can change sign. The plotted line is live; the script has no bar-close gate. Read the math.sum reference and repainting documentation when defining an adaptation.

Make divergence and timeframe rules explicit

A value above zero is a state. Crossing above zero is an event that also depends on the previous value. A change in slope is a third condition. The example only plots O; none of these events creates an alert automatically.

For divergence, specify whether price pivots select the comparison bars or whether oscillator pivots do. Set left and right confirmation bars, acceptable pivot spacing, equality rules, and the earliest bar on which the signal can be known. A pivot confirmed several bars later cannot be treated as an entry known on the earlier swing bar.

Two calls with lengths 20 and 14 still run on the same chart timeframe. They do not produce daily and hourly data by themselves. A multi-timeframe adaptation needs explicit data requests and a documented policy for the unclosed higher-timeframe bar.

Additional volume or trend filters are hypotheses to test, not established improvements in win rate. Define entries, exits, sizing, fees and slippage; separate the parameter-selection sample from later evaluation. No reliable signal frequency, reversal percentage, or preferred market is established by this formula.

Compare the information each volume indicator uses

OBV accumulates signed volume without the rolling subtraction. This oscillator measures a rolling sum relative to its EMA. MFI uses typical-price direction and price-times-volume flows to form a bounded ratio when its inputs and denominators are valid.

These are different transformations of price and reported volume, not independent observations of who traded. Agreement between them does not establish causation or a performance ranking. Check calculations on the same feed before adding trading interpretations.

Pine Script v6: implementation and limits

The complete source below preserves the local helper and its fixed length. Paste it into a new TradingView indicator and inspect the values. The label-count allowance does not create labels; no labels or alerts are implemented.

Pine Script v6
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Pineify

//@version=6
indicator(title="On Balance Volume Oscillator", overlay=false, max_labels_count=500)

p_ta_obv_oscillator(series float src, simple int length) =>
    change = ta.change(src)
    obv = math.sum(change > 0 ? volume : change < 0 ? -volume : 0*volume, length)
    obv_osc = obv - ta.ema(obv, length)
    obv_osc

p_ind_1 = p_ta_obv_oscillator(close, 20) // OBV Oscillator
plot(p_ind_1, title="OBV Oscillator", color=color.rgb(0, 188, 212, 0), linewidth=2)
hline(0, "Zero Line", color=color.gray, linestyle=hline.style_dashed)
Existing indicator chart preview
Existing visual preview. Verify exact values against the source; the image is not a performance result.

Specify a checkable adaptation in Pineify

Ask for an explicit rolling signed-volume sum minus its EMA, then specify length, source, missing-data policy, and whether signals require a closed bar. Keep S, E, and O visible while checking the four-row synthetic example. If adding divergence or another timeframe, define confirmation timing before testing a trading rule.

Open Pine Script AI Coding Agent

Educational indicator analysis. No measured trading performance is established here. Syntax validation does not prove formula equivalence, execution assumptions or profitability.

Implementation questions

No. It means the rolling signed-volume sum is above its EMA. The sum can still be negative, and total volume does not identify trade initiators or institutions.

No. It is zero-centered but retains volume units. Scaling all valid volume observations scales the output, so there is no fixed RSI-like range.

Yes. An older, more negative contribution can leave the rolling window. Compare both the entering and expiring observations.

No. The final call fixes close and length 20. Edit the call or add validated inputs in an adaptation.

No. Length changes both the rolling sum and EMA. At length 1, their difference is zero wherever valid, which disproves that universal claim.

No. It has one plotted oscillator and a zero reference. Divergence needs explicit pivot rules; different lengths alone do not request different timeframes.

A missing volume contribution remains missing. math.sum counts non-missing observations, so the lookback can span extra chart bars. This helper does not provide a separate validity warning.