Skip to content

Volume indicators

These functions need volume as well as price. Check that your instrument supplies meaningful volume; a field full of zeros or a different kind of volume changes the interpretation.

VWAP

vwap() returns the cumulative volume-weighted typical price, where typical price is (high + low + close) / 3. It accumulates over the history supplied to the calculation. It does not automatically restart at the opening of each trading session.

vwap(20) instead uses a rolling 20-bar window. Both return a price-level series. The explicit forms are vwap(bars) and vwap(bars, 20).

close > vwap()
close > vwap(20)
vwap(20) > vwap(20)[1]

The first and second tests can give different results because they use different windows. For an intraday rule that requires a session-anchored VWAP, do not assume the empty call provides that anchor. A cumulative value also depends on how much earlier history was supplied.

VWMA

vwma(bars, 14) returns the rolling volume-weighted average of close, using 14 bars by default after explicit bars. This differs from VWAP's typical-price input. Both results are prices.

close > vwma(bars, 14)

Keep bars explicit: vwma(14) is not a supported shorthand. Its positional settings are input, period, close column, volume column; normal strategy use needs only the first two.

OBV

obv() returns On-Balance Volume: add volume when close rises, subtract it when close falls, and leave the total unchanged on equal closes. It has no period argument and returns a cumulative series in volume units.

obv() > obv()[1]
close > sma(20) and obv() > obv()[1]

A rising OBV means the latest update increased that cumulative total. Its absolute level depends on the start of history, so a universal threshold such as 1,000 is not comparable across instruments and datasets. obv(20) does not mean a 20-bar OBV; it would put a number into a column-name position. Use obv(bars) for explicit input.

MFI

mfi(14) returns Money Flow Index, a 0–100 series built from typical-price changes and volume. Its default period is 14, and mfi() uses that default. mfi(bars, 14) is explicit.

mfi(14) < 20
mfi(14) > 80

The period controls the calculation window; 20 and 80 are example thresholds you choose. MFI is volume-sensitive and is not interchangeable with close-based RSI. Early or zero-flow windows can be initialised rather than fully populated; supply the intended lookback before relying on a threshold.

CMF

cmf(20) returns Chaikin Money Flow, a dimensionless ratio normally between −1 and 1 for ordinary OHLC data with non-negative volume. It combines close's location in each high–low range with that bar's volume. Default period: 20; cmf() and cmf(bars, 20) are accepted.

cmf(20) > 0
cmf(20) > 0.1

A threshold of 0.1 is a ratio of 0.1, not a 0–100 oscillator reading of 10. Positive readings indicate closes weighted toward the upper part of their ranges over the window. A zero-volume window is filled with 0 in this implementation; it is not evidence of balanced trading activity.

Force Index

force_index(13) smooths one-bar close change × volume with an EMA. Its default smoothing period is 13; force_index() and force_index(bars, 13) are accepted. It returns a series in price-times-volume units.

force_index(13) > 0
force_index(13) > force_index(13)[1]

The first condition checks the sign; the second checks whether the smoothed reading increased. Its magnitude depends on the instrument's price and volume scales, so a fixed absolute threshold does not transfer cleanly across instruments.

For plain volume relative to its recent average, use volume > mean(volume, 20); series helpers explain that scalar mean and its warmup behaviour.