Розробка VWAP (Volume-Weighted Average Price) алгоритму виконання
VWAP execution алгоритм — більш розумна версія TWAP: замість рівномірного розподілу за часом, обсяг розподіляється пропорційно історичному торговому обсягу. У години високої активності розміщується більше ордерів, у тихі періоди — менше. Мета — виконати ордер по ціні, близькій до ринкового VWAP за період.
Відмінність VWAP від TWAP
TWAP ділить обсяг рівномірно за часом. VWAP ділить обсяг пропорційно типовому ринковому обсягу в кожен часовий інтервал.
Приклад для BTC/USDT (24-годинна сесія): обсяг у 14:00–16:00 UTC (перекриття Європи та Америки) значно вищий, ніж у 02:00–04:00 UTC (мінімальна активність). VWAP алгоритм це враховує.
Передбачення intraday volume profile
def build_volume_profile_intraday(historical_df, n_buckets=48):
"""
Будуємо середній обсяг для кожного 30-хвилинного інтервалу дня
на основі історичних даних (останні 30 днів)
"""
historical_df['time_bucket'] = historical_df.index.time
avg_volume = historical_df.groupby('time_bucket')['volume'].mean()
# Нормалізуємо до одиниці (ваги повинні суму в 1)
weights = avg_volume / avg_volume.sum()
return weights
Алгоритм виконання
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 для i-го інтервалу
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]
# Адаптуємо якщо обсяг за попередні інтервали відрізнявся від прогнозу
actual_volume = await self.get_market_volume(interval_idx)
expected_volume = self.expected_volumes[interval_idx]
if actual_volume > expected_volume * 1.5:
# Ринок активніший — збільшуємо ордер
target_qty *= (actual_volume / expected_volume)
await self.place_order(target_qty)
Участь у ринковому обсягу (POV)
Participation Rate — альтернативний підхід: виконувати X% від поточного ринкового обсягу.
target_qty_per_interval = market_volume × participation_rate (наприклад, 10%)
POV гарантує мінімальний ринковий вплив (не більше 10% ринку), але не гарантує виконання до deadline при низькому обсязі.
Адаптація у реальному часі
Якщо поточне виконання відстає від плану (ринок рухається невигідно) — алгоритм може:
- Агресивніше виконувати залишок обсягу
- Тимчасово перейти на market orders
- Розширити часовий горизонт (якщо допустимо)
Benchmark та звітність
| Метрика | Описання |
|---|---|
| Implementation Shortfall | Різниця між рішенням торгувати та фінальним виконанням |
| VWAP Slippage | Average fill price vs ринковий VWAP |
| Market Impact | Наскільки наші ордери рухали ринок |
| Fill Rate | % виконаного обсягу |
Повний execution report після завершення: timeline виконання, середня ціна fill vs VWAP, slippage по кожному інтервалу.
Стек: Python (asyncio + CCXT), PostgreSQL для execution logs, Grafana для visualisation прогресу виконання у реальному часі.







