TradingView indicator comparisons

Volume profile vs VWAP: distribution shape vs weighted mean

Volume profile shows how volume is distributed across price rows; VWAP reduces prices and volumes to one weighted mean at each observation time. Two distributions can have the same VWAP while concentrating volume at different prices. In the complete examples below, both VWAPs are $100, but one profile peaks at $100 and the other peaks at $98 and $102. The mean alone cannot reveal that difference.

See the decision guide

Two profiles, one $100 VWAP

These are invented transaction records for two separate six-trade windows, A and B. Prices are in US dollars and quantities are shares. Each row below is one complete trade in its own window; there are no omitted trades. Both windows begin immediately before trade 1 and end immediately after trade 6. Their identical price sequence isolates the change in volume allocation.

Two volume profiles with a shared VWAP of 100 dollars. A has row volumes 5, 15, 60, 15, 5; B has 40, 5, 10, 5, 40 at prices 98 through 102.
Original diagram of the hypothetical records below. Bar length is shares, both panels use the same scale, and the dashed line marks the final VWAP. View original source
  • Transaction VWAP = sum(price × shares) / sum(shares). A: (490 + 1,485 + 3,000 + 3,000 + 1,515 + 510) / 100 = $100. B: (3,920 + 495 + 500 + 500 + 505 + 4,080) / 100 = $100.
  • This equality holds at the final cutoff. After trade 3, each window has 50 shares, but A has $4,975 of traded value and B has $4,915. Their developing VWAPs are $99.50 and $98.30 respectively.
  • Reordering the records within either window preserves its final VWAP and profile. It can change the developing path. Neither final summary reconstructs the transaction sequence.
Trade orderPriceA sharesA price × sharesB sharesB price × shares
1$985$49040$3,920
2$9915$1,4855$495
3$10030$3,0005$500
4$10030$3,0005$500
5$10115$1,5155$505
6$1025$51040$4,080
Total100$10,000100$10,000

Define the rows before naming the peaks

Use five fixed bins of width $1. Include each lower edge and exclude each upper edge: the first bin is [97.5, 98.5), and the last is [101.5, 102.5). Labels are bin midpoints. Sum the full quantity of each transaction into its containing bin; do not spread a trade across rows. Keep all tied maxima when reporting point of control (POC), rather than silently selecting one.

  • A has a single largest row at $100. B has two equal largest rows at $98 and $102. Here bimodal means two separated maximum-volume rows in this finite sample, including the boundary rows.
  • The VWAP row contains 60% of A volume and 10% of B volume. The two outer rows together contain 10% and 80%. Calling $100 the most traded price would therefore be wrong for B.
  • Volume-weighted variance adds a second summary: sum(shares × (price − VWAP)²) / total shares. A gives (5 × 4 + 15 × 1 + 15 × 1 + 5 × 4) / 100 = 0.7 dollars squared. B gives (40 × 4 + 5 × 1 + 5 × 1 + 40 × 4) / 100 = 3.3 dollars squared. This is descriptive dispersion, not forecast risk or a platform band formula.
  • No value area is calculated here. Its percentage, expansion procedure, tie rules and overshoot policy would be additional choices. They are unnecessary to demonstrate the information lost in the mean.
Price binMidpoint labelA volume / shareB volume / share
$97.50 to below $98.50$985 / 5%40 / 40%: tied POC
$98.50 to below $99.50$9915 / 15%5 / 5%
$99.50 to below $100.50$10060 / 60%: POC10 / 10%
$100.50 to below $101.50$10115 / 15%5 / 5%
$101.50 to below $102.50$1025 / 5%40 / 40%: tied POC

Reproduce the aggregation from the raw records

Run this Python 3 example without external packages. The function uses the declared fixed bins and calculates VWAP directly from transaction prices, before any bin approximation. It reports every POC tie and rejects nonfinite values, negative quantities, out-of-range prices and a zero total. A missing quantity must be resolved at the data source; it is not a zero-volume trade.

  • Multiplying every quantity by the same positive factor leaves VWAP, percentage shares and weighted variance unchanged. It scales the absolute profile bars.
  • Putting all records into one $5 bin [97.5, 102.5) gives a single 100-share bar for both A and B. The shape difference disappears even though the original records remain different. Keep bin boundaries fixed during a comparison.
  • A profile midpoint average only equals transaction VWAP when its within-row approximation happens to preserve traded value. One share at $99.60 belongs to the $100 row, but its transaction VWAP is $99.60, not $100. These examples avoid that approximation because every trade is exactly at a midpoint.
Output order: total shares, traded value, VWAP, row volumes, POC midpoint labels, weighted variance.Python 3
from math import floor, isfinite

A = [(98, 5), (99, 15), (100, 30), (100, 30), (101, 15), (102, 5)]
B = [(98, 40), (99, 5), (100, 5), (100, 5), (101, 5), (102, 40)]

def summarize(trades):
    # Five fixed $1 bins: [97.5, 98.5), ..., [101.5, 102.5).
    rows = [0] * 5
    notional = 0
    for price, quantity in trades:
        if not (isfinite(price) and isfinite(quantity)) or quantity < 0:
            raise ValueError("Prices and quantities must be finite; quantity >= 0")
        row = floor(price - 97.5)
        if not 0 <= row < len(rows):
            raise ValueError("Price outside the declared bins")
        rows[row] += quantity
        notional += price * quantity
    total = sum(rows)
    if total <= 0:
        raise ValueError("VWAP requires positive total volume")
    vwap = notional / total
    # Keep every tied maximum; report bin midpoints as labels.
    pocs = [98 + i for i, volume in enumerate(rows) if volume == max(rows)]
    variance = sum(q * (p - vwap) ** 2 for p, q in trades) / total
    return total, notional, vwap, rows, pocs, variance

assert summarize(A) == (100, 10000, 100.0, [5, 15, 60, 15, 5], [100], 0.7)
assert summarize(B) == (100, 10000, 100.0, [40, 5, 10, 5, 40], [98, 102], 3.3)
print("A:", summarize(A))
print("B:", summarize(B))

Why TradingView can differ from the transaction example

TradingView documents Volume Profile as a calculation from lower-timeframe bars; the selected lower interval depends on the profile tool. Its up/down split uses bar direction, not verified buyer/seller aggressor identity. VWAP uses a selected bar source, with HLC3 as the default, and resets at the chosen anchor period. These chart calculations need not reproduce a transaction-level calculation.

  • Aggregate either sample into one candle: open = 98, high = 102, low = 98, close = 102, volume = 100. Both OHLCV records are identical. HLC3 = (102 + 98 + 102) / 3 = $100.6667, so a one-bar HLC3-volume average differs from the exact $100 transaction VWAP. The original volume distribution cannot be recovered uniquely from this candle.
  • For a chart comparison, record the exchange symbol, volume units, regular or extended hours, timezone, start/end timestamps, profile row boundaries, lower interval, VWAP source and calculation timeframe. Session VWAP resets each session; it does not automatically share the window of a fixed-range or visible-range profile.
  • Read both tools through the same completed bar. A full-session profile viewed after the close contains information unavailable earlier. If evaluating a developing profile, save its rows and VWAP at each historical decision cutoff.
  • TradingView lists trade volume for stocks, tick volume for indices/forex/crypto CFDs, and base or quote volume for crypto. Confirm the actual feed and units. Unknown or unavailable volume prevents an honest volume-weighted comparison.

Choose the question, then write a rule that can fail

Use VWAP when the question is distance from a weighted average. Use a profile when the question concerns concentration across prices. To test how those descriptions differ, freeze the completed sample and evaluate a hypothetical later close of $100.25. It is $0.25 above VWAP in both cases, but it lies inside a row containing 60% of A volume and only 10% of B volume.

  • A specific research filter could require a later confirmed close above the saved VWAP and inside a saved row containing at least 50% of completed-window volume. At $100.25, A passes and B fails. At $101.25, both fail the row-share condition; at exactly $100, neither passes the strict above-VWAP condition. This arbitrary threshold illustrates different classifications, not a validated strategy.
  • The rule needs the saved row edges and volumes, not only a POC line. Define every boundary and freeze the inputs at the cutoff. A close of $100.50 falls into the next row under the stated half-open bins.
  • For a TradingView implementation, give Pine Script AI Coding Agent the chosen bar source, session window, row allocation method and confirmation rule. Ask for clearly labeled OHLCV proxies or manually supplied completed-profile rows. Require it to reject missing data and avoid claiming that OHLCV reveals the original trades.
  • Review generated source and request a syntax check, then compare a few closed-bar outputs by hand. A profitable strategy would additionally require entries, exits, costs, fill assumptions and evaluation on later data. The arithmetic examples establish none of those results.
Where Pineify fits

Pine Script AI Coding Agent

Draft and revise a comparison script from explicit data, row boundaries and confirmation rules. Review any approximation and validate the generated behavior in TradingView.

Draft a profile and VWAP comparison

Frequently asked questions

Educational information, not investment advice. All transaction records and later prices are hypothetical. The calculations are not backtests, observed market data or evidence of returns. Generated scripts and data approximations require independent review.

Sources and verification

Published by Pineify. Pineify is an independent product and is not affiliated with TradingView. Sources support the technical explanations; examples do not establish trading performance.