trading4 Min Read

Execution Algorithms: VWAP & TWAP in Python

Gorav Singal

October 30, 2026

TL;DR

A big order can't be dumped at once — it eats through the order book and moves the price against you (market impact). So you SLICE the parent order into small child orders over the day. TWAP (Time-Weighted Average Price) trades equal slices every interval — simple, ignores volume. VWAP (Volume-Weighted Average Price) trades in proportion to the day's volume curve — more when the market is liquid (open/close), less in thin midday minutes — so it leaves a smaller footprint. The Python for both schedules is here, plus a simple impact model. On a simulated 100k-share fill, TWAP cost +105 bps vs the arrival price and VWAP +92 bps — about 13 bps cheaper. 'Did you beat the day's VWAP?' is literally how execution desks are graded. This is execution, not alpha — but it decides how much of your edge survives the fill.

Execution Algorithms: VWAP & TWAP in Python

Every strategy so far produced signals — when to be long, short, or flat. But a signal is worthless until you actually fill the order, and filling a big order is its own hard problem. This is execution, and it’s where a surprising amount of real-world edge is won or lost. It’s also the part retail traders ignore and professionals obsess over.

A note up front: educational material, not financial advice. Nothing here is a recommendation to trade.

The problem: you can’t just dump it

Suppose you want to buy 100,000 shares. If you send one market order, you eat through the order book — you fill the best ask, then the next, then the next, each worse than the last — and your own buying pushes the price up against you. That’s market impact, and on a big order it can cost far more than commissions and spread combined.

The fix is to slice the big “parent” order into many small “child” orders spread over time, each small enough to be absorbed without moving the price much. The question is: on what schedule? The two standard answers are TWAP and VWAP.

Execution algorithms TWAP vs VWAP: a U-shaped market-volume curve through the day; TWAP schedules equal slices across time (a flat line), VWAP schedules slices in proportion to volume (following the curve), trading more when liquid and less in thin minutes. VWAP leaves a smaller footprint.

  • TWAP (Time-Weighted Average Price) — slice the order evenly over time: same size every minute. Dead simple, predictable, and it ignores how much the market is actually trading.
  • VWAP (Volume-Weighted Average Price) — slice in proportion to the volume curve: trade more when the market is busy (typically near the open and close) and less in the thin midday lull. By matching your participation to available liquidity, you leave a smaller footprint — you’re never the elephant in a thin market.

Building both schedules in Python

import numpy as np

Q = 100_000          # parent order: buy 100k shares
mins = 390           # a 6.5-hour trading day in minutes

# A realistic U-shaped intraday volume curve (busy at open & close)
x = np.linspace(0, 1, mins)
vol_curve = 1.5 - np.sin(np.pi * x)
vol_curve /= vol_curve.sum()          # normalise to fractions of the day
market_vol = vol_curve * 1_000_000    # the market trades ~1M shares today

# TWAP: equal shares each minute. VWAP: proportional to the volume curve.
twap_schedule = np.full(mins, Q / mins)
vwap_schedule = Q * vol_curve

# A simple temporary-impact model: filling x% of a minute's volume
# costs ~k * participation, added to the price (you're buying).
price = 500 + np.cumsum(np.random.default_rng(5).normal(0, 0.03, mins))
k = 0.1
def avg_fill(schedule):
    participation = schedule / market_vol
    fill_price = price + k * participation * price   # impact pushes price up
    return (fill_price * schedule).sum() / schedule.sum()

arrival = price[0]
for name, sched in [("TWAP", twap_schedule), ("VWAP", vwap_schedule)]:
    px = avg_fill(sched)
    print(f"{name}: avg fill {px:.2f}  ->  {(px-arrival)/arrival*1e4:+.1f} bps vs arrival")

TWAP is one line (Q / mins each minute); VWAP is the parent size times the volume curve. The impact model is deliberately simple — the more of a minute’s volume you take, the more you move the price — but it captures the essential dynamic.

The measured difference

On a simulated 100,000-share buy over one day:

schedule avg fill vs arrival price
TWAP +105 bps
VWAP +92 bps

VWAP came in about 13 basis points cheaper — because it didn’t force size into the thin midday minutes where each share had more impact. On 100,000 shares at ₹500, 13 bps is roughly ₹65,000 saved on a single order, for zero change in strategy. That’s why execution matters: it’s free money (or free savings) that compounds over every trade you ever make.

Note the benchmark itself: “did you beat the day’s VWAP?” is literally how execution desks are measured. Beating VWAP means you filled better than the average participant that day; missing it means you left money on the table. Entire teams exist to shave basis points off execution.

Execution is not alpha — but it protects alpha

The crucial framing: VWAP/TWAP don’t make you money the way a strategy does. They decide how much of the edge you already have actually survives the fill. A strategy with a 20 bps edge per trade that loses 15 bps to sloppy execution keeps only 5. Good execution is the difference between a profitable strategy and a break-even one — especially for anything that trades frequently or in size, where slippage silently eats the gross edge. (The trading course has a whole lesson on exactly this: how costs and slippage turn a profitable-looking gross edge into a net loss.)

A few practical notes:

  • Retail small orders usually don’t need this — if you’re buying 100 shares of a liquid stock, a market order is fine. Execution algos matter when your order is large relative to the available liquidity.
  • Implementation shortfall is the more sophisticated cousin: it explicitly trades off impact (go slow, trade small) against timing risk (the price drifts away while you wait), and front-loads or back-loads accordingly.
  • Participation-rate (POV) algos cap you at, say, 10% of volume at all times, so you never dominate the book.

Takeaways

  • A big order moves the price against you (market impact), so you slice it into small child orders over time.
  • TWAP = equal slices across time (simple). VWAP = slices that follow the volume curve (trade more when liquid, less when thin) → smaller footprint.
  • Measured on a 100k-share fill: VWAP beat TWAP by ~13 bps — real money, for free. “Beat the day’s VWAP” is the industry’s execution benchmark.
  • Execution is not alpha — but it decides how much of your alpha survives. For frequent or large trading, it’s the difference between profit and break-even.

Next: a role that lives entirely in execution and the spread — market making, where you provide liquidity instead of taking it, and fight inventory risk for a living.

Share

Related Posts

Position Sizing & the Kelly Criterion in Python

Position Sizing & the Kelly Criterion in Python

Every strategy article so far asked ”what should I trade?” This one asks the…

Momentum & Trend Following in Python

Momentum & Trend Following in Python

Momentum is, along with value, one of the most robust and widely-documented…

Mean Reversion & Pairs Trading in Python

Mean Reversion & Pairs Trading in Python

The moving-average crossover bet on direction and lost. Here’s a strategy with a…

The Moving-Average Crossover, Backtested Honestly in Python

The Moving-Average Crossover, Backtested Honestly in Python

If algo trading has a “hello world,” it’s the moving-average crossover. Every…

Market Making Basics: Spread Capture vs Inventory Risk (in Python)

Market Making Basics: Spread Capture vs Inventory Risk (in Python)

So far you’ve been a taker — crossing the spread to get filled. A market maker…

Order-Book Imbalance: A Microstructure Signal (in Python)

Order-Book Imbalance: A Microstructure Signal (in Python)

The strategies so far used daily or minute bars. This last one goes down to the…

Latest Posts

Position Sizing & the Kelly Criterion in Python

Position Sizing & the Kelly Criterion in Python

Every strategy article so far asked ”what should I trade?” This one asks the…

Momentum & Trend Following in Python

Momentum & Trend Following in Python

Momentum is, along with value, one of the most robust and widely-documented…

Mean Reversion & Pairs Trading in Python

Mean Reversion & Pairs Trading in Python

The moving-average crossover bet on direction and lost. Here’s a strategy with a…

The Moving-Average Crossover, Backtested Honestly in Python

The Moving-Average Crossover, Backtested Honestly in Python

If algo trading has a “hello world,” it’s the moving-average crossover. Every…

Market Making Basics: Spread Capture vs Inventory Risk (in Python)

Market Making Basics: Spread Capture vs Inventory Risk (in Python)

So far you’ve been a taker — crossing the spread to get filled. A market maker…

Order-Book Imbalance: A Microstructure Signal (in Python)

Order-Book Imbalance: A Microstructure Signal (in Python)

The strategies so far used daily or minute bars. This last one goes down to the…