VWAP in Python — Coding It from Scratch (pandas)

Session VWAP with a daily reset, and anchored VWAP

VWAP computed in Python
VWAP computed in Python

VWAP is a running ratio of two cumulative sums, as the explainer covered. The only real decision is when to reset — each session (the classic intraday VWAP) or never (anchored VWAP). Here’s both in pandas.

What you’ll need

  • Python 3.9+, pandas
  • Intraday OHLCV with a datetime index (for session VWAP).

Session VWAP (resets each day)

The classic intraday VWAP restarts every trading day. groupby on the date makes that clean:

import pandas as pd


def session_vwap(df: pd.DataFrame) -> pd.Series:
    typical = (df["high"] + df["low"] + df["close"]) / 3
    tpv = typical * df["volume"]

    day = df.index.normalize()                      # the calendar date per bar
    cum_tpv = tpv.groupby(day).cumsum()
    cum_vol = df["volume"].groupby(day).cumsum()
    return (cum_tpv / cum_vol).rename("vwap")

Each day, cumsum restarts, so VWAP begins fresh at the session open and accumulates through the day — exactly how desks and day traders use it.

Anchored VWAP (from a chosen point)

Anchored VWAP just accumulates from one starting index and never resets — this is what the chart above shows:

def anchored_vwap(df: pd.DataFrame, start) -> pd.Series:
    d = df.loc[start:]
    typical = (d["high"] + d["low"] + d["close"]) / 3
    return (typical * d["volume"]).cumsum() / d["volume"].cumsum()

Anchor it at an earnings date, a major high, or a swing low to see the volume-weighted fair value since that event.

VWAP bands

vwap = session_vwap(df)
typical = (df["high"] + df["low"] + df["close"]) / 3
# Volume-weighted variance around VWAP, per session.
day = df.index.normalize()
var = ((typical - vwap) ** 2 * df["volume"]).groupby(day).cumsum() / df["volume"].groupby(day).cumsum()
sd = var ** 0.5
upper, lower = vwap + 2 * sd, vwap - 2 * sd

Gotchas

  • Session VWAP needs a datetime index. The daily reset depends on grouping by date; on a plain integer index you can only do anchored VWAP.
  • Typical price. The standard uses (H+L+C)/3. Some use close only — pick one and be consistent.
  • Real volume required. Garbage volume in, garbage VWAP out. Spot forex has no central volume, so VWAP there is at best a proxy.

The lazy one-liner

import pandas_ta as ta
df["vwap"] = ta.vwap(df["high"], df["low"], df["close"], df["volume"])   # session VWAP

Same indicator elsewhere: MQL5, Pine Script, EasyLanguage, NinjaScript.


This post is educational, not financial advice. Indicators describe the past; they don’t predict the future. Backtest anything before you risk real money on it.

Sources and further reading

  1. GroupBy cumulative sum reference (pandas documentation)
  2. The Total Cost of Transactions on the NYSE (The Journal of Finance)
  3. Windowing operations (pandas documentation)

Historical research from the Algogen archive. Not investment advice.

Blog

Have a strategy idea?

Describe it in plain English, preview where your rules fire, then decide whether the evidence is worth a backtest.

Keep me postedHow it works