Вы провели backtest стратегии — 40% годовых при просадке 15%. Через месяц реального счёта — минус 30% капитала. Знакомо? Исторический backtest показывает только одну реализацию. Чтобы увидеть полный спектр возможных исходов, нужна Monte Carlo симуляция. Мы разрабатываем систему, которая отвечает на вопросы, недоступные обычному backtest: какова вероятность потерять 20% капитала за полгода, выдержит ли стратегия затяжной drawdown.
В отличие от одиночного исторического пути, Monte Carlo генерирует тысячи альтернативных сценариев из тех же трейдов, давая вероятностную оценку доходности и риска. Например, при 10 000 симуляций вы получаете распределение доходности: медианное значение 40%, но 5-й процентиль — минус 20%. Это меняет подход к управлению капиталом. Такой анализ незаменим для хедж-фондов, проп-трейдеров и частных инвесторов, желающих понять реальные риски.
Зачем Monte Carlo для торговли
Единственная backtest-кривая — случайность. Исторический backtest — один реализованный путь из бесконечного числа возможных. Трейды случались в конкретном порядке, при конкретной рыночной волатильности. Monte Carlo симуляция многократно перемешивает трейды или генерирует новые из статистической модели, создавая распределение возможных исходов.
Ключевые результаты, которые вы получаете:
- Доверительный интервал для ожидаемой доходности (5-й, 50-й, 95-й процентили)
- Вероятность конкретного уровня drawdown (например, 20%)
- Требуемый начальный капитал для выживания с вероятностью 95%
- Ожидаемое время до восстановления после просадки
Какие методы Monte Carlo мы используем?
Мы применяем два основных подхода: рандомизацию трейдов и параметрическое моделирование. Рандомизация проста и не требует предположений о распределении, но не учитывает временные зависимости. Параметрические модели, такие как GBM или Student-t, лучше экстраполируют, но требуют подбора распределения. Выбор метода зависит от ваших данных и целей. Иногда мы используем машинное обучение для оценки параметров распределения.
| Метод |
Преимущества |
Недостатки |
| Рандомизация трейдов |
Не требует предп. о распределении |
Не учитывает временные зависимости |
| Параметрическое моделирование |
Учитывает fat tails, экстраполяция |
Требует подбора распределения |
Randomization по трейдам — самый простой подход: перемешивание исторических трейдов с возвращением.
import numpy as np
import pandas as pd
def monte_carlo_randomize_trades(trade_returns, n_simulations=10000, n_periods=252):
"""
trade_returns: массив доходностей каждой сделки
Каждая симуляция — случайная выборка с возвращением
"""
results = np.zeros((n_simulations, n_periods))
for i in range(n_simulations):
sampled_trades = np.random.choice(trade_returns, size=n_periods, replace=True)
results[i] = np.cumprod(1 + sampled_trades) - 1
return results
equity_curves = monte_carlo_randomize_trades(historical_trades)
# Статистики
p5, p50, p95 = np.percentile(equity_curves[:, -1], [5, 50, 95])
print(f"5th percentile final equity: {p5:.1%}")
print(f"Median final equity: {p50:.1%}")
print(f"95th percentile final equity: {p95:.1%}")
Maximum Adverse Excursion (MAE) симуляция оценивает распределение максимальной просадки.
def max_drawdown_distribution(equity_curves):
max_dd = np.zeros(len(equity_curves))
for i, curve in enumerate(equity_curves):
running_max = np.maximum.accumulate(1 + curve)
drawdown = (1 + curve) / running_max - 1
max_dd[i] = drawdown.min()
return max_dd
dd_dist = max_drawdown_distribution(equity_curves)
prob_20pct_drawdown = np.mean(dd_dist < -0.20)
print(f"Probability of 20%+ drawdown: {prob_20pct_drawdown:.1%}")
Почему параметрическая симуляция точнее?
Параметрические модели генерируют новые доходности из статистического распределения, что позволяет моделировать сценарии, отсутствующие в истории. Мы используем:
Geometric Brownian Motion (GBM):
def gbm_simulation(mu, sigma, S0, T, n_steps, n_sims):
dt = T / n_steps
returns = np.random.normal((mu - 0.5*sigma**2)*dt, sigma*np.sqrt(dt), (n_sims, n_steps))
price_paths = S0 * np.exp(np.cumsum(returns, axis=1))
return price_paths
Student-t distribution (лучше для финансов): Нормальное распределение underestimates fat tails. Student-t с 3-7 степенями свободы лучше описывает реальные return distributions.
from scipy import stats
def student_t_simulation(mu, sigma, df, n_steps, n_sims):
returns = stats.t.rvs(df=df, loc=mu, scale=sigma, size=(n_sims, n_steps))
return np.cumprod(1 + returns, axis=1)
Bootstrap методы: Stationary Bootstrap (случайные блоки переменной длины) и Block Bootstrap (фиксированные блоки) сохраняют временные зависимости.
Оценка Risk of Ruin
def probability_of_ruin(equity_curves, ruin_threshold=0.5):
"""
Вероятность потерять >50% капитала хотя бы один раз
"""
min_equity = equity_curves.min(axis=1)
return np.mean(min_equity < (1 - ruin_threshold))
prob_ruin = probability_of_ruin(equity_curves, ruin_threshold=0.5)
print(f"Probability of 50% drawdown (ruin): {prob_ruin:.1%}")
Что входит в разработку системы Monte Carlo?
Мы предлагаем услугу под ключ: от анализа вашей стратегии до внедрения автоматического отчёта. Стоимость разработки рассчитывается индивидуально и зависит от объёма данных, требуемой точности и сложности моделей. Экономия за счёт предотвращения крупных просадок может быть значительной. В среднем проект занимает от 2 до 4 недель.
| Этап |
Длительность |
Результат |
| Анализ данных и стратегии |
1-2 дня |
Отчёт о качестве данных, первичные распределения |
| Разработка базовой MC рандомизации |
3-5 дней |
Прототип с визуализацией конуса вероятности |
| Параметрические модели и stress testing |
5-10 дней |
Расширенная симуляция с GBM, Student-t, сценариями |
| Автоматизация и дашборд |
3-5 дней |
Регулярный пересчёт MC, алерты при росте риска |
| Документация и обучение |
2-3 дня |
Описание методологии, инструкция по обновлению данных |
Мы также включаем stress testing по сценариям: кризис (увеличение negative skew и fat tails на 2σ), серия из 10 убыточных трейдов подряд, высокая корреляция убытков. Это позволяет тестировать стратегию в экстремальных условиях.
Monte Carlo также позволяет подобрать размер позиции (например, по критерию Келли) для максимизации роста при заданном уровне риска. Мы реализуем симуляцию с различными долями капитала на сделку и оцениваем вероятность разорения для каждой.
Как интерпретировать результаты Monte Carlo?
Стандартные выводы для trader/investor:
- Конус вероятности (fan chart): p5/p25/p50/p75/p95 пути капитала
- Распределение итоговой доходности
- Распределение максимальной просадки
- Вероятность различных уровней drawdown
- Expected time to new equity high
Automated reporting: каждый раз при добавлении новых трейдов — автоматический перерасчёт MC и обновление отчёта. Если вероятность ruin выросла с 3% до 8% — алерт для управляющего.
Наш опыт — более 10 лет в разработке торговых систем и риск-моделей. Мы гарантируем прозрачную методологию и чёткую документацию. Свяжитесь с нами, чтобы оценить ваш проект — получите консультацию за 2-3 дня. Экономия от внедрения Monte Carlo может существенно снизить риски крупных потерь.
Согласно Monte Carlo method, данный подход широко применяется в финансах для оценки риска.
Какие проблемы прогнозирования временных рядов встречаются чаще всего?
Финансовый директор запрашивает прогнозирование временных рядов продаж на квартал. Аналитик строит SARIMA, добивается MAPE 8.3% на тестовой выборке — и с гордостью деплоит. Через два месяца в production метрика падает до 23%. Причина классическая: модель обучалась на данных до COVID, тестировалась на стабильном периоде, а production попал на промо-акцию и сбой поставок. Data leakage + distribution shift = красивые цифры в ноутбуке и неработающий прогноз в реальности. Мы сталкивались с этим десятки раз. Наш опыт — 5+ лет в прогнозировании временных рядов для ритейла, финтеха и IoT, более 50 завершённых проектов.
Неправильная кросс-валидация. Стандартный train_test_split для временных рядов — ошибка. Случайное разбиение создаёт data leakage: модель видит «будущие» значения в обучении. Правильно — TimeSeriesSplit или walk-forward validation с expanding window.
Множественная сезонность. Почасовые данные потребления электроэнергии имеют три сезонности: суточную (24 ч), недельную (168 ч), годовую (8760 ч). SARIMA справляется только с одной. Prophet обрабатывает несколько, но медленно масштабируется на тысячи рядов.
Пропуски и аномалии в данных. Пропуск в сенсорных данных — это информация (датчик отключился), а не просто NaN. Линейная интерполяция убивает этот сигнал. Правильная обработка зависит от природы пропуска.
Cold start при иерархическом прогнозировании. Новый SKU в ассортименте из 50 000 позиций: исторических данных нет, нужен прогноз. Стандартные подходы тут не работают — нужны cross-learning подходы или feature-based методы.
Какие инструменты и когда применять?
Prophet (Meta) — отличный старт для бизнес-данных с понятной сезонностью и праздниками. Быстро настраивается, интерпретируем, встроенная обработка выбросов и пропусков. Падает в точности при нерегулярных паттернах и не масштабируется на десятки тысяч рядов без параллелизации. Prophet (Facebook) — официальная документация.
Gradient boosting на фичах (LightGBM, XGBoost) — часто недооценённый подход. Создаёте фичи вручную: лаги (t-1, t-7, t-28), скользящие средние, категориальные признаки (день недели, месяц), экзогенные переменные. Модель обучается на всех рядах одновременно — решает cold start через похожие ряды. MAPE на ритейл-прогнозировании часто лучше нейронных сетей при правильной feature engineering.
TFT (Temporal Fusion Transformer) — трансформер, специально разработанный для интерпретируемого прогнозирования с ковариатами. Встроенные механизмы: variable selection (какие признаки важны), temporal self-attention (какие временные точки влияют на прогноз), квантильные предсказания. Доступен в pytorch-forecasting. Требует ~10 000+ записей на ряд для стабильного обучения. Temporal Fusion Transformer — академическая публикация.
PatchTST — трансформер, который делит временной ряд на патчи (аналогично ViT для изображений). Лучше захватывает локальные паттерны, чем классические трансформеры. Хорошо работает для long-horizon forecasting (прогноз на 96–720 шагов). Реализация в neuralforecast от Nixtla.
N-HiTS, N-BEATS — нейронные архитектуры без attention, быстрее TFT, конкурентная точность. N-BEATS выигрывает на M4/M5 benchmark для задач без ковариат.
| Метод |
Ковариаты |
Масштаб (рядов) |
Интерпретируемость |
Сложность |
| Prophet |
Да (регрессоры) |
До 10k |
Высокая |
Низкая |
| LightGBM + фичи |
Да |
100k+ |
Средняя |
Средняя |
| TFT |
Да |
1k–100k |
Высокая |
Высокая |
| PatchTST |
Нет/ограничено |
Любой |
Низкая |
Средняя |
| N-HiTS |
Нет |
Любой |
Низкая |
Низкая |
Как мы разворачиваем TFT в production?
TFT требует тщательной подготовки данных. Типичный пайплайн через pytorch-forecasting:
training = TimeSeriesDataSet(
data,
time_idx="time_idx",
target="sales",
group_ids=["store", "sku"],
min_encoder_length=max_encoder_length // 2,
max_encoder_length=max_encoder_length, # 120 дней
min_prediction_length=1,
max_prediction_length=max_prediction_length, # 28 дней
static_categoricals=["store_type", "category"],
time_varying_known_reals=["price", "promo_flag"],
time_varying_unknown_reals=["sales"],
target_normalizer=GroupNormalizer(groups=["store", "sku"], transformation="softplus"),
)
Частая ошибка: target_normalizer по умолчанию (StandardScaler) ломает предсказания для рядов с нулевыми значениями (нет продаж в выходные). GroupNormalizer с transformation="softplus" — правильный выбор для count-данных.
Пошаговая инструкция по настройке TFT
-
Сбор и подготовка данных. Обработать пропуски (маркировать NaN, интерполировать только если это технический сбой), агрегировать до нужной частоты, сформировать ковариаты (праздники, промо, цены).
-
Создание
TimeSeriesDataSet. Указать group_ids (например, магазин+SKU), временной индекс, горизонт прогноза. Настроить target_normalizer с учётом распределения таргета.
-
Обучение baseline. Сначала Prophet или LightGBM — чтобы понять, насколько сложнее задача.
-
Тренировка TFT. Запустить
TemporalFusionTransformer с loss=QuantileLoss(), подобрать learning rate и размеры hidden слоёв. Использовать pytorch_forecasting или neuralforecast.
-
Валидация и интерпретация. Проверить walk-forward, проанализировать variable selection, построить attention heatmap.
Кейс: прогноз спроса в ритейле. Сеть из 120 магазинов, 8000 SKU, горизонт прогноза 28 дней. Исходная система: SARIMA отдельно для каждого ряда, MAPE 18.4%, полный цикл переобучения — 6 часов. TFT на PyTorch + pytorch-forecasting: одна модель на все ряды, MAPE 11.2%, переобучение — 40 мин на A10G. Дополнительный бонус: feature importance через variable selection — выяснилось, что day_before_holiday влияет сильнее, чем сама дата праздника. Средняя экономия бюджета на инференсе для клиента составила 1.5 млн ₽ в год.
Как правильно оценивать качество прогнозов?
Не используйте RMSE как единственную метрику — она сильно штрафует за большие ошибки на больших значениях. Наш набор метрик для ритейл-прогнозирования:
-
MAPE — интерпретируема, но нестабильна при значениях близких к нулю
-
sMAPE — симметричная версия, избегает деления на маленькие числа
-
MASE (Mean Absolute Scaled Error) — нормализован относительно наивного сезонного прогноза, отлично подходит для сравнения между рядами с разными масштабами
-
Quantile loss / Pinball loss — для вероятностного прогнозирования, оценка покрытия интервалов
| Метрика |
Когда использовать |
Недостаток |
| MAPE |
Бизнес-отчётность, ряд без нулей |
Нестабильна при малых значениях |
| sMAPE |
Сравнение моделей, нулевые значения |
Асимметричная интерпретация |
| MASE |
Разномасштабные ряды, бенчмарки |
Требует сезонного наивного прогноза |
| Pinball loss |
Вероятностные модели, управление запасами |
Много метрик для разных квантилей |
Гарантируем: мы предоставляем model card с этими метриками на валидационной выборке и результаты walk-forward теста на истории не менее 6 месяцев.
Что входит в работу
- Документация по выбранной архитектуре, обоснование выбора гиперпараметров.
- Воспроизводимый пайплайн обучения и инференса (Docker + CI/CD + Airflow/Prefect).
- Код с комментариями и модульными тестами на ключевые компоненты.
- Обучение вашей команды: как переобучать модель, как интерпретировать выходы, как деплоить новые версии.
- Поддержка в течение 3 месяцев после сдачи: консультации, фиксы багов, донастройка.
Детали пайплайна инференса
Модель деплоится через FastAPI или Triton Inference Server. Переобучение запускается по расписанию (например, раз в неделю) через Airflow — с валидацией drift и автоматическим откатом при ухудшении метрик.
Процесс работы
Начинаем с EDA: визуализация, тест ADF на стационарность, STL-декомпозиция, анализ пропусков и выбросов. Это 2–3 дня, но часто выявляет системные проблемы данных, которые блокируют прогнозирование.
Затем: baseline (наивный seasonal, Prophet), feature engineering для LGBM, выбор архитектуры нейронной сети если нужно. Walk-forward validation с реалистичным горизонтом. Деплой через API с автоматическим переобучением по расписанию через Airflow или Prefect.
Сроки ориентировочно: MVP-прогноз на одном типе данных — 3–6 недель. Иерархическая система прогнозирования с автоматизацией — 2–5 месяцев. Стоимость рассчитывается индивидуально.
Наша команда — сертифицированные ML-инженеры (AWS ML Specialty, GCP Professional ML Engineer). За 5 лет на рынке реализовали более 50 проектов по прогнозированию. Свяжитесь с нами для бесплатного анализа ваших данных — мы оценим задачу и дадим первые рекомендации за 1–2 дня. Закажите консультацию и убедитесь, что ваши прогнозы работают в production, а не только в ноутбуке.