What it measures
VWAP is the average price paid for an instrument since a starting point, weighted by volume. A bar with heavy volume pulls the average towards its price much more than a quiet bar does. The result is a running estimate of the "fair" price of the session: where most of the volume changed hands.
It's mainly an intraday tool. The standard version resets at the start of each trading day, so it answers a specific question: is price currently above or below the average price traded today?
The formula in words
- For every bar, take a typical price, usually (high + low + close) ÷ 3.
- Multiply it by the bar's volume.
- Keep a running total of those products and a running total of volume since the anchor (the session open, or the start of the week or month).
- VWAP = running total of price × volume ÷ running total of volume.
- For bands, compute the volume-weighted standard deviation of price around VWAP and add or subtract a multiple of it.
Everything restarts at the next anchor. That's why VWAP starts each session at the first bar's typical price and becomes steadier as the day goes on and more volume accumulates.
How traders read it
- Bias. Price above VWAP means buyers have paid up relative to today's average; below means the opposite. Many intraday traders only look for longs above VWAP and shorts below it.
- Reactions at VWAP. Pullbacks to VWAP during a trending session are watched as possible continuation areas; repeated crossings of VWAP suggest a balanced, rangebound day.
- Execution benchmark. Institutions measure fills against VWAP, which is one reason the level gets attention.
- Deviation bands. Moves to the second band are stretched relative to the session's distribution, and are used both as targets and as mean-reversion zones.
- Weekly and monthly anchors. Anchoring to the start of the week or month gives a slower reference level that swing traders use.
Common settings
| Setting | Typical value | Notes |
|---|---|---|
| Anchor | Session (daily) | Week or month for swing traders. |
| Source | hlc3 | The typical price. Close-only versions exist. |
| Bands | 1 and 2 standard deviations | Some traders add a third band. |
| Timeframe | 1 to 15 minutes | On daily bars a session VWAP collapses to a single bar's price. |
Check the market hours tool to see when sessions open in your time zone. For forex and other 24-hour markets, the "session" boundary is a convention set by the data feed.
Pine Script v6 code
The complete, self-contained script is below. Copy it into a new indicator in TradingView's Pine Editor, or download the .pine file.
//@version=6
indicator("Anchored VWAP with deviation bands", shorttitle = "VWAP", overlay = true)
anchor = input.string("Session", "Reset every", options = ["Session", "Week", "Month"])
src = input.source(hlc3, "Source")
mult1 = input.float(1.0, "Band 1 (x stdev)", minval = 0.1, step = 0.1)
mult2 = input.float(2.0, "Band 2 (x stdev)", minval = 0.1, step = 0.1)
anchorTf = anchor == "Week" ? "W" : anchor == "Month" ? "M" : "D"
newPeriod = timeframe.change(anchorTf)
vol = nz(volume)
totalVol = ta.cum(vol)
var float sumPV = 0.0
var float sumV = 0.0
var float sumPV2 = 0.0
if newPeriod
sumPV := 0.0
sumV := 0.0
sumPV2 := 0.0
sumPV += src * vol
sumV += vol
sumPV2 += src * src * vol
vwapValue = sumV > 0 ? sumPV / sumV : na
sd = sumV > 0 ? math.sqrt(math.max(sumPV2 / sumV - vwapValue * vwapValue, 0)) : na
// Hide the first bar of each period so the line breaks at the reset instead of jumping.
show = not newPeriod
plot(show ? vwapValue : na, "VWAP", color = color.new(color.orange, 0), linewidth = 2, style = plot.style_linebr)
u1 = plot(show ? vwapValue + mult1 * sd : na, "Upper 1", color = color.new(color.gray, 30), style = plot.style_linebr)
l1 = plot(show ? vwapValue - mult1 * sd : na, "Lower 1", color = color.new(color.gray, 30), style = plot.style_linebr)
plot(show ? vwapValue + mult2 * sd : na, "Upper 2", color = color.new(color.gray, 60), style = plot.style_linebr)
plot(show ? vwapValue - mult2 * sd : na, "Lower 2", color = color.new(color.gray, 60), style = plot.style_linebr)
fill(u1, l1, color = color.new(color.orange, 92), title = "Band 1 fill")
crossAbove = ta.crossover(close, vwapValue)
crossBelow = ta.crossunder(close, vwapValue)
alertcondition(crossAbove, "Close above VWAP", "{{ticker}} closed above VWAP ({{interval}})")
alertcondition(crossBelow, "Close below VWAP", "{{ticker}} closed below VWAP ({{interval}})")
if barstate.islast and totalVol == 0
runtime.error("This symbol has no volume data, so VWAP can't be calculated.")The script accumulates price × volume, volume and price² × volume from each anchor and derives VWAP and its standard deviation from those three sums, which is exactly the formula above written out. Choose the reset (session, week or month) in the settings; two pairs of deviation bands are drawn, with the inner pair shaded.
It stops with a clear error message on symbols that have no volume data, such as some indices and spot forex feeds, rather than drawing a meaningless line.
Add it to your chart
- Open any chart on TradingView and open the Pine Editor.
- Create a new indicator, delete the template code and paste the script.
- Click Save, then Add to chart. Change lengths and levels from the indicator's settings.
Stuck on an error? See how to add a Pine Script indicator to TradingView.
Pitfalls
- No or partial volume. Spot forex and CFD feeds often report tick volume (number of price changes), not traded volume. VWAP still draws, but it is weighted by activity rather than by real size.
- Using a session VWAP on daily bars. Each daily bar is its own session, so the line just follows the bar's typical price. Use intraday charts, or a weekly or monthly anchor.
- Early-session noise. In the first minutes VWAP rests on very little volume and moves a lot. It becomes more meaningful as the session builds.
- Session definition. Extended-hours data and 24-hour markets change where the "day" begins. Check that the reset happens where you expect on your chart.
Related reading
- Pine Script repainting: how to spot it, test for it and fix it
- Pine Script alerts: alertcondition() vs alert(), messages, webhooks and frequency
- Forex Market Hours (free tool)
- Position Size Calculator (free tool)
The script is an educational example: test it on your own markets before relying on it. Indicators describe the past; they don't predict the future. Trading involves substantial risk of loss and is not suitable for every investor. Edgoro is a software tool, not a broker or financial adviser: nothing it produces is investment advice, and past or backtested performance does not guarantee future results.