VWAP (Volume-Weighted Average Price) Execution Algorithm Development
VWAP execution algorithm is a smarter version of TWAP: instead of distributing volume evenly over time, volume is distributed proportionally to historical trading volume. More orders during high-activity hours, fewer during quiet periods. Goal: execute order at price close to market VWAP over the period.
Difference Between VWAP and TWAP
TWAP divides volume evenly over time. VWAP divides volume proportionally to typical market volume in each time interval.
Example for BTC/USDT (24-hour session): volume during 14:00–16:00 UTC (Europe-America overlap) significantly higher than 02:00–04:00 UTC (minimum activity). VWAP algorithm accounts for this.
Intraday Volume Profile Prediction
def build_volume_profile_intraday(historical_df, n_buckets=48):
"""
Build average volume for each 30-minute interval of the day
based on historical data (last 30 days)
"""
historical_df['time_bucket'] = historical_df.index.time
avg_volume = historical_df.groupby('time_bucket')['volume'].mean()
# Normalize to unity (weights should sum to 1)
weights = avg_volume / avg_volume.sum()
return weights
Execution Algorithm
class VWAPExecutor:
def __init__(self, symbol, total_qty, duration_hours, exchange):
self.total_qty = total_qty
self.volume_weights = self.load_volume_profile(symbol, duration_hours)
# slice_sizes[i] = qty for i-th interval
self.slice_sizes = [w * total_qty for w in self.volume_weights]
async def execute_interval(self, interval_idx):
target_qty = self.slice_sizes[interval_idx]
# Adapt if volume over past intervals differed from forecast
actual_volume = await self.get_market_volume(interval_idx)
expected_volume = self.expected_volumes[interval_idx]
if actual_volume > expected_volume * 1.5:
# Market more active — increase order
target_qty *= (actual_volume / expected_volume)
await self.place_order(target_qty)
Participation of Volume (POV)
Participation Rate — alternative approach: execute X% of current market volume.
target_qty_per_interval = market_volume × participation_rate (e.g., 10%)
POV guarantees minimal market impact (no more than 10% of market), but doesn't guarantee execution by deadline on low volume.
Real-Time Adaptation
If current execution lags plan (market moves unfavorably) — algorithm can:
- Execute remaining volume more aggressively
- Temporarily switch to market orders
- Extend time horizon (if allowable)
Benchmark and Reporting
| Metric | Description |
|---|---|
| Implementation Shortfall | Difference between trading decision and final execution |
| VWAP Slippage | Average fill price vs market VWAP |
| Market Impact | How much our orders moved the market |
| Fill Rate | % of executed volume |
Full execution report on completion: execution timeline, average fill price vs VWAP, slippage per interval.
Stack: Python (asyncio + CCXT), PostgreSQL for execution logs, Grafana for real-time progress visualization.







