Indicator · Pine Script v6 · On the chart

Anchored VWAP [WavesUnchained]

by casoon

Calculates volume-weighted average price anchored to automatically detected swing pivots, period starts, or a custom manual timestamp.

View on GitHub

Repaints

GitHub stars9on the repository
Pine versionv6current
Lines of code247
Settings17inputs
LicenceMIT
Last update3 days ago27 Oct 2026

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new indicator, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart, then adjust the settings with the gear icon next to its name.

Source Code

247 lines of Pine Script v6 from indicators/mean_reversion/anchored_vwap/anchored_vwap.pine, published under MIT. Keep the author's credit and licence lines when you reuse it.

anchored_vwap.pine
//@version=6
// ============================================================================
// Anchored VWAP [WavesUnchained]
// Version: 1.0.4
// Author: WavesUnchained
// Build: 2026-10-12
// ============================================================================
// Volume-weighted average price anchored to a selectable origin (swing pivot,
// session / week / month / year, or a manual date) with volume-weighted σ bands.
// Stage-4 "fair value zone" location sensor for the reversal pipeline: it reports
// how stretched price is from value (distance in σ), it never fires a long/short
// trigger.
//
// Features:
//   ✓ Anchor at auto swing pivot, period start, or manual timestamp
//   ✓ Volume-weighted standard-deviation bands (two configurable multiples)
//   ✓ Distance-from-value in σ as a symmetric Location output
//   ✓ Stretched / band-touch context markers (no entries)
//   ✓ Anchor markers, light-theme dashboard, alerts
//
// Data Contract:
//   Price:     REQUIRED   chart symbol
//   Volume:    REQUIRED   real trade volume — feed must deliver volume and
//                         syminfo.volumetype must not be "tick"; otherwise not available
//   OI:        NO
//   Reference: NO
//   Verdict:   Exchange-only
//
// ============================================================================

indicator("Anchored VWAP [WavesUnchained]", "AVWAP", overlay=true, max_labels_count=500, max_lines_count=500)

// ─────────────────────────────────────────────────────────────────────────────
// INPUTS
// ─────────────────────────────────────────────────────────────────────────────

g_anchor = "1 · Anchor"
anchorMode = input.string("Auto: Last Swing", "Anchor on",
     options=["Auto: Last Swing", "Auto: Swing High", "Auto: Swing Low",
              "Session", "Week", "Month", "Year", "Manual Date"], group=g_anchor)
pivLeft    = input.int(5, "Swing Left Bars",  minval=1, group=g_anchor)
pivR       = input.int(5, "Swing Right Bars", minval=1, group=g_anchor,
     tooltip="Auto modes re-seed the VWAP from the actual pivot bar (pivR bars back), so value accrues from the real swing, not the confirmation bar.")
anchorTime = input.time(timestamp("01 Jan 2024 00:00 +0000"), "Manual Anchor", group=g_anchor)
srcSel     = input.source(hlc3, "Price Source", group=g_anchor)

g_bands = "2 · Bands"
showBands = input.bool(true, "Show σ Bands", group=g_bands)
mult1     = input.float(1.0, "Band 1 (σ)", minval=0.0, step=0.25, group=g_bands)
mult2     = input.float(2.0, "Band 2 (σ)", minval=0.0, step=0.25, group=g_bands)

g_loc = "3 · Location"
stretchSigma = input.float(2.0, "Stretched at (σ)", minval=0.5, step=0.25, group=g_loc,
     tooltip="|distance| ≥ this σ → flag a stretched location. Above value = potential short location, below = long location. Context only, not a trigger.")
showStretch  = input.bool(true, "Show stretched markers", group=g_loc)

g_disp = "4 · Display"
showAnchor = input.bool(true, "Show anchor markers", group=g_disp)
showTable  = input.bool(true, "Show dashboard", group=g_disp)
tablePos   = input.string("Top Right", "Dashboard position",
     options=["Top Right", "Top Left", "Bottom Right", "Bottom Left"], group=g_disp)

g_col = "5 · Colors"
colVwap = input.color(#ff6f00,            "VWAP",  group=g_col)
colUp   = input.color(#d50000,            "Above value", group=g_col)
colDn   = input.color(#00c853,            "Below value", group=g_col)

// ─────────────────────────────────────────────────────────────────────────────
// DATA VALIDITY
// ─────────────────────────────────────────────────────────────────────────────

// Echtes Handelsvolumen? Nur "tick" schließt aus; "n/a" zählt, wenn der Feed Volumen liefert (DATA_VALIDITY §2).
bool volumeIsReal = (ta.cum(nz(volume)) > 0 and syminfo.volumetype != "tick") and not na(volume)

float vol = volumeIsReal ? volume : na

// ─────────────────────────────────────────────────────────────────────────────
// ANCHOR EVENT
// ─────────────────────────────────────────────────────────────────────────────

float ph = ta.pivothigh(pivLeft, pivR)
float pl = ta.pivotlow(pivLeft, pivR)
bool isPivotMode = str.startswith(anchorMode, "Auto")

// All ta.* computed globally for a consistent series (v6 pitfall: no conditional ta.*)
bool chD = ta.change(time("D"))   != 0
bool chW = ta.change(time("W"))   != 0
bool chM = ta.change(time("M"))   != 0
bool chY = ta.change(time("12M")) != 0

bool evt = false
if anchorMode == "Auto: Last Swing"
    evt := not na(ph) or not na(pl)
else if anchorMode == "Auto: Swing High"
    evt := not na(ph)
else if anchorMode == "Auto: Swing Low"
    evt := not na(pl)
else if anchorMode == "Session"
    evt := chD
else if anchorMode == "Week"
    evt := chW
else if anchorMode == "Month"
    evt := chM
else if anchorMode == "Year"
    evt := chY
else
    evt := time >= anchorTime and time[1] < anchorTime

bool active = anchorMode != "Manual Date" or time >= anchorTime

// ─────────────────────────────────────────────────────────────────────────────
// VWAP ACCUMULATION  (running sums, reset on anchor event)
// ─────────────────────────────────────────────────────────────────────────────

var float sumPV  = na
var float sumV   = na
var float sumPV2 = na

float src = srcSel

if active
    if evt or na(sumV)
        sumPV  := 0.0
        sumV   := 0.0
        sumPV2 := 0.0
        if isPivotMode
            for i = pivR to 0
                float p = nz(src[i])
                float v = nz(vol[i])
                sumPV  := sumPV + p * v
                sumV   := sumV + v
                sumPV2 := sumPV2 + p * p * v
        else
            sumPV  := src * vol
            sumV   := vol
            sumPV2 := src * src * vol
    else
        sumPV  := sumPV + src * vol
        sumV   := sumV + vol
        sumPV2 := sumPV2 + src * src * vol

float vwap     = sumV > 0.0 ? sumPV / sumV : na
float variance = sumV > 0.0 ? math.max(0.0, sumPV2 / sumV - vwap * vwap) : na
float sd       = math.sqrt(variance)

float up1 = vwap + mult1 * sd
float dn1 = vwap - mult1 * sd
float up2 = vwap + mult2 * sd
float dn2 = vwap - mult2 * sd

// ─────────────────────────────────────────────────────────────────────────────
// LOCATION OUTPUT  (distance from value in σ — symmetric, never a trigger)
// ─────────────────────────────────────────────────────────────────────────────

float distSigma = sd > 0.0 ? (close - vwap) / sd : na
bool stretchedUp = active and not na(distSigma) and distSigma >=  stretchSigma   // potential short location
bool stretchedDn = active and not na(distSigma) and distSigma <= -stretchSigma   // potential long location

// ─────────────────────────────────────────────────────────────────────────────
// PLOTS
// ─────────────────────────────────────────────────────────────────────────────

plot(active ? vwap : na, "AVWAP", color=colVwap, linewidth=2)

pUp2 = plot(active and showBands ? up2 : na, "Upper 2σ", color=color.new(colUp, 60))
pUp1 = plot(active and showBands ? up1 : na, "Upper 1σ", color=color.new(colUp, 75))
pDn1 = plot(active and showBands ? dn1 : na, "Lower 1σ", color=color.new(colDn, 75))
pDn2 = plot(active and showBands ? dn2 : na, "Lower 2σ", color=color.new(colDn, 60))

fill(pUp1, pUp2, color=showBands ? color.new(colUp, 92) : na, title="Upper Band Fill")
fill(pDn1, pDn2, color=showBands ? color.new(colDn, 92) : na, title="Lower Band Fill")

// ─────────────────────────────────────────────────────────────────────────────
// CONTEXT MARKERS  (Location flags — not entries, see design skill §1/§9)
// ─────────────────────────────────────────────────────────────────────────────

plotshape(showAnchor and evt and active and volumeIsReal, "Anchor",
     style=shape.flag, location=location.belowbar, color=color.new(colVwap, 20), size=size.tiny)

plotshape(showStretch and stretchedUp, "Stretched ↑ (short location)",
     style=shape.triangledown, location=location.abovebar, color=color.new(colUp, 25), size=size.tiny)
plotshape(showStretch and stretchedDn, "Stretched ↓ (long location)",
     style=shape.triangleup, location=location.belowbar, color=color.new(colDn, 25), size=size.tiny)

// ─────────────────────────────────────────────────────────────────────────────
// DASHBOARD
// ─────────────────────────────────────────────────────────────────────────────

f_pos(string p) =>
    switch p
        "Top Left"     => position.top_left
        "Bottom Right" => position.bottom_right
        "Bottom Left"  => position.bottom_left
        =>                position.top_right

var table t = table.new(f_pos(tablePos), 2, 5,
     bgcolor=color.new(color.white, 5),
     border_color=color.new(color.gray, 60),
     border_width=1,
     frame_color=color.new(color.gray, 40),
     frame_width=1)

color tc = color.new(color.gray, 20)
color hd = color.new(color.gray, 90)

if showTable and barstate.islast
    table.cell(t, 0, 0, "ANCHORED VWAP", text_color=tc, bgcolor=hd, text_size=size.small)
    table.cell(t, 1, 0, anchorMode, text_color=tc, bgcolor=hd, text_size=size.small)

    table.cell(t, 0, 1, "AVWAP", text_color=tc, text_size=size.small)
    table.cell(t, 1, 1, na(vwap) ? "—" : str.tostring(vwap, format.mintick), text_color=tc, text_size=size.small)

    table.cell(t, 0, 2, "σ", text_color=tc, text_size=size.small)
    table.cell(t, 1, 2, na(sd) ? "—" : str.tostring(sd, format.mintick), text_color=tc, text_size=size.small)

    table.cell(t, 0, 3, "Distance (σ)", text_color=tc, text_size=size.small)
    color dcol = na(distSigma) ? tc : (distSigma >= 0 ? colUp : colDn)
    table.cell(t, 1, 3, na(distSigma) ? "—" : str.tostring(distSigma, "#.00"), text_color=dcol, text_size=size.small)

    table.cell(t, 0, 4, "Location", text_color=tc, text_size=size.small)
    string locTxt = stretchedUp ? "Stretched ↑" : stretchedDn ? "Stretched ↓" : "Near value"
    color  locCol = stretchedUp ? colUp : stretchedDn ? colDn : tc
    table.cell(t, 1, 4, locTxt, text_color=locCol, text_size=size.small)

// ─────────────────────────────────────────────────────────────────────────────
// DATA VALIDITY WARNING
// ─────────────────────────────────────────────────────────────────────────────

// Kurzer Hinweis unten rechts; was fehlt, steht im Data Contract oben.
var table volWarn = table.new(position.bottom_right, 1, 1)
if barstate.islast and not volumeIsReal
    table.cell(volWarn, 0, 0, "AVWAP · not available",
         bgcolor = color.new(color.orange, 20), text_color = color.white, text_size = size.small)

// ─────────────────────────────────────────────────────────────────────────────
// ALERTS  (location context, not entries)
// ─────────────────────────────────────────────────────────────────────────────

bool alertsOnBarClose = input.bool(true, "Alerts only on bar close (confirmed)", group="Alerts")
bool alertOk = not alertsOnBarClose or barstate.isconfirmed

alertcondition(alertOk and (stretchedUp and not stretchedUp[1]), "Stretched Above Value",
     "AVWAP · STRETCHED ABOVE VALUE · {{ticker}} {{interval}}")
alertcondition(alertOk and (stretchedDn and not stretchedDn[1]), "Stretched Below Value",
     "AVWAP · STRETCHED BELOW VALUE · {{ticker}} {{interval}}")
alertcondition(alertOk and (ta.cross(close, vwap)), "Price Crossed AVWAP",
     "AVWAP · VWAP CROSS · {{ticker}} {{interval}}")

Overview

Anchored VWAP [WavesUnchained] plots volume-weighted standard deviation bands with configurable multiples and measures price distance from VWAP in standard deviation units to identify stretched market conditions. The indicator draws anchor points, stretch markers, and an optional summary table directly on the price chart. Requiring valid trade volume, it acts as a location sensor rather than providing direct entry signals.

Details

Published by

casoon on GitHub

Draws

On the price chart

Markets

Any symbol

Timeframes

Any timeframe

Risk Notes

  • Signals can change on the live bar or after it closes (repainting)

Topics

pine-scriptpinescripttechnical-analysistrading-indicatorstrading-strategiestradingview

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
Anchor onstringAuto: Last SwinganchorMode
Swing Left Barsint5pivLeft
Swing Right Barsint5pivR
Manual Anchortimetimestamp("01 Jan 2024 00:00 +0000")anchorTime
Price Sourcesourcehlc3srcSel
Show σ BandsbooltrueshowBands
Band 1 (σ)float1.0mult1
Band 2 (σ)float2.0mult2
Stretched at (σ)float2.0stretchSigma
Show stretched markersbooltrueshowStretch
Show anchor markersbooltrueshowAnchor
Show dashboardbooltrueshowTable
Show all 17 settings
SettingTypeDefaultVariable
Dashboard positionstringTop RighttablePos
VWAPcolor#ff6f00colVwap
Above valuecolor#d50000colUp
Below valuecolor#00c853colDn
Alerts only on bar close (confirmed)booltruealertsOnBarClose
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.

Similar Pine Scripts

20 stars

This indicator calculates a base moving average (EMA, SMA, WMA, or HMA) and projects multiple symmetrical envelope bands around it directly on the price chart. Users can adjust the length, source, moving average type, and initial envelope multiplier. Additiona

Indicator v5 Moving averagesVolatility & bands
Updated 1 year ago · None stated GitHub repository of Multiple Moving Average Envelope

Bottom Level Finder

by chris-c-thomas
14 stars

Bottom Level Finder is a support identification indicator designed to locate correction and re-entry zones directly on the price chart. It calculates horizon-adaptive Fibonacci retracements, drawdown percentage levels, moving averages, and integrated VIX volat

Indicator v6 Support & resistanceMoving averages
Updated 6 months ago · MIT GitHub repository of Bottom Level Finder
7 stars

This indicator plots standard Bollinger Bands alongside scaled Average True Range (ATR) bands directly on the price chart. It is designed to assist traders in identifying price consolidation zones, potential breakout levels, dynamic stops, and take-profit targ

Indicator v5 Moving averagesVolatility & bands
Updated 1 year ago · MPL-2.0 GitHub repository of Bollinger and ATR Bands

ATR Based Stoploss

by rubystar0512
5 stars

ATR Based Stoploss is an overlay indicator that calculates dynamic stop loss and take profit bands around a central simple moving average. It uses standard Average True Range or an ATR Surge Average derived from volatility spikes to offset profit and loss boun

Indicator v5 Volatility & bandsMoving averages
Updated 2 years ago · None stated GitHub repository of ATR Based Stoploss

This overlay indicator plots a Supertrend from an ATR length and factor, four exponential moving averages, and a selectable VWAP or TWAP taken from a chosen timeframe on the price chart. It also shows MACD and stochastic with adjustable lengths, smoothing, ver

Indicator v5 Oscillators & momentumMoving averages
Updated 1 year ago · MPL-2.0 GitHub repository of Momentum Setup: Vijay Thakare Option Buying Scalping Setup

Snag - VWAP

by dearvn
257 stars

This indicator plots a custom Anchored Volume-Weighted Average Price (VWAP) directly on the price chart along with optional standard deviation bands. Users can anchor the VWAP to standard time periods like sessions, weeks, or months, or to corporate events suc

Indicator v5 Moving averagesVolatility & bands Repaints
Updated 7 weeks ago · None stated GitHub repository of Snag - VWAP

More Moving averages scripts

Related on ForexR

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers