Skip to content

Free TradingView indicator

VWAP Deviation Bands

Session VWAP with three volume-weighted standard deviation bands and signals when price closes back inside a band.

Mean reversionv1.0TradingView (Pine Script v6) Non-repainting signals Alerts

What it does

This indicator plots the session VWAP and three pairs of bands at 1, 2 and 3 volume-weighted standard deviations. The bands show how far price has stretched from the session's average traded price, measured in the session's own units of dispersion.

It also marks re-entries: the bar that closes back inside a chosen band after the previous bar closed outside it. That is a common way to frame a fading or mean-reversion idea, and a way to see when an extended move is losing pace.

How it works

  1. At the first bar of each daily session the calculation restarts.
  2. VWAP = cumulative (source × volume) ÷ cumulative volume since the session start.
  3. Standard deviation = square root of the volume-weighted variance of the source around VWAP since the session start.
  4. Band k = VWAP ± multiplier k × standard deviation, for the three multipliers.
  5. A "re-entry from above" prints when the previous close was above the selected upper band and the current close is at or below it. "Re-entry from below" is the mirror image.
  6. Signals are checked only on closed bars and only after the warm-up bars, because the bands start at zero width and widen as the session develops.

How to use it

In a quiet, two-sided session, moves to the 2 SD band often stall, and a close back inside can be read as a sign that the push is fading. In a strong trend day, price can ride the 1 to 2 SD band for hours. That is why the re-entry signal should be paired with context, such as whether VWAP itself is flat or sloping.

Ways traders use the bands:

  • Flat VWAP plus re-entry from the 2 SD or 3 SD band: a possible fade toward VWAP.
  • Sloping VWAP with price holding between VWAP and the 1 SD band: a trend; pullbacks to VWAP may be more relevant than fades.
  • Band levels as reference points for take-profit targets on intraday trades. See what is a take-profit.

Settings

InputDefaultWhat it changes
Sourcehlc3Price averaged by volume.
Band 1 / 2 / 3 multiplier1.0 / 2.0 / 3.0Distance of each band.
Show band 3onHides the outer band if you prefer a cleaner chart.
Re-entry bandBand 2Which band the signals use.
Ignore first N bars of each session5Warm-up period with no signals.
Show re-entry markersonTriangles on signal bars.

Limitations

  • On spot forex, TradingView volume is typically tick volume from one feed, so VWAP and its bands are an approximation of activity.
  • Fading a band in a trending session can lead to repeated losses. The tool does not detect trend days for you.
  • Standard deviation bands assume nothing about future range; a news release can carry price far beyond 3 SD.
  • The session boundary is the symbol's daily rollover, which may not match the session you trade.
  • Requires an intraday chart and a symbol with volume data.

Pine Script source

In TradingView open Pine Editor, paste the code, click Save and then Add to chart.

FXP_VWAPDeviationBands.pine

80 lines

// © FXPIPS ONLINE — https://fxpips.online/tradingview-indicators/vwap-deviation-bands/
// License: MIT. Educational tool — not financial advice. Trading involves substantial risk.
//@version=6
indicator("FXP VWAP Deviation Bands", shorttitle = "FXP VWAP SD", overlay = true)

// ── Inputs ─────────────────────────────────────────────────────────────
grpV     = "Session VWAP"
src      = input.source(hlc3, "Source", group = grpV)

grpB     = "Deviation bands"
mult1    = input.float(1.0, "Band 1 multiplier", minval = 0.1, step = 0.1, group = grpB)
mult2    = input.float(2.0, "Band 2 multiplier", minval = 0.1, step = 0.1, group = grpB)
mult3    = input.float(3.0, "Band 3 multiplier", minval = 0.1, step = 0.1, group = grpB)
show3    = input.bool(true, "Show band 3", group = grpB)

grpSig   = "Signals"
sigBand  = input.string("Band 2", "Re-entry band", options = ["Band 1", "Band 2", "Band 3"], group = grpSig, tooltip = "A signal prints when a bar closes back inside this band after the previous bar closed outside it.")
warmup   = input.int(5, "Ignore first N bars of each session", minval = 1, group = grpSig, tooltip = "Bands are very narrow right after the session opens; this avoids early noise.")
showSig  = input.bool(true, "Show re-entry markers", group = grpSig)

grpVis   = "Display"
vwapCol  = input.color(color.orange, "VWAP color", group = grpVis)
upCol    = input.color(color.red, "Upper bands color", group = grpVis)
dnCol    = input.color(color.teal, "Lower bands color", group = grpVis)

// ── Calculation ────────────────────────────────────────────────────────
if timeframe.isdwm
    runtime.error("Session VWAP bands need an intraday chart.")

bool newSession = timeframe.change("D")

// With a multiplier of 1, the returned band distance equals one volume-weighted standard deviation.
[sVwap, up1raw, dn1raw] = ta.vwap(src, newSession, 1.0)
float sd = up1raw - sVwap

float u1 = sVwap + mult1 * sd
float l1 = sVwap - mult1 * sd
float u2 = sVwap + mult2 * sd
float l2 = sVwap - mult2 * sd
float u3 = sVwap + mult3 * sd
float l3 = sVwap - mult3 * sd

float sigUp = sigBand == "Band 1" ? u1 : sigBand == "Band 2" ? u2 : u3
float sigDn = sigBand == "Band 1" ? l1 : sigBand == "Band 2" ? l2 : l3

// Bars elapsed since the session started (0 on the first bar).
var int sBars = 0
sBars := newSession ? 0 : sBars + 1

// Re-entry from outside the band, on closed bars, after the warm-up period.
bool ready       = barstate.isconfirmed and sBars >= warmup
bool fadeFromTop = ready and close[1] > sigUp[1] and close <= sigUp
bool fadeFromBot = ready and close[1] < sigDn[1] and close >= sigDn

float cumVol = ta.cum(nz(volume))
if barstate.islast and cumVol == 0
    runtime.error("This symbol provides no volume data, so VWAP cannot be calculated.")

// ── Plots ──────────────────────────────────────────────────────────────
bool hide = newSession
plot(hide ? na : sVwap, "VWAP", color = vwapCol, linewidth = 2, style = plot.style_linebr)
pU1 = plot(hide ? na : u1, "Upper 1", color = color.new(upCol, 50), style = plot.style_linebr)
pL1 = plot(hide ? na : l1, "Lower 1", color = color.new(dnCol, 50), style = plot.style_linebr)
pU2 = plot(hide ? na : u2, "Upper 2", color = color.new(upCol, 25), style = plot.style_linebr)
pL2 = plot(hide ? na : l2, "Lower 2", color = color.new(dnCol, 25), style = plot.style_linebr)
pU3 = plot(hide or not show3 ? na : u3, "Upper 3", color = upCol, style = plot.style_linebr)
pL3 = plot(hide or not show3 ? na : l3, "Lower 3", color = dnCol, style = plot.style_linebr)
fill(pU1, pU2, color = color.new(upCol, 92), title = "Upper 1-2 fill")
fill(pL1, pL2, color = color.new(dnCol, 92), title = "Lower 1-2 fill")
fill(pU2, pU3, color = color.new(upCol, 85), title = "Upper 2-3 fill")
fill(pL2, pL3, color = color.new(dnCol, 85), title = "Lower 2-3 fill")
plot(sd, "1 SD distance", display = display.data_window)

plotshape(showSig and fadeFromTop, "Re-entry from above", shape.triangledown, location.abovebar, upCol, size = size.tiny)
plotshape(showSig and fadeFromBot, "Re-entry from below", shape.triangleup, location.belowbar, dnCol, size = size.tiny)

// ── Alerts ─────────────────────────────────────────────────────────────
alertcondition(fadeFromTop, "Close back inside upper band", "FXP VWAP SD: close back inside the upper deviation band on {{ticker}} {{interval}}")
alertcondition(fadeFromBot, "Close back inside lower band", "FXP VWAP SD: close back inside the lower deviation band on {{ticker}} {{interval}}")

Key inputs

Key inputs of VWAP Deviation Bands
InputDefaultDescription
Sourcehlc3Price averaged by volume.
Band 1 multiplier1.0Inner band distance in standard deviations.
Band 2 multiplier2.0Middle band distance in standard deviations.
Band 3 multiplier3.0Outer band distance in standard deviations.
Re-entry bandBand 2Band used for the close-back-inside signals.
Ignore first N bars of each session5Skips signals while the bands are still very narrow after the session opens.

Educational tools, not advice. Indicators and Expert Advisors describe price; they do not predict it, and past behaviour does not guarantee future results. Test everything on a demo account first and never risk money you cannot afford to lose. See our disclaimer.

Keep exploring

Related tradingview indicators