TradingView indicator guides

VAPI: Volume-Weighted Close Location and CMF

VAPI averages each bar's closing position within its high-low range, weighted by volume, and multiplies the result by 100. It is a price-and-volume proxy, not a measurement of buyer-initiated trades, institutional money or net cash entering an asset. With matching windows and data handling, it is 100 times Chaikin Money Flow.

Inspect the Pine Script

Trace the numerator and denominator

For a nonzero bar range, x = (2C − H − L)/(H − L). A close at the high gives +1, at the low gives −1, and at the midpoint gives 0. Sum volume × x over N bars, divide by the volume sum over the same bars, then multiply by 100.

For valid H ≥ C ≥ L, nonnegative volumes and a positive total, VAPI is a weighted mean bounded by −100 and +100. A reading of +60 means that weighted close-location mean is +0.60. It does not mean 60% of trades were buys, a 60% gain, or a 60% chance of success. Each trade has a buyer and seller; this code contains no trade-side classification or participant identity.

The copied helper assigns x = 0 when H = L. That bar's volume remains in the denominator, so it can dilute the result toward zero. A doji with open equal to close can still have a nonzero high-low range; doji is not a synonym for a zero-range bar. Open is not used by this formula.

A three-bar calculation with a flat bar

Use N = 3 for this hypothetical calculation. The copied example below fixes N at 10; edit that argument in a separate diagnostic copy to reproduce this table.

BarH / L / CVolumexVolume × x
A110 / 100 / 108100+0.6+60
B109 / 99 / 101200−0.6−120
C105 / 105 / 1053000 by policy0

Weighted sum = −60, total volume = 600, so VAPI = −10. Excluding C's volume would give −20, but that is not what this helper does. The denominator policy matters even though C adds zero to the numerator.

Multiplying every volume in this table by ten leaves VAPI at −10. A higher total volume therefore need not mean a larger reading. Changing only one bar's volume changes its relative weight; this cannot identify whether the trades were institutional, retail or wash trades.

For another isolated example, a previous close of 110 followed by H = 100, L = 90, C = 99 gives x = +0.8 despite the close-to-close decline. A next bar H = 90, L = 80, C = 89 also gives +0.8 while price falls again. A two-bar VAPI would be +80 for any positive volumes on those two bars. Positive close location can coexist with a price downtrend.

VAPI and Chaikin Money Flow share the formula

TradingView's CMF definition uses [(C−L)−(H−C)]/(H−L), which simplifies exactly to x above. Both sum the same weighted volumes and divide by total volume. On matching data, lookback and flat/missing/zero-volume policies, VAPI = 100 × CMF. Their zero crossings are then identical, and +60 VAPI corresponds to +0.60 CMF.

Default lengths, special-bar guards or data sources can differ between implementations. Check those before comparing output; scaling alone cannot make VAPI lead CMF or supply independent confirmation. See the CMF guide for its specific contract.

OBV instead accumulates signed volume based on close-to-close direction. It can fall on the gap-down example even though the VAPI contribution is positive. Neither method directly observes aggressor-side volume or money flows into investor accounts.

Know this script's actual controls and boundaries

The published call is p_ta_vapi(10). It exposes no Settings input for length, even though the helper accepts a length argument. The histogram is teal for nonnegative values and red for negative ones; two area plots separate the positive and negative parts. A zero-height teal value is not evidence of buying.

When the total volume sum is zero the helper returns zero by explicit convention. This does not mean measured buying and selling were balanced. Missing volume is not the same as zero volume; there is no explicit consecutive-valid-data gate, negative-volume check or full OHLC validation. Check the underlying feed and unavailable values before using a zero or missing reading as a signal.

The lookback counts chart bars. The script uses the chart's available volume, which can be trade volume, tick activity or unavailable depending on instrument and provider. An exchange name, asset class or market-cap rank does not guarantee data quality or comparability. Rescaling volume units uniformly cancels in the ratio; changing the underlying activity being counted does not.

The current close, high, low and volume can change on an open bar. This script has no bar-close gate, alerts, pivot detection, multi-timeframe request or orders. A cross, divergence or confirmed signal needs additional rules. Specify pivot confirmation timing, and do not place a backtest entry on an earlier pivot bar using information learned later.

Source and a reproducible test

LazyBear's public VAPI script was published April 11, 2015 with a length input defaulting to 10. Its public formula directly divides by the bar range and total volume. The helper below adds zero-range and zero-total guards and uses a fixed call; its plotting also differs. Do not assume exact equality on exceptional bars.

For a diagnostic version, expose x, the weighted-volume sum and total volume. Reproduce the table, then compare with a CMF calculation on the identical bars. Include a zero-range positive-volume bar, all-zero volume and missing data as separate cases. This is a formula comparison, not a performance test.

If you test trades, define the precise event, confirmation, entry price, exits, size and costs first. Compare filters on a separate period; filtering out trades does not prove fewer losing trades or better returns. No universal best timeframe, profitable threshold or measured win rate is established here. Platform timing reference: TradingView repainting documentation.

Pine Script v6: implementation and limits

This complete helper-based example fixes the lookback at ten chart bars. It draws a histogram and positive/negative areas with a zero reference. It does not expose inputs or create alerts or strategy orders. The unused p_custom_sources helper does not alter the calculation.

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/
// (c) Pineify

//@version=6
indicator(title="Volume Accumulation Percentage Indicator", overlay=false, max_labels_count=500)

p_custom_sources() =>
    [open, high, low, close, volume]

p_ta_vapi(simple int length) =>
    x = high == low ? 0 : (2 * close - high - low) / (high - low)
    tva = math.sum(volume * x, length)
    tv = math.sum(volume, length)
    va = tv == 0 ? 0 : 100 * tva / tv
    va

p_ind_1 = p_ta_vapi(10)

hline(0, title="VAPI - Zero", color=#787B86, linewidth=1)
plot(p_ind_1, title="VAPI", style=plot.style_histogram, color=p_ind_1 >= 0 ? color.rgb(38, 166, 154, 0) : color.rgb(239, 83, 80, 0))
plot(p_ind_1 >= 0 ? p_ind_1 : 0, title="VAPI - Positive", color=color.new(color.rgb(38, 166, 154, 0), 50), style=plot.style_area)
plot(p_ind_1 < 0 ? p_ind_1 : 0, title="VAPI - Negative", color=color.new(color.rgb(239, 83, 80, 0), 50), style=plot.style_area)

Specify a checkable adaptation in Pineify

Pineify's Visual Editor exposes VAPI Time Periods (default 10), one VAPI output, histogram selection and drawing colors. The standalone copy below is a fixed configuration. Ask the AI Coding Agent to add a length input, explicit missing-volume handling or a closed-bar event while preserving the stated zero-range convention. Check the generated code and numerical values before use; product access follows the current plan.

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 weights each bar’s volume by closing location in its range. It does not classify trade aggressors, identify institutions or track cash transfers.

With identical bars, length and exceptional-data policies, this formula is 100 times CMF. Their zero crossings match. Different default lengths or missing-value handling can change results.

For H=L this helper gives the bar zero weighted contribution, but its volume remains in the denominator. Positive flat-bar volume can dilute the ratio toward zero.

Yes. A gap-down bar can close near its own high. The calculation uses current high-low location, not previous close direction.

No. Its call fixes length at 10. The Pineify Visual Editor separately exposes a Time Periods input; an editable standalone script needs an input added and validated.

If the summed volume is zero, this helper returns zero by convention. That is not evidence of balanced trading; missing data must be examined separately.