Volume Weighted Average Price (VWAP)
anchor = 1d Overview
Volume Weighted Average Price (VWAP) calculates the average price weighted by trading volume within specified time anchors, serving as a key benchmark for institutional execution quality and intraday fair value. The indicator multiplies each price by its corresponding volume, sums these products across the anchor period, then divides by total volume to produce the volume-weighted mean. Unlike simple moving averages, VWAP gives greater importance to prices where substantial trading occurred, reflecting true market consensus during active periods. Traders reset VWAP at anchor boundaries such as daily opens, 4-hour sessions, or monthly starts, creating fresh reference levels that adapt to each new trading period. When price trades above VWAP, it suggests bullish sentiment with buyers willing to pay premium prices; conversely, prices below VWAP indicate bearish pressure. The implementation supports flexible anchor specifications from minutes to months, with the default daily anchor aligning with standard institutional practices. Many algorithms use VWAP as a target price, attempting to achieve fills near this volume-weighted benchmark to minimize market impact.
When using candle data, this module accepts any price source string via from_candles(..., source) and defaults to hlc3 in with_default_candles.
Implementation Examples
Compute VWAP from raw arrays or candle data:
use vectorta::indicators::vwap::{vwap, VwapInput, VwapParams};
use vectorta::utilities::data_loader::{Candles, read_candles_from_csv};
// From raw slices (timestamps: ms since epoch)
let timestamps = vec![/* i64 timestamps as f64 in files; here i64 in Rust */ 1633046400000_i64, 1633046460000, 1633046520000];
let volumes = vec![1200.0, 800.0, 1500.0];
let prices = vec![100.0, 101.0, 100.5];
let params = VwapParams { anchor: Some("1d".to_string()) };
let input = VwapInput::from_slice(×tamps, &volumes, &prices, params);
let out = vwap(&input)?;
for v in out.values { println!("VWAP: {}", v); }
// From candles (defaults: source = "hlc3", anchor = "1d")
let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let input = VwapInput::with_default_candles(&candles);
let out = vwap(&input)?; API Reference
Input Methods ▼
// From raw slices (timestamps ms as i64)
VwapInput::from_slice(&[i64], &[f64], &[f64], VwapParams) -> VwapInput
// From candles with custom source (e.g., "close", "hlc3")
VwapInput::from_candles(&Candles, &str, VwapParams) -> VwapInput
// From candles plus external price vector
VwapInput::from_candles_plus_prices(&Candles, &[f64], VwapParams) -> VwapInput
// Default candles (source = "hlc3", anchor = "1d")
VwapInput::with_default_candles(&Candles) -> VwapInput Parameters Structure ▼
pub struct VwapParams {
pub anchor: Option<String>, // Default: "1d"
} Output Structure ▼
pub struct VwapOutput {
pub values: Vec<f64>, // VWAP per input index
} Validation, Warmup & NaNs ▼
timestamps.len == prices.len == volumes.lenelseVwapError::MismatchTimestampsPricesVolumes.anchormust contain a positive number and one unit; units:m,h,d,M. UppercaseH/Dnormalized.- On each anchor boundary, accumulators reset; value is
vol_price_sum/volume_sumifvolume_sum > 0, otherwiseNaN. - Month anchors use calendar-aware bucketing; invalid timestamps yield
VwapError::MonthConversionError. - Streaming:
VwapStream::updatereturnsSome(vwap)whenvolume_sum > 0, otherwiseNone.
Error Handling ▼
use vectorta::indicators::vwap::{vwap, VwapInput, VwapParams, VwapError};
match vwap(&input) {
Ok(output) => process(output.values),
Err(VwapError::MismatchTimestampsPricesVolumes { timestamps, prices, volumes }) => {
eprintln!("Length mismatch: ts={}, prices={}, vols={}", timestamps, prices, volumes);
}
Err(VwapError::MismatchPricesVolumes { prices, volumes }) => {
eprintln!("Out slice size mismatch: prices={}, dst={}", prices, volumes);
}
Err(VwapError::NoData) => eprintln!("No data provided"),
Err(VwapError::ParseAnchorError { msg }) => eprintln!("Anchor parse error: {}", msg),
Err(VwapError::UnsupportedAnchorUnit { unit_char }) => eprintln!("Unsupported unit: {}", unit_char),
Err(VwapError::MonthConversionError { ts_ms }) => eprintln!("Month conversion failed for {}", ts_ms),
} Python Bindings
Basic Usage ▼
Compute VWAP from timestamped volume and price arrays:
import numpy as np
from vectorta import vwap
# Arrays: timestamps (ms, int64), volumes/prices (float64)
timestamps = np.array([1633046400000, 1633046460000, 1633046520000], dtype=np.int64)
volumes = np.array([1200.0, 800.0, 1500.0], dtype=np.float64)
prices = np.array([100.0, 101.0, 100.5], dtype=np.float64)
# Default anchor is "1d"; kernel can be 'auto' or 'scalar'
values = vwap(timestamps, volumes, prices, anchor="1d", kernel="auto")
print(values) Streaming Real-time Updates ▼
One call per tick; returns None until volume_sum > 0 in the current anchor:
from vectorta import VwapStream
stream = VwapStream(anchor="1d")
for ts, price, vol in tick_feed:
v = stream.update(ts, price, vol)
if v is not None:
print("VWAP:", v) Batch Parameter Sweep ▼
Compute many anchors at once and inspect rows:
import numpy as np
from vectorta import vwap_batch
timestamps = np.array([...], dtype=np.int64)
volumes = np.array([...], dtype=np.float64)
prices = np.array([...], dtype=np.float64)
res = vwap_batch(timestamps, volumes, prices, anchor_range=("1d", "3d", 1), kernel="auto")
print(res['values'].shape) # (rows, cols)
print(res['anchors']) # ["1d", "2d", "3d"] CUDA Acceleration ▼
If built with CUDA, a device API is available:
# Requires build with Python + CUDA features
from vectorta import vwap_cuda_batch_dev
res_dev = vwap_cuda_batch_dev(
timestamps, volumes, prices,
anchor_range=("1d", "3d", 1),
device_id=0
)
# Returns a device-backed array wrapper (f32); see DeviceArrayF32Py JavaScript/WASM Bindings
Basic Usage ▼
Compute VWAP in JavaScript/TypeScript with timestamp, volume, and price arrays:
import { vwap_js } from 'vectorta-wasm';
const timestamps = new Float64Array([1633046400000, 1633046460000, 1633046520000]);
const volumes = new Float64Array([1200, 800, 1500]);
const prices = new Float64Array([100.0, 101.0, 100.5]);
// Anchor defaults to "1d"; kernels: 'auto' | 'scalar' | 'scalar_batch'
const values = vwap_js(timestamps, volumes, prices, '1d', 'auto');
console.log(values); Memory-Efficient Operations ▼
Use vwap_into with manual allocation:
import { vwap_alloc, vwap_free, vwap_into, memory } from 'vectorta-wasm';
const len = prices.length;
const tsPtr = vwap_alloc(len);
const volPtr = vwap_alloc(len);
const prPtr = vwap_alloc(len);
const outPtr = vwap_alloc(len);
new Float64Array(memory.buffer, tsPtr, len).set(timestamps);
new Float64Array(memory.buffer, volPtr, len).set(volumes);
new Float64Array(memory.buffer, prPtr, len).set(prices);
// Args: ts_ptr, vol_ptr, pr_ptr, out_ptr, len, anchor
vwap_into(tsPtr, volPtr, prPtr, outPtr, len, '1d');
const out = new Float64Array(memory.buffer, outPtr, len).slice();
vwap_free(tsPtr, len); vwap_free(volPtr, len); vwap_free(prPtr, len); vwap_free(outPtr, len); Batch Processing ▼
Enumerate anchors and compute all series:
import { vwap_batch, vwap_batch_metadata_js } from 'vectorta-wasm';
const anchors = vwap_batch_metadata_js('1d', '3d', 1); // ['1d','2d','3d']
const packed = vwap_batch(timestamps, volumes, prices, '1d', '3d', 1);
// 'packed' returns a flat array of size rows*len and metadata via anchors
// Reshape as needed for your UI Performance Analysis
AMD Ryzen 9 9950X (CPU) | NVIDIA RTX 4090 (GPU) | Benchmarks: 2026-01-05
Related Indicators
Arnaud Legoux Moving Average
Moving average indicator
Compound Ratio Moving Average (CoRa Wave)
Moving average indicator
Centered Weighted Moving Average
Moving average indicator
Double Exponential Moving Average
Moving average indicator
Ehlers Distance Coefficient Filter
Moving average indicator
Ehlers Error-Correcting EMA (ECEMA)
Moving average indicator