Monte Carlo Simulations
10 min read
Use randomized simulations to stress-test strategies, estimate drawdown distributions, and build confidence intervals around expected returns.
10 min read
Use randomized simulations to stress-test strategies, estimate drawdown distributions, and build confidence intervals around expected returns.
Monte Carlo simulation is a statistical technique that runs thousands of randomized variations of a trading strategy to estimate the distribution of possible outcomes — drawdowns, equity curves, terminal returns. For traders, the most common form is trade-shuffle bootstrap: resample your historical trade results to build confidence intervals around what could happen.
Randomness can kill a strategy that looks great on paper. Monte Carlo testing shows you if your edge survives chaos.
Prerequisites: Variance & Standard Deviation, Skewness & Kurtosis. Continues into: Law of Large Numbers & Confidence Intervals.
You’ve got:
But here’s the real question:
Can your system survive randomness?
Just because a strategy worked historically doesn’t mean it’s robust. You need to test:
That’s what Monte Carlo Simulation is for — and every serious trader should use it.
Monte Carlo for traders comes in two flavors: (1) trade-shuffle — a bootstrap of your historical trades, where you sample with replacement to simulate longer histories or without replacement to permute the same set; and (2) price-path MC, which simulates synthetic price series from a fitted process (Geometric Brownian Motion, Heston).
Most retail trading articles mean trade-shuffle bootstrap when they say "Monte Carlo." That's what the rest of this lesson covers — and that's what assumes your trades are independent.
It helps you see:
It’s not backtesting new trades — it’s reshuffling real results to stress test how they unfold. And critically: trade-shuffle MC assumes outcome[i] is independent of outcome[i-1]. That assumption breaks for trend-followers and any strategy with serial correlation in its P&L.
| Variant | What's randomized | Key assumption | Best for |
|---|---|---|---|
| Trade-shuffle (bootstrap) | Order of historical trades | Trades are independent | Mean-reverting / scalping strategies with many trades |
| Price-path (GBM / Heston) | Synthetic prices from a parametric process | Returns follow that process | Option payoffs, derivatives, capital-buffer sizing |
| Walk-forward MC | Re-run strategy on permuted OOS folds | Future regimes resemble OOS folds | Validating that a backtest didn't overfit |
Let’s say:
Sounds great. But:
| Sequence A | Sequence B |
|---|---|
| Win, Win, Loss, Win, ... | Loss, Loss, Loss, Loss, Win, ... |
| Steady equity climb | Emotional breakdown, account risked |
Same trades. Different order. Massively different equity curves.
Monte Carlo shows you how bad it could feel — even if your edge is good.
Use it to set:
"My backtest showed a 10% drawdown." Monte Carlo says: "Given my historical trade distribution and assuming independence, the 5th-percentile drawdown is 20–25%."
MC does not predict — it quantifies what could happen if your sample is representative and your assumptions hold. If the regime shifts, the simulation tells you nothing about the new world. Variance is messier in real life — Monte Carlo only exposes the variance that was already in your sample.
Two systems may have the same average return, but:
Monte Carlo makes these differences visual and measurable.
MC results are only as honest as their inputs. Three traps:
A related trap: bootstrapping a fat-tailed return distribution underestimates the tail because the sample itself missed the rare event. The worst real-world drawdown is almost always outside the MC envelope.
List 100+ trade outcomes (in R or % gain/loss)
Use Excel or Google Sheets to either:
RAND + SORT (samples without replacement — same trades, new sequence)INDEX(trades, RANDBETWEEN(1, N)) (allows duplicates — useful for projecting 500 future trades from 100 historical)Cumulatively sum each run
Repeat 5,000+ times
Chart the 5th / 50th / 95th percentile equity curves
| Method | Excel formula | Output use case | Assumption |
|---|---|---|---|
| With replacement (bootstrap) | INDEX(range, RANDBETWEEN(1,N)) | Project longer future histories | Trades are i.i.d. samples from a stable distribution |
| Without replacement (permutation) | RAND + SORT | Show how the same trades reorder | Sample is the universe; only sequence varies |
import numpy as np
trades = np.array([...]) # array of R-multiples per historical trade
N_RUNS, N_TRADES = 10_000, len(trades)
equity_paths = np.empty((N_RUNS, N_TRADES))
for i in range(N_RUNS):
sample = np.random.choice(trades, size=N_TRADES, replace=True) # bootstrap
equity_paths[i] = np.cumsum(sample)
drawdowns = equity_paths - np.maximum.accumulate(equity_paths, axis=1)
max_dd = np.min(drawdowns, axis=1)
print(np.percentile(max_dd, [5, 50, 95]))
Libraries: numpy / pandas for the math; vectorbt and quantstats wrap this with reporting and Sharpe / Sortino / drawdown stats out of the box. backtesting.py offers a similar bootstrap utility on its trade ledger.
| Metric | Meaning |
|---|---|
| Max drawdown (worst run) | Capital you could lose before recovery |
| Median return | What happens most often (expectation) |
| 95% CI | High-confidence boundaries for equity |
| Best run | Don't expect this — it's the dream |
| Worst run | Plan for this — it's the cost of the game |
If your edge falls apart in simulation — it’s probably not robust in real trading. If it survives simulation, you've ruled out some failure modes; you have not proven survival.
Monte Carlo shows the variance and distribution, including the skew and kurtosis of your equity paths — the bootstrap underestimates fat tails when the sample missed them. EV gives you the central tendency. The Kelly criterion helps you size appropriately against the drawdown distribution MC produces. The Law of Large Numbers tells you how many runs you need before the percentile bands stabilize.
Together, they create a data-driven growth plan that’s emotionally and statistically sustainable.
Further reading: Ralph Vince, The Mathematics of Money Management (1992) — foundational treatment of trade-resampling for risk estimation. Howard Bandy, Quantitative Trading Systems — chapter on bootstrap validation of backtests. Marcos López de Prado, Advances in Financial Machine Learning (2018) — combinatorial purged cross-validation as a more honest alternative to naive MC. Andreas Clenow, Following the Trend (2013) — explicit discussion of why bootstrap caveats matter for serially-correlated trend strategies.
Watch 20 simulated equity paths diverge from the same starting capital. Adjust the win rate and click Re-shuffle to see how randomness creates wildly different outcomes from identical edge parameters.
The same set of trades, in different orders, produces dramatically different equity curves and drawdowns. A run of losses early can blow past your risk tolerance even when long-run expectancy is positive — Monte Carlo reshuffles the order to expose how bad the path could feel.
For each randomized run, MC reports a worst-case drawdown, a median return, and a 95% confidence interval on terminal equity. Aggregated across thousands of runs, it gives you the distribution of equity outcomes — but only conditional on your historical sample being representative.
No. Monte Carlo shows what could happen given your sample and assumptions (independence, stationarity). It does not forecast the future. The real worst-case is almost always outside the MC envelope, because the regime shift, flash crash, or broker failure was not in the sample.
Backtests show one path. Monte Carlo shows a distribution of paths — conditional on your sample being representative.
The real worst-case is almost always outside the MC envelope, because the regime shift, the flash crash, the broker failure weren't in your 200 trades. Use MC to set lower bounds on pain, never upper bounds. If MC says max DD is 20%, plan for 35%.
A casino doesn't simulate. It already knows the distribution. You don't — so you bootstrap, and you stay humble about the gap between your sample and the future.