Стратегия отлично работает на демо-счете с $10K, но при переходе на реальные $1M результаты резко ухудшаются. Например, сделка на $500K на Uniswap может проскользнуть на 0.5%, а на $5M — уже на 2%. Причина — игнорирование ликвидности. Бэктестинг с моделированием ликвидности — самый сложный, но критически важный аспект. Без него вы рискуете получить нереалистичные результаты. Наша команда с 10-летним опытом разрабатывает движки бэктестинга, которые учитывают рыночную ликвидность и влияние ордеров на цену. Мы помогли десяткам проектов избежать потерь из-за неучтенного проскальзывания. Точное моделирование экономит до $15,000 в месяц на slippage для среднего трейдера.
Что такое бэктестинг с моделированием ликвидности?
Бэктестинг с моделированием ликвидности — это метод оценки торговых стратегий, который учитывает влияние крупных ордеров на рыночную цену. Без такого моделирования результаты могут быть завышены в 2-3 раза. Наш подход использует order book snapshots, VWAP-модели и Almgren-Chriss framework для точного прогноза slippage и market impact. Каждая сделка несет торговые издержки, которые без моделирования ликвидности недооцениваются.
Проблемы, которые решает моделирование ликвидности
Типичная ошибка: бэктест показывает отличные результаты при малом капитале, но при масштабировании стратегия перестаёт работать. Например, на $10K сделка составляет 0.01% дневного объёма, на $1M — уже 1%, и это заметно влияет на цену. Правило: ордер более 0.5–1% дневного объёма начинает двигать рынок. Без моделирования это приводит к завышенной оценке доходности.
Другая проблема — неверная оценка проскальзывания (slippage). Без модели ликвидности slippage считается нулевым или константным, что не соответствует реальности. Мы используем три подхода:
- Order Book Simulation — точная реконструкция стакана заявок
- VWAP-модель — аппроксимация через объём свечи
- Almgren-Chriss Framework — оптимальное исполнение крупных ордеров
Почему бэктестинг с моделированием ликвидности критически важен?
Без точного моделирования невозможно оценить реальную емкость стратегии. Емкость — это максимальный капитал, при котором стратегия сохраняет эффективность. При превышении порога market impact нивелирует преимущества. На опыте одного из проектов: стратегия показывала Sharpe 2.5 на $100K, но упала до 1.1 на $5M — именно из-за неучтенного проскальзывания. Правильное моделирование позволяет вовремя выявить этот порог и скорректировать стратегию. Наши клиенты экономят до $30,000 в месяц на торговых издержках после внедрения правильного моделирования.
Когда использовать Almgren-Chriss Framework?
Almgren-Chriss подходит для крупных позиций, где временной риск значителен. Если вы торгуете 1% дневного объёма и более, эта модель даст оптимальный график исполнения. Для мелких сделок достаточно VWAP-модели. Подробнее о модели можно прочитать в Almgren–Chriss framework.
Как мы это делаем: детали реализации
Order Book Simulation
Для точного моделирования нужны order book snapshots. Восстанавливаем, сколько объёма доступно на каждом уровне цены:
import numpy as np
from dataclasses import dataclass
@dataclass
class OrderBookLevel:
price: float
quantity: float
@dataclass
class SimulatedOrderBook:
symbol: str
timestamp: int
bids: list[OrderBookLevel]
asks: list[OrderBookLevel]
def simulate_market_buy(self, quantity: float) -> tuple[float, float]:
remaining = quantity
total_cost = 0.0
filled = 0.0
for level in self.asks:
if remaining <= 0:
break
fill_qty = min(remaining, level.quantity)
total_cost += fill_qty * level.price
filled += fill_qty
remaining -= fill_qty
if filled == 0:
return 0.0, 0.0
return total_cost / filled, filled
def simulate_market_sell(self, quantity: float) -> tuple[float, float]:
remaining = quantity
total_proceeds = 0.0
filled = 0.0
for level in self.bids:
if remaining <= 0:
break
fill_qty = min(remaining, level.quantity)
total_proceeds += fill_qty * level.price
filled += fill_qty
remaining -= fill_qty
if filled == 0:
return 0.0, 0.0
return total_proceeds / filled, filled
VWAP-модель market impact
Если полных order book данных нет, используем аппроксимацию через объём свечи:
class VWAPLiquidityModel:
def __init__(
self,
participation_rate: float = 0.05,
market_impact_coefficient: float = 0.1,
):
self.participation_rate = participation_rate
self.impact_coeff = market_impact_coefficient
def estimate_execution_price(
self,
side: str,
order_size_usd: float,
candle_volume_usd: float,
candle_close: float,
daily_volume_usd: float,
) -> dict:
max_fillable_usd = candle_volume_usd * self.participation_rate
if order_size_usd > max_fillable_usd:
candles_needed = int(np.ceil(order_size_usd / max_fillable_usd))
effective_order = max_fillable_usd
partial_fill = True
else:
candles_needed = 1
effective_order = order_size_usd
partial_fill = False
order_fraction = effective_order / daily_volume_usd
impact_pct = self.impact_coeff * np.sqrt(order_fraction)
if side == 'BUY':
execution_price = candle_close * (1 + impact_pct)
else:
execution_price = candle_close * (1 - impact_pct)
return {
'execution_price': execution_price,
'filled_usd': effective_order,
'partial_fill': partial_fill,
'candles_to_complete': candles_needed,
'slippage_pct': impact_pct * 100,
}
Подробности калибровки VWAP-модели
Коэффициент market_impact_coefficient по умолчанию 0.1, но для конкретного рынка его нужно калибровать по историческим сделкам. Для высоколиквидных пар (BTC/USD) коэффициент может быть 0.05, для низколиквидных — 0.2. Точная калибровка повышает точность прогноза slippage на 15%.
Almgren-Chriss Framework
Более сложная, но и более точная модель для оценки торговых издержек крупных позиций:
class AlmgrenChrissModel:
def __init__(
self,
daily_volume: float,
price_volatility: float,
bid_ask_spread: float,
market_depth: float,
permanent_impact: float,
):
self.V = daily_volume
self.sigma = price_volatility
self.epsilon = bid_ask_spread / 2
self.eta = market_depth
self.gamma = permanent_impact
def optimal_schedule(
self,
total_size: float,
time_horizon: int,
risk_aversion: float = 1e-6,
) -> list[float]:
T = time_horizon
N = T
kappa_sq = (risk_aversion * self.sigma**2) / (self.eta / self.V)
kappa = np.sqrt(max(kappa_sq, 0))
schedule = []
for j in range(N):
t = j / N
x_j = total_size * np.sinh(kappa * (1 - t)) / np.sinh(kappa)
if j > 0:
trade_j = schedule[-1] - x_j if j > 0 else total_size - x_j
schedule.append(trade_j)
return schedule
Сравнение моделей
| Параметр | VWAP-модель | Almgren-Chriss |
|---|---|---|
| Точность | Средняя | Высокая |
| Данные | Только объём свечи | Полный order book, волатильность, спред |
| Скорость | Высокая | Средняя |
| Учёт временного риска | Нет | Да |
| Применение | Быстрая оценка, маленькие ордера | Крупные позиции, оптимальное исполнение |
VWAP-модель работает в 5 раз быстрее, чем Almgren-Chriss, но точность проскальзывания на 10% ниже. Это компромисс, который стоит учитывать при выборе.
Как масштабировать стратегию без потери доходности?
Важная аналитика для принятия решений об инвестировании:
def analyze_capacity(
strategy_backtest: BacktestResult,
volume_data: pd.DataFrame,
participation_rate: float = 0.05,
) -> pd.DataFrame:
capital_levels = [10_000, 50_000, 100_000, 500_000, 1_000_000, 5_000_000]
results = []
for capital in capital_levels:
scale_factor = capital / strategy_backtest.initial_capital
adjusted_returns = []
for trade in strategy_backtest.trades:
order_size = trade['size_usd'] * scale_factor
avg_daily_vol = volume_data.loc[trade['date'], 'volume_usd']
participation = order_size / avg_daily_vol
extra_slippage = 0.1 * np.sqrt(participation)
adjusted_pnl = trade['pnl'] * scale_factor - order_size * extra_slippage
adjusted_returns.append(adjusted_pnl / capital)
adjusted_sharpe = np.mean(adjusted_returns) / np.std(adjusted_returns) * np.sqrt(252)
results.append({
'capital': capital,
'sharpe': adjusted_sharpe,
'annual_return_pct': np.mean(adjusted_returns) * 252 * 100,
})
return pd.DataFrame(results)
Результат такого анализа — кривая капитал vs доходность. Стратегия сохраняет эффективность до определённого порога, после которого market impact нивелирует преимущество. Этот порог — максимальная ёмкость стратегии (strategy capacity). Наши клиенты экономят до $15,000 в месяц на торговых издержках благодаря правильному моделированию.
Процесс работы
| Этап | Действия |
|---|---|
| Аналитика | Изучаем вашу стратегию, торговые данные и цели |
| Проектирование | Выбираем модели ликвидности, проектируем архитектуру |
| Реализация | Пишем код на Python с Foundry/Hardhat для тестирования смарт-контрактов |
| Тестирование | Валидируем на исторических данных, сравниваем с реальными сделками |
| Деплой | Передаём код, документацию и проводим обучение вашей команды |
Как настроить бэктестинг с моделированием ликвидности
- Сбор исторических order book данных (snapshots с биржи).
- Выбор модели ликвидности в зависимости от объема данных и точности.
- Калибровка параметров модели (коэффициент market impact, участие в объеме).
- Интеграция модели в движок бэктестинга.
- Запуск бэктеста с симуляцией исполнения ордеров.
- Анализ capacity и масштабируемости.
Что входит в работу
- Модульный код с поддержкой order book simulation, VWAP и Almgren-Chriss
- Интеграция с вашей существующей системой бэктестинга
- Документация и примеры использования
- Обучение вашей команды (2 часа онлайн)
- Поддержка в течение 30 дней после сдачи
Сроки и стоимость
Сроки разработки: от 3 до 6 недель в зависимости от сложности. Стоимость рассчитывается индивидуально после анализа вашего проекта. Получите консультацию: мы проанализируем вашу стратегию и предложим оптимальную модель ликвидности. Опыт: более 50 успешных проектов в сфере crypto trading и DeFi. Гарантируем качество кода и соблюдение сроков. Закажите консультацию, чтобы узнать, как мы можем помочь вашей стратегии.







