TradingView indicator calculations

Elastic volume weighted moving average: volume memory and missing data

An elastic volume weighted moving average updates its previous value by a fraction determined by current volume: E = previous E + (volume / volume budget) × (price − previous E). Its memory decays through successive updates. A conventional VWMA recomputes a weighted average over a fixed bar window. The two calculations can disagree even with the same prices, volumes and length.

See the decision guide

Choose a published recursion and specify its denominator

Christian P. Fries describes E = ((N − v) × previous E + v × p) / N, with N a share-volume budget. His introductory paper motivates it as an approximation to the average price paid per share. It does not observe investors' actual holdings or cost bases. Linn Software also documents a budget calculated as a multiple of recent average volume.

  • This page selects that average-volume form with multiplier L: S = L × SMA(volume, L) = sum of the latest L volumes, including the current bar. Then α = current volume / S and E = (1 − α) × previous E + α × current price.
  • This is an explicit rolling-budget adaptation of the published recursion. The seed and missing-data rules below are choices for this implementation, not claims that every script named EVWMA uses them.
  • N is a volume quantity, not the number of bars. A fixed N of 1,000 shares and a rolling sum over 20 bars are different specifications. Neither a rolling budget nor a fixed-budget proxy directly measures the cost basis of all shareholders.

Why EVWMA retains a different price history

For valid data, fixed-window VWMA(L) = sum(price × volume, L) / sum(volume, L). An observation leaves that numerator when it becomes L bars old. EVWMA instead carries the previous average forward. Its denominator has a bar window, but its price state has recursive memory.

  • A seed difference Δ becomes Δ × product(1 − α) over later valid updates. There is no universal L-bar warm-up that erases it. A bar with α = 1 removes all earlier state influence.
  • With constant positive volume and L = 3, a seed difference retains (2/3)³ = 8/27 of its size after three updates. This recursive coefficient corresponds to EMA length 5 under α = 2 / (length + 1), not EMA length 3.
  • Multiplying every volume by the same positive constant leaves α unchanged in this rolling-budget version. Changing bar aggregation, session or feed can still change the result because the update sequence changes.
PropertyRolling-budget EVWMA hereFixed-window VWMA
Price calculationUpdate one previous state using α = v / SRecompute the weighted price sum over L bars
Old price influenceMultiplied by each later (1 − α)Removed once outside the L-bar window
Current volume is zeroHolds the seeded stateCan change when the oldest observation leaves
Equal positive volumeα = 1 / L; recursive smoothingSimple average of the last L prices
Length = 1, positive volumeα = 1, so E equals current priceEquals current price

A ten-bar example separates memory from window weighting

Use L = 3 and the invented prices and volumes below. Price is in arbitrary units; volume is in shares. Bars 0 and 1 are warm-up. Seed EVWMA at price 104 on bar 2, the first full valid window with positive current volume. VWMA uses that same three-bar window. Values shown are calculated before rounding; none are market observations or trading returns.

  • Bar 3: E = 104 + (30/50) × (110 − 104) = 107.6. VWMA = (102×10 + 104×10 + 110×30) / 50 = 107.2.
  • Bar 4 has zero volume, so EVWMA stays at 107.6. VWMA rises to (104×10 + 110×30) / 40 = 108.5 because the older price 102 leaves its window.
  • Bar 5: E = 107.6 + (60/90) × (80 − 107.6) = 89.2. Bar 8 has a zero denominator; the hold rule is an explicit extension, not a division by zero. Bar 9 has α = 1 and replaces the old state completely.
BarPriceVolumeSαEVWMAVWMA(3)
010010UnavailableUnavailableUnavailableUnavailable
110210UnavailableUnavailableUnavailableUnavailable
210410301/3104 (seed)102
311030500.6107.6107.2
41200400107.6108.5
58060902/389.290
690060089.280
7100060089.280
810000Undefined89.2 (held)Unavailable
910010101100100

Zero, missing and extreme volume require different decisions

A recorded zero is an observation. Missing volume is an unknown. The example preserves that distinction: an all-zero valid window holds an existing EVWMA but produces no VWMA; an invalid window resets EVWMA and displays a gap. It never converts unknown volume into evidence of no trading.

  • For nonnegative input and a current-inclusive rolling sum, S ≥ current volume. Thus α cannot exceed 1. The displayed script also bounds α to [0, 1] as a numerical guard. This is not a repair for an incorrectly defined denominator.
  • A fixed budget or a prior-bar average can give α > 1. Reject such observations, change the budget, or explicitly document clamping as an algorithm change. Do not silently call the result an ordinary convex average.
  • With L = 3, prices [100, 102, 104, 106, 108, 110, 112] and volumes [10, 10, 10, missing, 10, 10, 10], EVWMA is 104 on bar 2, unavailable on bars 3 through 5, then reseeds to 112 on bar 6. The matching VWMA on bar 6 is 110.
Input caseResult under the policy on this page
All volumes zero from the startNo seed exists; EVWMA and VWMA remain unavailable.
Current volume zero after a seedHold EVWMA. If S = 0, α is unavailable and VWMA is unavailable.
Missing or negative volume in the L-bar windowReset EVWMA to unavailable; wait for a full valid window and positive current volume to reseed.
Missing price in the L-bar windowUse the same reset policy, even if that bar has zero volume.
Current volume 1,000,000; prior two volumes 1 eachS = 1,000,002; α ≈ 0.999998. A previous E of 100 and price 110 give E ≈ 109.999980.
Fixed budget N = 100; current volume 150α = 1.5. A previous E of 100 and price 110 give E = 115, beyond both inputs.

Pine v6 with visible denominator and validation state

Paste this independent implementation into the Pine Editor. Enable Synthetic example with length 3 to reproduce bars 0 through 9 of the table; indexing starts at the first loaded chart bar. The Data Window exposes input volume, S, α and window validity. With test mode off, the script uses close and volume from the chart feed. The strict-window VWMA comparison is calculated explicitly so both lines share the stated missing-data policy.

Educational formula implementation. Syntax validation checks compilation diagnostics; numerical examples and chart comparisons test separate properties.pine
//@version=6
indicator("Rolling-budget EVWMA and VWMA", overlay=true)
length = input.int(3, "Volume window", minval=1)
isTest = input.bool(false, "Synthetic example")
float samplePrice = switch bar_index
    0 => 100.0
    1 => 102.0
    2 => 104.0
    3 => 110.0
    4 => 120.0
    5 => 80.0
    6 => 90.0
    => 100.0
float sampleVolume = switch bar_index
    0 => 10.0
    1 => 10.0
    2 => 10.0
    3 => 30.0
    4 => 0.0
    5 => 60.0
    6 => 0.0
    7 => 0.0
    8 => 0.0
    => 10.0
float p = isTest ? samplePrice : close
float v = isTest ? sampleVolume : volume
bool validBar = not na(p) and not na(v) and v >= 0
float validCount = math.sum(validBar ? 1.0 : 0.0, length)
float total = math.sum(validBar ? v : 0.0, length)
float weighted = math.sum(validBar ? p * v : 0.0, length)
bool validWindow = bar_index >= length - 1 and validCount == length
float alpha = validWindow and total > 0 ? math.max(0.0, math.min(1.0, v / total)) : na
var float evwma = na
if not validWindow
    evwma := na
else if total > 0 and v > 0
    evwma := na(evwma[1]) ? p : evwma[1] + alpha * (p - evwma[1])
else
    evwma := evwma[1]
float vwma = validWindow and total > 0 ? weighted / total : na
plot(evwma, "EVWMA", color=color.blue, linewidth=2, style=plot.style_linebr)
plot(vwma, "Strict-window VWMA", color=color.orange, style=plot.style_linebr)
plot(v, "Input volume", display=display.data_window)
plot(validWindow ? total : na, "Volume budget", display=display.data_window)
plot(alpha, "Update fraction", display=display.data_window)
plot(validWindow ? 1 : 0, "Valid window", display=display.data_window)
plot(isTest ? bar_index : na, "Test bar", display=display.data_window)
bool crossUp = ta.crossover(p, evwma)
alertcondition(not isTest and validWindow and v > 0 and barstate.isconfirmed and crossUp, "Price crosses above EVWMA", "Close crossed above EVWMA on a confirmed chart bar.")

Compare values before interpreting crossings

Use the same symbol, timeframe, session and adjustment settings when comparing scripts. Confirm which volume series the feed supplies; a tick count is not an exchange share count. Compare completed bars, since price and volume can both change while a bar is open. The script uses chart data without higher-timeframe requests or a forward plot offset.

  • Match the volume-budget formula and seed before comparing two EVWMA lines. A zero seed can create a large startup error. Different loaded history can also change a recursive state.
  • The alert checks an upward price crossing only on confirmed chart bars with valid windows and positive current volume. A price crossing above a held line on a zero-volume bar is deliberately excluded. Create the alert with Once Per Bar Close.
  • A high-volume price shock can move EVWMA almost to price immediately. A low-volume move may barely move it. Neither behavior establishes whether the next price move will continue or reverse.

Use this specification in Pineify

Ask Pine Script AI Coding Agent to draft or revise the indicator using the current-inclusive volume sum, explicit seed and strict reset policy above. Include both example sequences as expected results. Inspect the generated source, request syntax diagnostics, then compare completed-bar values in TradingView before adding entry or exit rules.

  • For another EVWMA variant, supply its public formula and the exact denominator. Changing L, excluding current volume, choosing a fixed budget or clamping an out-of-range coefficient changes the calculation.
  • Specify costs, position sizing and execution timing separately if you turn the indicator into a strategy. A matching average and a successful syntax check do not prove profitability.
Where Pineify fits

Pine Script AI Coding Agent

Turn the stated EVWMA recurrence, seed and missing-data policy into Pine Script that you can inspect and compare with the worked examples.

Build an EVWMA comparison

Frequently asked questions

Educational calculations, not investment advice. All numerical sequences on this page are hypothetical. EVWMA does not identify actual investor cost bases or guarantee profitable trades.

Sources and verification

Published by Pineify. Pineify is an independent product and is not affiliated with TradingView. Sources support the technical explanations; examples do not establish trading performance.