VWAP with Anchored Std Dev Bands — Volume Drop
# VWAP with Anchored Std Dev Bands — Volume Drop
Anchored VWAP tells you where the volume-weighted crowd is positioned; standard deviation bands around it tell you how dispersed that positioning is. Together you get a fair-value rail with statistical context for how far is "too far" — without forcing an arbitrary lookback window.
## What it does
- Builds a volume-weighted average price anchored to the start of each Session, Week, or Month (your choice).
- Computes a volume-weighted standard deviation from the same anchored data set using the closed-form `Var = E[P²] − (E[P])²`.
- Plots ±1σ, ±2σ, and ±3σ envelopes around the VWAP — they widen as participation disperses and tighten as the auction balances.
- Shades the 2σ–3σ zones as "volatility extremes" so reversion setups jump off the chart.
- Live label shows current VWAP, 1σ, and the full 2σ bandwidth.
## Recommended settings
- **Anchor:** `DAY` for intraday, `WEEK` for swing, `MONTH` for position work.
- **Source:** `hlc3` (typical price) — the canonical volume-weighting input.
- **Band 1 / 2 / 3:** `1.0 / 2.0 / 3.0` — change only if you trade a chronically high- or low-vol instrument.
- **Show ±3σ Band:** `yes` — it's where reversion trades actually live.
- **Shade 2σ–3σ Cloud:** `yes` — visual cue for the volatility-extreme zone.
## Ideal timeframe
1m–5m for `DAY` anchor on US equity index futures; 15m–1h for `WEEK`; daily for `MONTH`.
## How to use
Treat the anchored VWAP as fair value and the ±1σ band as the "normal" trading envelope. Touches of ±2σ during regular auction (no news, no halt) are statistical extremes — most fade back to the mean. Touches of ±3σ are rarer and usually signal a regime change rather than a fade. Use VWAP reclaims/losses as bias flips, and 2σ extensions as either profit targets (if you entered near the VWAP) or fade entries with a stop beyond the 3σ band.
## thinkScript code
```
# ─────────────────────────────────────────────
# │ MarketFragments.com | DNA & Market │
# │ info@marketfragments.com │
# │ www.marketfragments.com │
# ─────────────────────────────────────────────
# Time →
# │
# █ █ █│ █
# █ █ █ │ █ █
# █ █ █ │ █ █ █ ╭─╮
# █ █ █ │ █ █ █ █ ╭─╯ ╰─╮
# █ █ █ │ █ █ █ █ █ █ ╭─╯ ╰─╮
# █ █ █ │ █ █ █ █ █ █ █ █ ╭─╯ ╰─╮
# █ █ █ │ █ █ █ █ █ █ █ █ █ █╭─╯ ╰─╮
# █ █ █ │ █ █ █ █ █ █ █ █ ╰─╮ ╭─╯
# █ █ █ │ █ █ █ █ █ █ ╰─╮ ╭─╯
# █ █ █ │ █ █ █ █ ╰─╮ ╭─╯
# █ █ █ │ █ █ ╰─╮ ╭─╯
# █ █ █ │ █ ╰─────╯
# ──────┴──────────────────────────────────────────────────────────────
# T1 T2 T3 T4 T5 T6
#
# Indicator: VWAP with Anchored Std Dev Bands
# Category : Volume
# Free for non-commercial use. Attribution appreciated.
#
# What it does:
# Plots a volume-weighted average price anchored to the start of each
# Session / Week / Month, surrounded by ±1σ, ±2σ, and ±3σ standard
# deviation envelopes computed from the same anchored data set. The
# bands describe where price has actually traded around fair value
# so far in the anchor period — they widen as activity disperses and
# tighten when the auction balances.
# ─────────────────────────────────────────────
declare upper;
input anchor = {default DAY, WEEK, MONTH};
input devMult1 = 1.0;
input devMult2 = 2.0;
input devMult3 = 3.0;
input showBand3 = yes;
input showCloud = yes;
input showLabel = yes;
# Source price (typical price hlc3 — volume-weighted standard)
def srcPrice = (high + low + close) / 3;
def vol = volume;
# Detect a new anchor period
def isNew;
switch (anchor) {
case DAY:
isNew = GetDay() != GetDay()[1];
case WEEK:
isNew = GetWeek() != GetWeek()[1];
case MONTH:
isNew = GetMonth() != GetMonth()[1];
}
# Running sums — reset on each new anchor bar, accumulate otherwise
def sumPV = if isNew then srcPrice * vol else CompoundValue(1, sumPV[1] + srcPrice * vol, srcPrice * vol);
def sumV = if isNew then vol else CompoundValue(1, sumV[1] + vol, vol);
def sumP2V = if isNew then Sqr(srcPrice) * vol else CompoundValue(1, sumP2V[1] + Sqr(srcPrice) * vol, Sqr(srcPrice) * vol);
# VWAP and volume-weighted variance: Var = E[P²] - (E[P])²
def vwap = if sumV > 0 then sumPV / sumV else Double.NaN;
def variance = if sumV > 0 then (sumP2V / sumV) - Sqr(vwap) else 0;
def stdev = Sqrt(Max(variance, 0));
plot VWAP_line = vwap;
plot UpperBand1 = vwap + devMult1 * stdev;
plot LowerBand1 = vwap - devMult1 * stdev;
plot UpperBand2 = vwap + devMult2 * stdev;
plot LowerBand2 = vwap - devMult2 * stdev;
plot UpperBand3 = if showBand3 then vwap + devMult3 * stdev else Double.NaN;
plot LowerBand3 = if showBand3 then vwap - devMult3 * stdev else Double.NaN;
VWAP_line.SetDefaultColor(Color.YELLOW);
VWAP_line.SetLineWeight(2);
UpperBand1.SetDefaultColor(Color.LIGHT_GREEN);
LowerBand1.SetDefaultColor(Color.LIGHT_RED);
UpperBand2.SetDefaultColor(Color.GREEN);
LowerBand2.SetDefaultColor(Color.RED);
UpperBand3.SetDefaultColor(Color.DARK_GREEN);
LowerBand3.SetDefaultColor(Color.DARK_RED);
UpperBand2.SetLineWeight(2);
LowerBand2.SetLineWeight(2);
# Volatility-extreme clouds between the 2σ and 3σ bands
AddCloud(if showCloud and showBand3 then UpperBand3 else Double.NaN,
if showCloud and showBand3 then UpperBand2 else Double.NaN,
Color.DARK_GREEN, Color.DARK_GREEN);
AddCloud(if showCloud and showBand3 then LowerBand2 else Double.NaN,
if showCloud and showBand3 then LowerBand3 else Double.NaN,
Color.DARK_RED, Color.DARK_RED);
# Live label
AddLabel(showLabel,
"VWAP " + Round(vwap, 2) +
" 1σ: " + Round(stdev, 2) +
" bandwidth(2σ): " + Round(2 * devMult2 * stdev, 2),
Color.YELLOW);
# Alerts on volatility-extreme touches and VWAP retests
Alert(close crosses above UpperBand2, "Close crossed ABOVE Upper 2σ band", Alert.BAR, Sound.Ring);
Alert(close crosses below LowerBand2, "Close crossed BELOW Lower 2σ band", Alert.BAR, Sound.Ring);
Alert(close crosses above VWAP_line, "Close reclaimed the anchored VWAP", Alert.BAR, Sound.Chimes);
Alert(close crosses below VWAP_line, "Close lost the anchored VWAP", Alert.BAR, Sound.Chimes);
```
Drop your tweaks, screenshots, and questions below — that's how the library gets better.

