Indicator · Pine Script v6 · On the chart

Anchored VWAP + Moving Average

by Corbanistan

This indicator plots an anchored VWAP and a moving average on the price chart.

View on GitHub

GitHub stars1on the repository
Pine versionv6current
Lines of code367
Settings34inputs
LicenceMPL-2.0
Last update9 months ago27 Jan 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

367 lines of Pine Script v6 from vwap_ma_combo.pine, published under MPL-2.0. Keep the author's credit and licence lines when you reuse it.

vwap_ma_combo.pine
// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Corbanistan

//@version=6
indicator("Anchored VWAP + Moving Average", shorttitle="AVWAP+MA", overlay=true)

// ═══════════════════════════════════════════════════════════════════════════════
// ░░░░░░░░░░░░░░░░░░░░░░░░░ ANCHORED VWAP SETTINGS ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
// ═══════════════════════════════════════════════════════════════════════════════

vwapGroup = "══════════ Anchored VWAP ══════════"

showVwap = input.bool(true, "Show VWAP", group=vwapGroup)

anchorType = input.string("Auto", "Anchor Period", 
     options=["Auto", "Session", "Week", "Month", "Quarter", "Year", "Highest High", "Lowest Low", "Highest Volume"], 
     group=vwapGroup, 
     tooltip="Select the anchor point for VWAP calculation.\n\n• Auto: Automatically selects best anchor based on symbol type and timeframe\n• Session: Resets each trading session\n• Week/Month/Quarter/Year: Resets on period change\n• Highest High/Lowest Low: Anchors from the highest/lowest price within lookback\n• Highest Volume: Anchors from the highest volume bar within lookback")

showAutoLabel = input.bool(true, "Show Auto-Detected Anchor Label", group=vwapGroup, 
     tooltip="When using Auto mode, display a label showing which anchor was selected")

lookbackLength = input.int(50, "Lookback Length", minval=1, maxval=500, group=vwapGroup, 
     tooltip="Number of bars to look back when searching for anchor points.\n\n⚠️ Only used when Anchor Period is set to:\n• Highest High\n• Lowest Low\n• Highest Volume\n\nThis setting is ignored for time-based anchors (Session, Week, Month, Quarter, Year, Auto).")

vwapColor = input.color(color.new(color.blue, 0), "VWAP Color", group=vwapGroup)
vwapWidth = input.int(2, "VWAP Line Width", minval=1, maxval=5, group=vwapGroup)

showAnchorMarker = input.bool(false, "Show Anchor Period Marker", group=vwapGroup, 
     tooltip="Display a diamond icon at the bottom of the chart marking the start of each anchor period")
anchorMarkerColor = input.color(color.new(color.fuchsia, 0), "Anchor Marker Color", group=vwapGroup)

// VWAP Band Settings
showBand1 = input.bool(false, "Show Band 1", group=vwapGroup, inline="band1")
bandMultiplier1 = input.float(1.0, "Multiplier", minval=0.1, step=0.1, group=vwapGroup, inline="band1")
band1Color = input.color(color.new(color.blue, 50), "", group=vwapGroup, inline="band1")

showBand2 = input.bool(false, "Show Band 2", group=vwapGroup, inline="band2")
bandMultiplier2 = input.float(2.0, "Multiplier", minval=0.1, step=0.1, group=vwapGroup, inline="band2")
band2Color = input.color(color.new(color.purple, 50), "", group=vwapGroup, inline="band2")

showBand3 = input.bool(false, "Show Band 3", group=vwapGroup, inline="band3")
bandMultiplier3 = input.float(3.0, "Multiplier", minval=0.1, step=0.1, group=vwapGroup, inline="band3")
band3Color = input.color(color.new(color.red, 50), "", group=vwapGroup, inline="band3")

// ═══════════════════════════════════════════════════════════════════════════════
// ░░░░░░░░░░░░░░░░░░░░░░░░░ MOVING AVERAGE SETTINGS ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
// ═══════════════════════════════════════════════════════════════════════════════

maGroup = "══════════ Moving Average ══════════"

showMa = input.bool(true, "Show Moving Average", group=maGroup)

maType = input.string("EMA", "MA Type", 
     options=["SMA", "EMA", "WMA", "RMA", "HMA", "VWMA", "DEMA", "TEMA"], 
     group=maGroup,
     tooltip="Select the type of moving average:\n• SMA: Simple Moving Average\n• EMA: Exponential Moving Average\n• WMA: Weighted Moving Average\n• RMA: Running Moving Average (Wilder's)\n• HMA: Hull Moving Average\n• VWMA: Volume Weighted Moving Average\n• DEMA: Double Exponential Moving Average\n• TEMA: Triple Exponential Moving Average")

maLength = input.int(20, "MA Length", minval=1, maxval=500, group=maGroup)

maSource = input.source(close, "MA Source", group=maGroup, 
     tooltip="Select the price source for MA calculation (open, high, low, close, hl2, hlc3, ohlc4, hlcc4)")

maColor = input.color(color.new(color.orange, 0), "MA Color", group=maGroup)
maWidth = input.int(2, "MA Line Width", minval=1, maxval=5, group=maGroup)

// ═══════════════════════════════════════════════════════════════════════════════
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░ CROSS SIGNALS ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
// ═══════════════════════════════════════════════════════════════════════════════

signalsGroup = "══════════ Cross Signals ══════════"

showVwapCross = input.bool(false, "Show VWAP Cross Signals", group=signalsGroup, 
     tooltip="Display arrows when price crosses above or below the VWAP line")
vwapCrossUpColor = input.color(color.new(color.teal, 0), "VWAP Cross Up", group=signalsGroup, inline="vwapCross")
vwapCrossDownColor = input.color(color.new(color.red, 0), "Down", group=signalsGroup, inline="vwapCross")

showMaCross = input.bool(false, "Show MA Cross Signals", group=signalsGroup, 
     tooltip="Display arrows when price crosses above or below the Moving Average line")
maCrossUpColor = input.color(color.new(color.lime, 0), "MA Cross Up", group=signalsGroup, inline="maCross")
maCrossDownColor = input.color(color.new(color.fuchsia, 0), "Down", group=signalsGroup, inline="maCross")

showBothCross = input.bool(false, "Show Combined Cross Signals", group=signalsGroup, 
     tooltip="Display arrows when price crosses both VWAP and MA in the same direction on the same bar")
bothCrossUpColor = input.color(color.new(color.yellow, 0), "Both Cross Up", group=signalsGroup, inline="bothCross")
bothCrossDownColor = input.color(color.new(color.orange, 0), "Down", group=signalsGroup, inline="bothCross")

showVwapMaCross = input.bool(false, "Show VWAP/MA Cross Signals", group=signalsGroup, 
     tooltip="Display an X marker when VWAP crosses the Moving Average line")
vwapMaCrossColor = input.color(color.new(color.purple, 0), "VWAP/MA Cross Color", group=signalsGroup)

// ═══════════════════════════════════════════════════════════════════════════════
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ CALCULATIONS ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
// ═══════════════════════════════════════════════════════════════════════════════

// --- VWAP Anchor Detection ---
isNewPeriod(periodType) =>
    switch periodType
        "Session" => ta.change(time("D")) != 0
        "Week" => ta.change(time("W")) != 0
        "Month" => ta.change(time("M")) != 0
        "Quarter" => ta.change(time("3M")) != 0
        "Year" => ta.change(time("12M")) != 0
        => false

// Find highest high bar index within lookback
highestHighBar() =>
    highestIdx = 0
    highestVal = high[0]
    for i = 1 to lookbackLength - 1
        if high[i] > highestVal
            highestVal := high[i]
            highestIdx := i
    highestIdx

// Find lowest low bar index within lookback
lowestLowBar() =>
    lowestIdx = 0
    lowestVal = low[0]
    for i = 1 to lookbackLength - 1
        if low[i] < lowestVal
            lowestVal := low[i]
            lowestIdx := i
    lowestIdx

// Find highest volume bar index within lookback
highestVolumeBar() =>
    highestIdx = 0
    highestVal = volume[0]
    for i = 1 to lookbackLength - 1
        if volume[i] > highestVal
            highestVal := volume[i]
            highestIdx := i
    highestIdx

// --- Auto Anchor Detection Logic ---
// Detect symbol type
isForex = syminfo.type == "forex" or syminfo.type == "cfd"
isCrypto = syminfo.type == "crypto"
isStock = syminfo.type == "stock" or syminfo.type == "dr"
isFutures = syminfo.type == "futures"
isIndex = syminfo.type == "index"

// Get timeframe in minutes for comparison
tfInMinutes = timeframe.in_seconds() / 60

// Auto-select best anchor based on symbol type and timeframe
// Logic:
// - Forex: Session (24hr markets, session reset is most relevant)
// - Crypto: Session for intraday, Week for daily+ (24/7 market)
// - Stocks: Session for intraday, Week for daily/weekly
// - Futures: Session for intraday, Week for daily+
// - Index: Session for intraday, Month for daily+
// - Higher timeframes (weekly+): Use Month or Quarter
autoAnchor = if isForex
    // Forex: Use Session for intraday, Week for daily+
    if tfInMinutes >= 10080  // Weekly or higher
        "Month"
    else if tfInMinutes >= 1440  // Daily
        "Week"
    else
        "Session"
else if isCrypto
    if tfInMinutes >= 10080  // Weekly or higher
        "Month"
    else if tfInMinutes >= 1440  // Daily
        "Week"
    else
        "Session"
else if isStock or isFutures
    if tfInMinutes >= 10080  // Weekly or higher
        "Month"
    else if tfInMinutes >= 1440  // Daily
        "Week"
    else
        "Session"
else if isIndex
    if tfInMinutes >= 10080  // Weekly or higher
        "Quarter"
    else if tfInMinutes >= 1440  // Daily
        "Month"
    else
        "Session"
else
    // Default fallback
    if tfInMinutes >= 1440
        "Week"
    else
        "Session"

// Resolve the effective anchor type
effectiveAnchor = anchorType == "Auto" ? autoAnchor : anchorType

// Determine if current bar is anchor point based on selected type
isAnchorPeriod = switch effectiveAnchor
    "Session" => isNewPeriod("Session")
    "Week" => isNewPeriod("Week")
    "Month" => isNewPeriod("Month")
    "Quarter" => isNewPeriod("Quarter")
    "Year" => isNewPeriod("Year")
    "Highest High" => bar_index >= lookbackLength and highestHighBar() == 0
    "Lowest Low" => bar_index >= lookbackLength and lowestLowBar() == 0
    "Highest Volume" => bar_index >= lookbackLength and highestVolumeBar() == 0
    => false

// Force anchor on first bar to ensure proper VWAP initialization
isAnchor = bar_index == 0 or isAnchorPeriod

// --- VWAP Calculation ---
var float sumPV = 0.0
var float sumV = 0.0
var float sumPV2 = 0.0

typicalPrice = hlc3

if isAnchor
    sumPV := typicalPrice * volume
    sumV := volume
    sumPV2 := typicalPrice * typicalPrice * volume
else
    sumPV := sumPV + typicalPrice * volume
    sumV := sumV + volume
    sumPV2 := sumPV2 + typicalPrice * typicalPrice * volume

vwapValue = sumV != 0 ? sumPV / sumV : na

// Standard deviation for bands
variance = sumV != 0 ? (sumPV2 / sumV) - (vwapValue * vwapValue) : 0
stdDev = math.sqrt(math.max(variance, 0))

upperBand1 = vwapValue + stdDev * bandMultiplier1
lowerBand1 = vwapValue - stdDev * bandMultiplier1
upperBand2 = vwapValue + stdDev * bandMultiplier2
lowerBand2 = vwapValue - stdDev * bandMultiplier2
upperBand3 = vwapValue + stdDev * bandMultiplier3
lowerBand3 = vwapValue - stdDev * bandMultiplier3

// --- Moving Average Calculation ---
// DEMA helper
dema(src, len) =>
    ema1 = ta.ema(src, len)
    ema2 = ta.ema(ema1, len)
    2 * ema1 - ema2

// TEMA helper
tema(src, len) =>
    ema1 = ta.ema(src, len)
    ema2 = ta.ema(ema1, len)
    ema3 = ta.ema(ema2, len)
    3 * (ema1 - ema2) + ema3

maValue = switch maType
    "SMA" => ta.sma(maSource, maLength)
    "EMA" => ta.ema(maSource, maLength)
    "WMA" => ta.wma(maSource, maLength)
    "RMA" => ta.rma(maSource, maLength)
    "HMA" => ta.hma(maSource, math.max(maLength, 4))  // HMA requires minimum length of 4
    "VWMA" => ta.vwma(maSource, maLength)
    "DEMA" => dema(maSource, maLength)
    "TEMA" => tema(maSource, maLength)
    => ta.ema(maSource, maLength)

// ═══════════════════════════════════════════════════════════════════════════════
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ PLOTTING ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
// ═══════════════════════════════════════════════════════════════════════════════

// Plot VWAP
plot(showVwap ? vwapValue : na, "VWAP", color=vwapColor, linewidth=vwapWidth)

// Plot VWAP Bands
// Band 1
ub1Plot = plot(showVwap and showBand1 ? upperBand1 : na, "Upper Band 1", color=band1Color, linewidth=1)
lb1Plot = plot(showVwap and showBand1 ? lowerBand1 : na, "Lower Band 1", color=band1Color, linewidth=1)
fill(ub1Plot, lb1Plot, color=color.new(band1Color, 90), title="Band 1 Fill")

// Band 2
ub2Plot = plot(showVwap and showBand2 ? upperBand2 : na, "Upper Band 2", color=band2Color, linewidth=1)
lb2Plot = plot(showVwap and showBand2 ? lowerBand2 : na, "Lower Band 2", color=band2Color, linewidth=1)
fill(ub2Plot, lb2Plot, color=color.new(band2Color, 90), title="Band 2 Fill")

// Band 3
ub3Plot = plot(showVwap and showBand3 ? upperBand3 : na, "Upper Band 3", color=band3Color, linewidth=1)
lb3Plot = plot(showVwap and showBand3 ? lowerBand3 : na, "Lower Band 3", color=band3Color, linewidth=1)
fill(ub3Plot, lb3Plot, color=color.new(band3Color, 90), title="Band 3 Fill")

// Plot Moving Average
plot(showMa ? maValue : na, "Moving Average", color=maColor, linewidth=maWidth)

// --- Cross Signal Detection ---
// VWAP crosses (only detect if VWAP is enabled and has valid value)
vwapCrossUp = showVwap and not na(vwapValue) and ta.crossover(close, vwapValue)
vwapCrossDown = showVwap and not na(vwapValue) and ta.crossunder(close, vwapValue)

// MA crosses (only detect if MA is enabled and has valid value)
maCrossUp = showMa and not na(maValue) and ta.crossover(close, maValue)
maCrossDown = showMa and not na(maValue) and ta.crossunder(close, maValue)

// Combined crosses (both cross in same direction on same bar)
bothCrossUp = vwapCrossUp and maCrossUp
bothCrossDown = vwapCrossDown and maCrossDown

// Plot VWAP cross signals
plotshape(showVwapCross and vwapCrossUp ? low : na, "VWAP Cross Up", 
     style=shape.triangleup, location=location.belowbar, 
     color=vwapCrossUpColor, size=size.small)
plotshape(showVwapCross and vwapCrossDown ? high : na, "VWAP Cross Down", 
     style=shape.triangledown, location=location.abovebar, 
     color=vwapCrossDownColor, size=size.small)

// Plot Anchor Period Marker
plotshape(showAnchorMarker and showVwap and isAnchor, "Anchor Period Start", 
     style=shape.labelup, location=location.bottom, 
     color=anchorMarkerColor, size=size.small)

// Plot MA cross signals
plotshape(showMaCross and maCrossUp ? low : na, "MA Cross Up", 
     style=shape.triangleup, location=location.belowbar, 
     color=maCrossUpColor, size=size.small)
plotshape(showMaCross and maCrossDown ? high : na, "MA Cross Down", 
     style=shape.triangledown, location=location.abovebar, 
     color=maCrossDownColor, size=size.small)

// Plot combined cross signals
plotshape(showBothCross and bothCrossUp ? low : na, "Both Cross Up", 
     style=shape.triangleup, location=location.belowbar, 
     color=bothCrossUpColor, size=size.normal)
plotshape(showBothCross and bothCrossDown ? high : na, "Both Cross Down", 
     style=shape.triangledown, location=location.abovebar, 
     color=bothCrossDownColor, size=size.normal)

// VWAP/MA crosses (exclude anchor bars where VWAP resets cause false crosses)
vwapMaCrossUp = ta.crossover(vwapValue, maValue) and not isAnchor
vwapMaCrossDown = ta.crossunder(vwapValue, maValue) and not isAnchor

// Plot VWAP/MA cross signals (X marker at cross location)
vwapMaCross = vwapMaCrossUp or vwapMaCrossDown
plotshape(showVwapMaCross and vwapMaCross ? vwapValue : na, "VWAP/MA Cross", 
     style=shape.xcross, location=location.absolute, 
     color=vwapMaCrossColor, size=size.small)

// --- Auto Mode Info Table (tables render above chart elements) ---
var table infoTable = table.new(position.top_right, 1, 1, bgcolor=color.new(vwapColor, 85), border_width=1, border_color=color.new(vwapColor, 50))

if barstate.islast and anchorType == "Auto" and showAutoLabel and showVwap
    // Create info text showing detected settings
    symbolTypeText = isForex ? "Forex" : isCrypto ? "Crypto" : isStock ? "Stock" : isFutures ? "Futures" : isIndex ? "Index" : "Other"
    infoText = "VWAP Anchor: " + effectiveAnchor + "\n(" + symbolTypeText + " detected)"
    
    table.cell(infoTable, 0, 0, infoText, text_color=vwapColor, text_size=size.small)
else
    table.clear(infoTable, 0, 0)

// ═══════════════════════════════════════════════════════════════════════════════
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ALERTS ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
// ═══════════════════════════════════════════════════════════════════════════════

// Price crosses VWAP
alertcondition(ta.crossover(close, vwapValue), "Price Crossed Above VWAP", "Price crossed above VWAP")
alertcondition(ta.crossunder(close, vwapValue), "Price Crossed Below VWAP", "Price crossed below VWAP")

// Price crosses MA
alertcondition(ta.crossover(close, maValue), "Price Crossed Above MA", "Price crossed above Moving Average")
alertcondition(ta.crossunder(close, maValue), "Price Crossed Below MA", "Price crossed below Moving Average")

// VWAP crosses MA (filter out anchor resets to avoid false alerts)
alertcondition(ta.crossover(vwapValue, maValue) and not isAnchor, "VWAP Crossed Above MA", "VWAP crossed above Moving Average")
alertcondition(ta.crossunder(vwapValue, maValue) and not isAnchor, "VWAP Crossed Below MA", "VWAP crossed below Moving Average")

Overview

The VWAP anchor can be chosen automatically or set to session, week, month, quarter, year, highest high, lowest low or highest volume bar within a lookback. Up to three standard deviation bands can be shown. The moving average supports several types and sources. Optional markers show price and VWAP crosses, price and average crosses, and combined crosses.

Details

Published by

Corbanistan on GitHub

Type

Indicator, Pine Script v6

Draws

On the price chart

Category

Moving averages, Volume, Support & resistance

Markets

Any symbol

Timeframes

Any timeframe

Risk Notes

No repainting, lookahead or stacked entries were found in its code or README. That says nothing about how well it works: test it first.

Settings

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

SettingTypeDefaultVariable
Show VWAPbooltrueshowVwap
Anchor PeriodstringAutoanchorType
Show Auto-Detected Anchor LabelbooltrueshowAutoLabel
Lookback Lengthint50lookbackLength
VWAP Colorcolorcolor.new(color.blue, 0)vwapColor
VWAP Line Widthint2vwapWidth
Show Anchor Period MarkerboolfalseshowAnchorMarker
Anchor Marker Colorcolorcolor.new(color.fuchsia, 0)anchorMarkerColor
Show Band 1boolfalseshowBand1
Multiplierfloat1.0bandMultiplier1
band1Colorcolorcolor.new(color.blue, 50)band1Color
Show Band 2boolfalseshowBand2
Show all 34 settings
SettingTypeDefaultVariable
Multiplierfloat2.0bandMultiplier2
band2Colorcolorcolor.new(color.purple, 50)band2Color
Show Band 3boolfalseshowBand3
Multiplierfloat3.0bandMultiplier3
band3Colorcolorcolor.new(color.red, 50)band3Color
Show Moving AveragebooltrueshowMa
MA TypestringEMAmaType
MA Lengthint20maLength
MA SourcesourceclosemaSource
MA Colorcolorcolor.new(color.orange, 0)maColor
MA Line Widthint2maWidth
Show VWAP Cross SignalsboolfalseshowVwapCross
VWAP Cross Upcolorcolor.new(color.teal, 0)vwapCrossUpColor
Downcolorcolor.new(color.red, 0)vwapCrossDownColor
Show MA Cross SignalsboolfalseshowMaCross
MA Cross Upcolorcolor.new(color.lime, 0)maCrossUpColor
Downcolorcolor.new(color.fuchsia, 0)maCrossDownColor
Show Combined Cross SignalsboolfalseshowBothCross
Both Cross Upcolorcolor.new(color.yellow, 0)bothCrossUpColor
Downcolorcolor.new(color.orange, 0)bothCrossDownColor
Show VWAP/MA Cross SignalsboolfalseshowVwapMaCross
VWAP/MA Cross Colorcolorcolor.new(color.purple, 0)vwapMaCrossColor
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

Midnight VWAP

by TradersPost
218 stars

The Midnight VWAP indicator calculates and overlays two distinct Volume Weighted Average Price (VWAP) lines on the price chart based on customizable session timeframes. It tracks an overnight or pre-market session alongside regular trading hours, resetting cal

Indicator v6 Moving averagesSessions & time
Updated 3 months ago · None stated GitHub repository of Midnight VWAP
7 stars

This indicator overlays Bollinger Bands on the price chart and fills the area between upper and lower bands using a color based on Cumulative Volume Delta trend. It plots an EMA 9 line and fills between the EMA 9 and Bollinger basis in green or red depending o

Indicator v6 Volatility & bandsVolume
Updated 5 months ago · None stated GitHub repository of Deep Chart + BB (CVD Internal)

IFA-VP Context

by eddiebelaval
7 stars

This indicator plots a fixed lookback Volume Profile alongside 20, 50, and 200 Simple Moving Averages directly on the price chart. It highlights trend changes via moving average crosses and marks Point of Control reactions, High Volume Nodes, and Value Area bo

Indicator v6 VolumeSupport & resistance
Updated 3 months ago · None stated GitHub repository of IFA-VP Context

More indicators

Trade Your Charts With a Regulated Broker

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

Compare brokers