OGT Owl Group Trading by Dr. Ken Long
Home About Learn The Loop Code Courses Essays Store Partners FAQ
Indicator Code · Owl Group Trading

VWAP - Volume-Weighted Average Price

The running average price weighted by traded volume, accumulated from the session start.

Concept: what VWAP means →

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;
}