Indicator Code · Owl Group Trading
VWAP - Volume-Weighted Average Price
The running average price weighted by traded volume, accumulated from the session start.
VWAP is the cumulative sum of each bar's typical price times its volume, divided by the cumulative volume, measured from the first bar of the session. It answers "what is the average price everyone actually paid so far today, weighted by how much traded?" Because it weights by volume, VWAP acts as an intraday fair-value anchor and a common reference for whether price is trading rich or cheap relative to the day's flow.
Verified. Python and JavaScript implementations agree to
0.00e+00 on a 60-bar reference OHLCV series (Python vs JavaScript, comparable positions).Pythonpermalink →
def vwap(high, low, close, volume):
"""Session VWAP.
Running cumulative (typical_price * volume) / cumulative volume,
accumulated from the first bar. Typical price = (H + L + C) / 3.
Faithful port of edge-canvas calcVWAP and the inner loop of
edge-transform CoreIndicators.calc_vwap. Bars with missing H/L/C or
zero/falsy volume do not advance the accumulator; they carry forward
the prior VWAP (or None until any volume has accumulated).
Args:
high, low, close, volume: equal-length sequences of floats.
Returns:
list of VWAP values (None before any volume accumulates).
"""
n = len(close)
out = [None] * n
cum_tpv = 0.0 # cumulative typical-price * volume
cum_vol = 0.0 # cumulative volume
for i in range(n):
h, l, c, v = high[i], low[i], close[i], volume[i]
# Skip incomplete bars: carry forward the running VWAP.
if h is None or l is None or c is None or not v:
out[i] = cum_tpv / cum_vol if cum_vol > 0 else None
continue
tp = (h + l + c) / 3.0 # typical price
cum_tpv += tp * v
cum_vol += v
out[i] = cum_tpv / cum_vol if cum_vol > 0 else None
return out
JavaScriptpermalink →
/**
* Session VWAP.
*
* Running cumulative (typicalPrice * volume) / cumulative volume,
* accumulated from the first bar. Typical price = (high + low + close) / 3.
*
* Bars with a missing high/low/close or zero/falsy volume do not advance
* the accumulator; they carry forward the prior VWAP (or null until any
* volume has accumulated).
*
* @param {Array<{high:number,low:number,close:number,volume:number}>} candles
* @returns {Array<number|null>} VWAP per bar (null before any volume accumulates)
*/
export function vwap(candles) {
const len = candles.length;
const result = new Array(len).fill(null);
if (!len) return result;
let cumTPV = 0; // cumulative typical-price * volume
let cumVol = 0; // cumulative volume
for (let i = 0; i < len; i++) {
const { high, low, close, volume } = candles[i];
// Skip incomplete bars: carry forward the running VWAP.
if (high == null || low == null || close == null || !volume) {
result[i] = cumVol > 0 ? cumTPV / cumVol : null;
continue;
}
const tp = (high + low + close) / 3; // typical price
cumTPV += tp * volume;
cumVol += volume;
result[i] = cumVol > 0 ? cumTPV / cumVol : null;
}
return result;
}
Improve Your Craft Every Morning
Daily commentary from Dr. Ken Long — what he's seeing in markets, how he's framing trades, and what's worth practicing today. Free.
Your email:
Tue–Fri mornings. Unsubscribe anytime. No spam, no hype.