TradingView indicators

Chaikin Oscillator on TradingView

The Chaikin Oscillator is the fast EMA of the accumulation/distribution line minus its slow EMA, commonly using 3 and 10 bars. It measures ADL momentum. It is neither the ADL itself nor the rolling volume ratio used by Chaikin Money Flow.

Use the calculation table and Pine Script below to check individual bars, EMA initialization and data gaps before turning a zero cross into a strategy rule.

Chaikin Oscillator formula

Marc Chaikin's oscillator starts with the close's position inside the current bar. The multiplier is +1 at the high, 0 at the midpoint and -1 at the low when the range is nonzero.

MFM = ((close - low) - (high - close)) / (high - low)

MFV = MFM × volume

ADL = previous ADL + MFV

CO = EMA(ADL, fast) - EMA(ADL, slow)

For length N, the EMA recurrence uses α = 2 / (N + 1): current EMA = α × current ADL + (1 - α) × previous EMA. Both averages must use the same ADL series and a documented starting rule.

Formula reference: TradingView's Chaikin Oscillator documentation. Zero-range handling and gap resets below are explicit choices in this example.

A four-bar audit of the 3/10 calculation

This is synthetic OHLCV data, not a market result. Start ADL at zero and seed both EMAs with the first ADL value of 50, matching the script. The fast weight is 1/2 and the slow weight is 2/11. Calculations retain full precision; the table rounds to three decimals.

BarH / L / CVolumeMFMMFVADLEMA 3EMA 10Raw CO
112 / 8 / 111000.5505050.00050.0000.000
212 / 8 / 9100-0.5-50025.00040.909-15.909
312 / 8 / 12100110010062.50051.65310.847
410 / 10 / 101000 (policy)010081.25060.44320.807

At bar 3, the fast EMA is 0.5 × 100 + 0.5 × 25 = 62.5. The slow EMA is (2/11) × 100 + (9/11) × 40.90909 = 51.65289. Their difference changes sign even though ADL does not need to cross zero.

Bar 4 adds no flow, but the two EMAs keep approaching ADL at different speeds, so CO changes. These are internal audit values: the script hides plotted CO for the first nine valid bars at the default slow length of 10. That warm-up is a chosen minimum, not proof that initialization effects have disappeared.

Inputs and data policy

InputDefaultConstraint and effect
Fast EMA length3Integer ≥ 1, smaller than slow. Controls the faster ADL average.
Slow EMA length10Integer ≥ 2, larger than fast. Also sets the number of valid bars before plotting resumes.
Bar conditionThis script doesWhat to check
High equals lowSet MFM to zero; retain the bar in the EMA sequence.No close location can be inferred from a zero range.
Volume is zeroAdd zero MFV; update both EMAs.Zero is a supplied value. It is different from unavailable volume.
Missing/negative volume or invalid HLCReset ADL and both EMAs; show a gap and orange shading.After data returns, seed a new segment and wait slowLength valid bars.
No bar exists during a closed sessionNo execution and no reset.A scheduled market closure is not an explicit na bar.
Fast length ≥ slow lengthStop with an input error.Equal lengths produce zero; reversed lengths invert the intended sign.

This reset policy avoids silently assigning invented flow to missing data. It also gives up continuity across that gap. Compare feeds and session settings before comparing oscillator values; tick volume counts price updates and is not traded quantity. TradingView explains volume availability by feed.

Copy the Chaikin Oscillator Pine Script

Paste this standalone indicator into TradingView's Pine Editor and add it to the chart. It exposes the two lengths, a zero reference, confirmed cross markers and audit values in the Data Window. Manual EMA recurrence makes the reset and seed policy visible in the code.

Pine Script v6
//@version=6
indicator("Chaikin Oscillator with data checks [Pineify]", overlay=false)

fastLength = input.int(3, "Fast EMA length", minval=1)
slowLength = input.int(10, "Slow EMA length", minval=2)
if fastLength >= slowLength
    runtime.error("Fast EMA length must be smaller than slow EMA length.")

invalidBar = na(high) or na(low) or na(close) or high < low or close > high or close < low or na(volume) or volume < 0
multiplier = high == low ? 0.0 : (2.0 * close - high - low) / (high - low)
var float adl = na
var float fastEma = na
var float slowEma = na
var int validBars = 0

// Missing data starts a new segment; it is never silently replaced by zero volume.
if invalidBar
    adl := na
    fastEma := na
    slowEma := na
    validBars := 0
else
    adl := nz(adl, 0.0) + multiplier * volume
    fastAlpha = 2.0 / (fastLength + 1)
    slowAlpha = 2.0 / (slowLength + 1)
    fastEma := na(fastEma) ? adl : fastAlpha * adl + (1.0 - fastAlpha) * fastEma
    slowEma := na(slowEma) ? adl : slowAlpha * adl + (1.0 - slowAlpha) * slowEma
    validBars += 1

ready = validBars >= slowLength
co = ready ? fastEma - slowEma : na
crossUp = ta.crossover(co, 0.0)
crossDown = ta.crossunder(co, 0.0)
confirmedUp = barstate.isconfirmed and crossUp
confirmedDown = barstate.isconfirmed and crossDown

plot(co, "Chaikin Oscillator", color=color.blue, linewidth=2, style=plot.style_linebr)
hline(0, "Zero", color=color.gray)
bgcolor(not ready ? color.new(color.orange, 85) : na, title="Invalid data or warm-up")
plot(adl, "ADL audit", display=display.data_window)
plot(fastEma, "Fast EMA audit", display=display.data_window)
plot(slowEma, "Slow EMA audit", display=display.data_window)
plotshape(confirmedUp, "Confirmed cross up", shape.triangleup, location.bottom, color.green, size=size.tiny)
plotshape(confirmedDown, "Confirmed cross down", shape.triangledown, location.top, color.red, size=size.tiny)
alertcondition(confirmedUp, "CO crossed above zero", "Chaikin Oscillator crossed above zero at bar close.")
alertcondition(confirmedDown, "CO crossed below zero", "Chaikin Oscillator crossed below zero at bar close.")
OutputMeaning
Blue lineFast minus slow EMA, after the selected warm-up.
Gray zero lineThe two EMA values are equal here.
Green / red triangleA cross above / below zero confirmed at bar close. It is not an order.
Orange backgroundInvalid data or fewer than slowLength consecutive valid bars.
Data Window audit fieldsADL and both EMA states, including warm-up values.

The open-bar line can change as price and volume update. Markers and alert conditions use barstate.isconfirmed. Create an alert from the desired condition in TradingView. Closing-bar confirmation does not validate the trading hypothesis or prevent later data revisions. Pine bar-state reference.

Read zero crosses without confusing CO, ADL and CMF

MeasureCalculationInterpretation boundary
ADLCumulative MFVIts absolute starting level is not a buy/sell threshold.
Chaikin OscillatorFast ADL EMA minus slow ADL EMAPositive means fast exceeds slow. It has no fixed upper or lower limit.
Chaikin Money FlowRolling sum(MFV) / sum(volume)A volume-normalized window ratio; its thresholds do not transfer to CO.

A rising negative CO means the EMA gap is narrowing while fast remains below slow. A positive CO does not establish positive flow on the current bar. It also does not measure actual cash entering an asset. CO's zero cross compares two ADL averages, whereas a MACD signal-line cross compares MACD with its own smoothed signal.

The close-location formula ignores the previous close. For example, after a previous close of 20, a bar with high 12, low 8 and close 11 contributes positive MFV despite the price drop. Price gaps and gaps in available data are separate issues.

  1. Audit a clean interval against TradingView's built-in CO using the same feed, session, timeframe and lengths. Check ADL, then each EMA before comparing the final difference.
  2. Inspect initialization and missing bars when values differ. This example's explicit reset policy can intentionally differ from the built-in series.
  3. Define pivots and their confirmation delay before adding divergence rules. A visual disagreement alone is not a timed entry.
  4. Test entry candidates with separately defined exits, position size, commission and slippage. Repeated zero crosses can occur without a lasting price move.

See the ADL guide and CMF guide for their separate calculations. Educational material; no return or signal accuracy is implied.

Turn the audit into a Pineify coding request

Use Pine Script AI Coding Agent to specify input constraints, confirmation timing and the missing-data policy. Keep the generated source open for review and compare its bar values before adding strategy orders.

Create a Pine v6 Chaikin Oscillator with fast 3 and slow 10 inputs. Require fast < slow. Use zero MFV for zero-range bars. Reset ADL and EMA states on missing volume, hide CO until 10 valid bars resume, and mark zero crosses only at bar close. Expose ADL and both EMAs in the Data Window. Keep exits and costs separate.
Open Pine Script AI Coding Agent

Chaikin Oscillator questions

It compares a fast and a slow EMA of the accumulation/distribution line. The result describes momentum in that price-and-volume proxy. A positive reading means the fast EMA is higher; it does not prove that institutions are buying or that price will rise.

The common setup uses 3 bars for the fast EMA and 10 for the slow EMA. Lengths count chart bars, so a 10-bar EMA on a five-minute chart has a different time scale from a 10-bar EMA on a daily chart. This page does not establish a best setting or timeframe.

No. CO subtracts two EMAs of cumulative ADL. CMF divides the sum of money flow volume by total volume over a rolling window. CMF is normalized; CO has no fixed bounds. A CMF threshold such as 0.05 is not a portable CO threshold.

No. The oscillator reaches zero when its fast and slow ADL averages are equal. ADL itself can be positive or negative at that point. A change of sign also says nothing by itself about the price crossing a moving average.

The script resets on missing or invalid price or volume data and hides the oscillator until the slow-length number of valid bars has accumulated again. Orange shading identifies unavailable or warming-up output. This explicit policy can differ from the built-in indicator around gaps and at the start of history.

Check the particular symbol and feed. Some symbols lack volume and some provide tick volume, which counts price updates rather than traded units. Crypto volume may describe one venue. The code accepts supplied nonnegative volume; it cannot verify its economic meaning or completeness.

The current oscillator value can move while the bar is open. Markers and alert conditions require the bar to close. Data-provider revisions can still change history. This is an indicator with alert conditions; it has no orders, exits, position sizing, fees or backtest results.

Sources and calculation notes

Official references checked October 17, 2026. The synthetic table and gap-handling policy are this page's worked example, not measured trading performance.