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.
- 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.






