Skip to content
Nalin Angrish edited this page Jul 18, 2026 · 1 revision

Volume-Weighted Average Price (VWAP)

Overview

VWAP (Volume-Weighted Average Price) is the ratio of the cumulative price--volume product to the cumulative volume over a given trading session. It represents the average price at which a security has traded throughout the day, weighted by the volume at each price level.

In Navier-Stocks, VWAP serves as the anchor line for the breakout detection engine. When the 1-minute candle close crosses decisively above VWAP (with volume confirmation), a long intent may be generated; conversely, a close below VWAP may trigger a short intent.

Mathematical Definition

For a sequence of $n$ trades, each with price $p_i$ and volume $v_i$:

$$ \text{VWAP} = \frac{\sum_{i=1}^{n} p_i \cdot v_i}{\sum_{i=1}^{n} v_i} $$

Candle-Based Variant

When working with OHLCV candles instead of raw ticks, the closing price is used as the representative price:

$$ \text{VWAP}_{\text{candle}} = \frac{\sum_{j=1}^{m} \text{close}_j \cdot \text{volume}_j}{\sum_{j=1}^{m} \text{volume}_j} $$

An alternative uses the typical price of each candle:

$$ \text{typical}_j = \frac{\text{high}_j + \text{low}_j + \text{close}_j}{3} $$

$$ \text{VWAP}_{\text{typical}} = \frac{\sum_{j=1}^{m} \text{typical}_j \cdot \text{volume}_j}{\sum_{j=1}^{m} \text{volume}_j} $$

Interpretation

Value Meaning
Price $\approx$ VWAP Fair value — no directional bias
Price $>$ VWAP Buyer-dominated session; possible bullish momentum
Price $<$ VWAP Seller-dominated session; possible bearish momentum

The VWAP Band measures how far the current price has strayed from VWAP:

$$ \text{deviation} = \text{price} - \text{VWAP} $$

$$ \text{deviation}% = \left(\frac{\text{price}}{\text{VWAP}} - 1\right) \times 100 $$

Role in the Pipeline

TickStore.RecentPrices() + RecentVolumes()
                  │
                  ▼
         VWAP(prices, volumes)  ────► VWAPResult.VWAP
                  │
                  ▼
         VWAPBand(price, vwap) ────► deviation, deviation%
                  │
                  ▼
         Breakout Detector (1.6) ──► signal.intent.*

The breakout detector checks:

  1. VWAP crossover: The 1-min candle close crosses above (long) or below (short) the VWAP line.
  2. Volume confirmation: The candle volume must be at least $2\times$ the rolling 10-minute volume SMA (see Volume Breakout).

Cumulative (Real-Time) Variant

For live tick-by-tick processing, a CumulativeVWAP accumulator maintains running sums:

$$S_{pv} = \sum p_i \cdot v_i, \quad S_v = \sum v_i$$

Each new tick updates both sums and returns the latest ratio immediately. This avoids re-scanning the full history on every tick.

Implementation

File: src/analysts/quantitative/indicators/vwap.go

Function Input Returns
VWAP prices []float64, volumes []int64 VWAPResult{VWAP, TotalVolume, PriceVolume, Valid}
VWAPFromCandles candles []Candle VWAPResult (uses close)
VWAPFromCandlesTypical candles []Candle VWAPResult (uses typical price)
CumulativeVWAP.Add price float64, volume int64 updated VWAP float64
VWAPBand price, vwap float64 deviation, deviationPct float64

Underlying math primitives: src/pkg/math/math.go — WeightedAverage() powers the core computation.

Edge Cases

Condition Behaviour
Empty input slices Valid = false
Mismatched price/volume lengths Valid = false
Total volume = 0 Valid = false
Single tick VWAP = tick price (trivial)
Zero volume ticks Contribution ignored (price × 0 = 0)
VWAP = 0 in VWAPBand Returns (0, 0) to avoid division by zero

References

  • Volume Breakout Indicator — downstream volume confirmation
  • Bollinger Bands Indicator — complementary volatility bands
  • src/analysts/quantitative/indicators/vwap_test.go — comprehensive test suite
  • wiki/High-Level-Design.md — architecture placement description

🌊 Navier-Stocks Documentation


Clone this wiki locally