Разработка алгоритма TWAP (Time-Weighted Average Price)
TWAP (Time-Weighted Average Price) — алгоритм исполнения крупных ордеров путём равномерного распределения объёма во времени. Цель не в получении прибыли от движения цены, а в минимизации рыночного влияния при исполнении: крупный ордер, выставленный единовременно, сдвинет цену против себя. TWAP делит его на равные части через равные интервалы.
Принцип работы
Нужно купить 100 BTC за 4 часа без сильного влияния на рынок:
Каждые 10 минут: купить 100/24 ≈ 4.17 BTC
Всего 24 интервала × 4.17 BTC = 100 BTC
Простой TWAP: равные доли через равные временные интервалы.
Адаптивный TWAP учитывает рыночные условия:
- Пропускаем интервал если текущая цена значительно выше TWAP (не покупаем дорого)
- Увеличиваем размер ордера если цена ниже текущего TWAP
- Пауза при аномально высокой волатильности
Реализация
import asyncio
from datetime import datetime, timedelta
class TWAPExecutor:
def __init__(self, symbol, total_qty, duration_minutes, exchange):
self.symbol = symbol
self.total_qty = total_qty
self.n_slices = duration_minutes // 5 # каждые 5 минут
self.slice_qty = total_qty / self.n_slices
self.exchange = exchange
self.executed_qty = 0
async def execute(self):
interval = (5 * 60) # секунды
for i in range(self.n_slices):
await self.execute_slice()
if i < self.n_slices - 1:
await asyncio.sleep(interval)
async def execute_slice(self):
remaining = self.total_qty - self.executed_qty
qty = min(self.slice_qty, remaining)
# Используем limit order близко к mid-price для экономии на fees
ticker = await self.exchange.fetch_ticker(self.symbol)
mid_price = (ticker['bid'] + ticker['ask']) / 2
limit_price = mid_price * 1.0005 # 0.05% выше mid
order = await self.exchange.create_limit_buy_order(
self.symbol, qty, limit_price
)
self.executed_qty += qty
return order
Limit vs Market orders в TWAP
Market orders: гарантированное исполнение, но худшая цена. Slippage на BTC может быть 0.02–0.1% на объёме > $100K.
Limit orders: лучшая цена, но риск неисполнения. Если за интервал ордер не исполнился — конвертируем в market ближе к концу интервала.
Hybrid подход: выставляем limit немного агрессивнее mid. Если через 80% интервала неисполнен — snipe через market order.
TWAP benchmark и оценка качества
Execution quality = среднее исполнение vs рыночный TWAP за период:
TWAP_benchmark = Σ(price_i × volume_i) / Σ(volume_i) за период исполнения
Если алгоритм купил по average price ниже рыночного TWAP — хорошее исполнение. Выше — плохое.
Slippage report: для каждого слайса фиксируем: цена quote, цена fill, bid/ask spread в момент исполнения.
Применения
- Исполнение крупных ордеров фондов без движения рынка
- Регулярные DCA (Dollar Cost Averaging) покупки
- Liquidation крупных позиций
- Rebalancing портфеля
Стек: Python (asyncio + CCXT), PostgreSQL для хранения ордеров и execution report, REST API для управления (запуск, остановка, статус исполнения). Уведомления о прогрессе через Telegram.







