Monte Carlo generates thousands of possible equity paths by resampling or simulating returns. Instead of one backtest (which is one path through history), you get a distribution of outcomes. The 5th percentile shows your realistic worst case.
One year of 250 trade returns has a maximum drawdown of 12.5%. Shuffle the same trades into 5,000 other orders: the final result is identical (True), but the maximum drawdown ranges from 12.6% to 26.8% (5th to 95th percentile). The order you happened to get was among the luckiest; plan for the distribution, not the history.
- Shuffling assumes trades are independent; strategies with streaks or regimes need block resampling.
- Simulated paths can only recombine what happened; they cannot produce a crash larger than any in the data.
- A thousand simulated paths from a wrong model are a thousand wrong answers.
rng = np.random.default_rng(12)
trades = rng.normal(0.002, 0.02, 250) # one year of trade returns
def mdd(rets):
w = np.cumprod(1 + rets); return (1 - w / np.maximum.accumulate(w)).max()
actual = mdd(trades)
shuffled = [mdd(rng.permutation(trades)) for _ in range(5_000)] # same trades, other orders
lo, hi = np.percentile(shuffled, [5, 95])
final_same = np.isclose(np.prod(1 + trades), np.prod(1 + rng.permutation(trades)))Assumes import numpy as np and import pandas as pd (and SciPy where imported). Each snippet simulates or makes up its own data, as the comments say.
The same idea with a library
# Python — Monte Carlo equity simulation import numpy as np daily_returns = df['returns'].values n_sims, n_days = 1000, 252 # Resample with replacement paths = np.zeros((n_sims, n_days)) for i in range(n_sims): sampled = np.random.choice(daily_returns, size=n_days) paths[i] = np.cumprod(1 + sampled) # Confidence bands p5 = np.percentile(paths, 5, axis=0) p95 = np.percentile(paths, 95, axis=0)
- An Introduction to the Bootstrap, B. Efron & R. J. Tibshirani, Chapman & Hall, 1993
- Monte Carlo Methods in Financial Engineering, P. Glasserman, Springer, 2003
Last reviewed October 2026 · How this site checks its content · Report a mistake
- Pattern EssaysThe FractalZoom in and the pattern repeats, the same shape living inside itself
- LLM EngineeringSamplingControlling creativity by shaping the probability distribution
- MLOps & Production MLAuto-Scaling EndpointsScaling with demand — and scaling back to save money
- The ToolkitCentral Limit Theorem & SamplingWhy averages become normal — the theorem underneath every CI and t-test
- The ToolkitConfidence IntervalsHow sure are you? — bootstrap and parametric CIs, and interpreting their width