Data Analytic Investments
Volume & PriceBeginner

VWAP

Volume-Weighted Average Price

The institutional benchmark price — the single most-watched intraday level by professional traders.

5m, 15m, 1H (intraday)
Crypto, Equities, Futures
Pine Script v5

What is it?

VWAP is the cumulative sum of (price × volume) divided by cumulative volume, calculated from the start of the trading session. It represents the average price at which all transactions have occurred, weighted by volume. Institutional traders use VWAP as a benchmark: buying below VWAP is considered value; selling above VWAP is considered premium. Algorithms are programmed to execute large orders near VWAP to minimise market impact. In crypto, where there is no official session open, VWAP is typically anchored to the UTC midnight open or to a significant price pivot (Anchored VWAP).

Common pitfalls

  • VWAP resets at the start of each session (or UTC midnight for crypto). It is meaningless on daily or weekly charts — it is strictly an intraday tool.
  • Early in the session, VWAP is heavily influenced by the first few candles. It becomes more stable and meaningful as the session progresses.
  • In crypto's 24/7 market, the choice of anchor point for VWAP is subjective. Different anchor points produce different VWAP levels — always specify your anchor.
  • VWAP is a lagging indicator on short timeframes — it reflects where price has been, not where it is going.
  • Wash trading on crypto exchanges inflates volume, which distorts VWAP. On-chain volume data is more reliable than exchange-reported volume for VWAP calculations.

Free code template

Paste directly into TradingView Pine Editor → Add to chart.

Pine Script v5
/indicator("VWAP + Bands — DAI Template", overlay=true)

showBands = input.bool(true, "Show SD Bands")
sd1Mult   = input.float(1.0, "Band 1 Multiplier", step=0.25)
sd2Mult   = input.float(2.0, "Band 2 Multiplier", step=0.25)

vwapVal = ta.vwap(hlc3)

// Standard deviation bands
variance = ta.stdev(hlc3, 20) * ta.stdev(hlc3, 20)
stdDev   = math.sqrt(variance)

upper1 = vwapVal + stdDev * sd1Mult
lower1 = vwapVal - stdDev * sd1Mult
upper2 = vwapVal + stdDev * sd2Mult
lower2 = vwapVal - stdDev * sd2Mult

pVwap = plot(vwapVal, "VWAP", color=#6366f1, linewidth=2)
pU1   = plot(showBands ? upper1 : na, "Upper 1", color=color.new(#6366f1, 50), linewidth=1)
pL1   = plot(showBands ? lower1 : na, "Lower 1", color=color.new(#6366f1, 50), linewidth=1)
pU2   = plot(showBands ? upper2 : na, "Upper 2", color=color.new(#ef4444, 60), linewidth=1)
pL2   = plot(showBands ? lower2 : na, "Lower 2", color=color.new(#22c55e, 60), linewidth=1)
fill(pU1, pL1, color.new(#6366f1, 94))

aboveVwap = close > vwapVal
belowVwap = close < vwapVal
bgcolor(aboveVwap ? color.new(#22c55e, 97) : color.new(#ef4444, 97))

alertcondition(ta.crossover(close, vwapVal),  "Price Crossed Above VWAP", "Bullish VWAP cross")
alertcondition(ta.crossunder(close, vwapVal), "Price Crossed Below VWAP", "Bearish VWAP cross")