Optimal Execution Algorithms: TWAP, VWAP & Market Impact › Schedule-Based Algorithms

Michael BrenndoerferJanuary 20, 20257 min read
Quantitative FinanceAll chapters
Part 12 of 15Market Making and High-Frequency Trading
Chapter 68Optimal Execution Algorithms: TWAP, VWAP & Market Impact › Schedule-Based Algorithms
Reading section 3 of 10 · Schedule-Based Algorithms · 7 minSection 3 of 10 · 7 min

Book contents

Section 3 of 10 · 7 min read

Optimal Execution Algorithms: TWAP, VWAP & Market Impact › Schedule-Based AlgorithmsOne section · Sections in this chapter3 / 10 ↓
Reading tools Definitions & inline links

Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.

Article links

Make inline references clickable

Schedule-based algorithms follow predetermined trading patterns, executing orders according to fixed rules regardless of short-term market conditions. Their simple, transparent rules make them common execution benchmarks.

Time-Weighted Average Price (TWAP)

The simplest execution algorithm is TWAP, which divides the total order into equal-sized pieces and executes one piece at regular intervals throughout the trading period. The logic behind TWAP is straightforward: without any information about when liquidity will be available or when prices might be favorable, the most sensible approach for you is to spread risk evenly across time.

For an order of XX shares executed over NN intervals of duration Δt\Delta t, TWAP trades at a constant rate. In continuous time, this rate is simply the total shares divided by the total duration:

vTWAP=XTv_{\text{TWAP}} = \frac{X}{T}

where:

  • vTWAPv_{\text{TWAP}}: trading rate in shares per unit time
  • XX: total order size
  • TT: total duration

This formula expresses a fundamental principle: TWAP commits to a fixed pace of execution that does not vary regardless of market activity. Whether the market is quiet or hectic, or whether spreads are narrow or wide, the algorithm continues trading at the same steady rate.

Equivalently, in discrete intervals where the trading day is divided into NN equal periods:

qn=XNq_n = \frac{X}{N}

where:

  • qnq_n: shares traded in interval nn
  • XX: total order size
  • NN: number of intervals

Each interval receives exactly the same allocation of shares. The index nn ranges from 1 to NN, and every interval is treated identically regardless of its position in the sequence or the market conditions prevailing at that time.

TWAP's appeal lies in its simplicity: it requires no forecasting of volume patterns, no estimation of market impact parameters, and no optimization. You can implement TWAP with nothing more than a clock and a calculator. The algorithm performs well when true trading costs are linear in execution rate and when the trader has no information about intraday volume patterns. In such circumstances, there is no basis for preferring one time period over another; equal treatment of all periods is the natural choice.

In[3]:
Code
import numpy as np


def generate_twap_schedule(total_shares: int, num_intervals: int) -> np.ndarray:
    """Generate a TWAP execution schedule."""
    shares_per_interval = total_shares / num_intervals
    return np.full(num_intervals, shares_per_interval)


# Example: Execute 100,000 shares over 20 intervals
total_order = 100_000
intervals = 20
twap_schedule = generate_twap_schedule(total_order, intervals)
Out[4]:
Console
TWAP Schedule for 100,000 shares over 20 intervals:
Shares per interval: 5,000
Total scheduled: 100,000

The output confirms that the algorithm divides the total order into equal chunks, so a constant trading rate regardless of market activity or price movements.

Volume-Weighted Average Price (VWAP)

VWAP improves on TWAP by executing in proportion to expected market volume. The key insight motivating VWAP is that markets naturally absorb more trading during high-volume periods, so concentrating execution during these times reduces market impact. Think of it this way. If one million shares trade during the open but only one hundred thousand during lunch, submitting your large order during the open will constitute a smaller fraction of total activity and therefore have less price impact.

If VnV_n represents the expected volume in interval nn and Vtotal=∑nVnV_{\text{total}} = \sum_n V_n is total expected volume across all intervals, then VWAP allocates shares according to the volume weights:

qn=X⋅VnVtotalq_n = X \cdot \frac{V_n}{V_{\text{total}}}

where:

  • qnq_n: target shares to trade in interval nn
  • XX: total order size
  • VnV_n: expected volume in interval nn
  • VtotalV_{\text{total}}: total expected volume

This formula ensures that the algorithm participates at a consistent rate relative to market activity. When volume is high, the algorithm trades more shares. When volume is low, the algorithm trades fewer shares. The ratio Vn/VtotalV_n / V_{\text{total}} represents the fraction of daily volume expected in interval nn, and this same fraction is applied to the total order size.

The VWAP benchmark itself, which gives the algorithm its name, is defined as the volume-weighted average of all prices observed during the trading period:

VWAP=∑n=1NPn⋅Vn∑n=1NVn\text{VWAP} = \frac{\sum_{n=1}^{N} P_n \cdot V_n}{\sum_{n=1}^{N} V_n}

where:

  • VWAP\text{VWAP}: volume-weighted average price benchmark
  • PnP_n: price in interval nn
  • VnV_n: volume in interval nn
  • NN: total number of intervals

This benchmark represents the average price at which all market participants traded during the period, with more weight given to prices during high-volume intervals. A VWAP algorithm aims to achieve an average execution price close to this benchmark. If the algorithm executes exactly according to the volume profile, it will by construction achieve a price equal to the market VWAP, assuming prices don't move in response to the algorithm's own trading.

In[5]:
Code
import numpy as np


def generate_vwap_schedule(
    total_shares: int, volume_profile: np.ndarray
) -> np.ndarray:
    """Generate a VWAP execution schedule based on expected volume profile."""
    volume_weights = volume_profile / volume_profile.sum()
    return total_shares * volume_weights


# Typical U-shaped intraday volume pattern
# Higher volume at open and close, lower during midday
def create_intraday_volume_profile(num_intervals: int) -> np.ndarray:
    """Create a realistic U-shaped intraday volume profile."""
    x = np.linspace(0, 1, num_intervals)
    # U-shape: high at endpoints, low in middle
    profile = 1 + 0.8 * (2 * (x - 0.5) ** 2)
    return profile / profile.sum()


volume_profile = create_intraday_volume_profile(intervals)
vwap_schedule = generate_vwap_schedule(total_order, volume_profile)
Out[6]:
Visualization
Bar chart with uniform bar heights representing equal share allocation across all 20 trading intervals.
TWAP execution schedule distributing 100,000 shares evenly across 20 intervals. The constant allocation per interval demonstrates predictable, equal treatment of time, but forgoes opportunities to adapt to actual intraday liquidity patterns.
Bar chart with higher bars at the first and last intervals and a trough at midday, showing U-shaped volume-weighted allocation.
VWAP execution schedule for 100,000 shares following a U-shaped intraday volume pattern: execution concentrates at high-volume periods during market open and close while declining during midday, minimizing market impact by maintaining consistent proportional participation with available liquidity.

The figure illustrates a key difference between the two approaches. TWAP maintains constant execution throughout the day, while VWAP front-loads and back-loads execution to match the typical U-shaped volume pattern observed in equity markets.

Limitations of Schedule-Based Algorithms

While simple and transparent, schedule-based algorithms have significant limitations:

  • No adaptation to conditions: They execute regardless of whether the spread is wide, the order book is thin, or prices are moving adversely
  • Predictability: Sophisticated market participants can detect and exploit predictable execution patterns
  • Benchmark mismatch: Matching a volume-weighted benchmark may not align with minimizing actual execution cost

TWAP performs poorly when volume varies significantly throughout the day, while VWAP can underperform when the actual volume distribution differs from the historical pattern used for scheduling. Both approaches ignore the trader's risk preferences and the specific characteristics of the security being traded.