Розробка системи Monte Carlo симуляції для оцінки торговельної стратегії
Monte Carlo симуляція — метод оцінки стохастичних систем через багаторазове випадкове моделювання. У торгівлі вона відповідає на питання, які backtesting не вирішує: "Могла б така ж втрата сталося в іншому порядку?", "Яка вірогідність втратити 20% за наступні 6 місяців?", "Витримає ли стратегія 5-річний drawdown?".
Чому Monte Carlo для торгівлі
Одна крива backtest — випадковість: Історичний backtest — один реалізований шлях із нескінченного числа можливих. Угоди сталися в конкретному порядку, при конкретній ринковій волатильності. MC генерує тисячі альтернативних шляхів з тих же угод.
Відповіді на ключові питання:
- Інтервал довіри для очікуваної дохідності
- Вірогідність конкретного рівня drawdown
- Необхідний стартовий капітал для виживання з 95% вірогідністю
- Очікуваний час до відновлення після drawdown
Методи Monte Carlo для торговельних систем
Рандомізація за угодами: Найпростіший підхід — перемішування історичних угод:
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%}")
Параметрична Monte Carlo симуляція
Альтернативний підхід: замість перемішування угод генерувати нові з статистичної моделі:
GBM (Geometric Brownian Motion):
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 розподіл (краще для фінансів): Нормальний розподіл недооцінює fat tails. Student-t з 3-7 ступенями свободи краще описує реальні return розподіли:
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: фіксовані блоки по k періодів
Оцінка 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%}")
Оптимізація через MC
Monte Carlo для position sizing: Для різних f (Kelly frакція) симулюємо 10,000 шляхів та вибираємо f*, максимізуючу кінцевий капітал при обмеженні max drawdown < X%:
optimal_f = find_optimal_f(
trade_returns,
max_acceptable_drawdown=0.25,
n_simulations=10000
)
Stress Testing сценарії:
- Криза 2008: збільшуємо negative skew та fat tails на 2σ
- COVID crash: серія з 10 збиткових угод підряд (реальна послідовність)
- 2022 bear market: висока кореляція збитків (недиверсифіковуваний ризик)
Тестуємо стратегію в цих stress-сценаріях: витримає ли при відповідному risk management?
Візуалізація та звіти
Стандартні виходи для трейдера/інвестора:
- Конус вірогідності (fan chart): p5/p25/p50/p75/p95 шляхи капіталу
- Розподіл кінцевої дохідності
- Розподіл максимальної просідки
- Вірогідність різних рівнів drawdown
- Очікуваний час до нової equity high
Автоматичні звіти: Кожен раз при додаванні нових угод — автоматично перерахувати MC та оновити звіт. Якщо вірогідність ruin виросла з 3% до 8% — алерт для менеджера.
Часовая шкала: базова MC рандомізація угод + візуалізація — 1-2 тижні. Повна система з параметричними моделями, stress testing та автоматичними звітами — 4-6 тижнів.







