Monte Carlo Simulation in Trading Systems
Monte Carlo simulation reshuffles trade order to reveal realistic drawdown and ruin probabilities, and this guide explains the technique and interpretation for beginner system developers.
Интерактивные инструменты могут не работать в переведённом виде.
Monte Carlo Simulation in Trading Systems
Your backtest produced one equity curve. Monte Carlo reveals the hundreds of equally-likely curves you might have lived through instead.
Why one backtest is misleading
A backtest produces a single sequence of trades in chronological order. The order matters: the same set of trades arranged differently produces very different drawdowns and very different psychological pressure. Your backtested drawdown of 15% might become 30% under a reordering of the same trades — same expectancy, very different survivability.
Monte Carlo simulation (MCS) addresses this by resampling the trade list thousands of times to build a distribution of outcomes.
Two main Monte Carlo approaches
1. Trade resampling (shuffle)
Take the backtested trades, randomize their order, and compute the resulting equity curve. Repeat 1,000–10,000 times.
What it reveals: the distribution of possible drawdowns and final equity, given your historical win/loss profile. A bad run of consecutive losers can happen in any order — MCS shows how likely each scenario is.
2. Trade resampling with replacement (bootstrap)
Sample trades randomly with replacement to construct new sequences of any length. This estimates not just drawdown but also the probability of ruin — the chance that a sequence of losses wipes out the account.
What it reveals: how robust the system is to extreme streaks not present in the historical sample.
What Monte Carlo reports
A typical MCS output includes:
| Metric | What it tells you |
|---|---|
| Median max drawdown | The drawdown you'd expect under typical trade ordering |
| 95th percentile max drawdown | The drawdown under a "bad luck" sequence |
| 99th percentile max drawdown | Near-worst-case drawdown |
| Probability of ruin | % chance of hitting your ruin threshold |
| Median final equity | Expected terminal account value |
| Distribution of final equity | Variance in outcomes |
Worked example
Backtested trades: 200 trades, expectancy +0.3R, max drawdown 12R.
Run 1,000 Monte Carlo shuffles:
- Median max drawdown: 14R
- 95th percentile: 22R
- 99th percentile: 28R
The backtest showed 12R; Monte Carlo says a 5% chance exists of facing a 22R drawdown. If your account can only survive 20R, the system is risky even with positive expectancy.
Practical use in position sizing
MCS directly informs position sizing. If the 99th-percentile drawdown is 28R and you want to limit worst-case drawdown to 25% of account:
Position risk per trade = 25% / 28 = ~0.9% per trade
You size down to stay within the worst-case envelope. This is a more rigorous method than the common "1% per trade" rule of thumb.
Probability of ruin
Define ruin as a specific loss threshold (e.g., 50% drawdown). MCS estimates the % of sequences that hit this threshold. A probability of ruin above 5% is uncomfortable; above 10% is unacceptable.
Account must survive N consecutive losers.
With 1% risk per trade: ruin requires 50 losers in a row.
With 5% risk per trade: ruin requires 10 losers in a row.
MCS reveals how often a 10-loss streak actually occurs.
Common Monte Carlo tools
- TradesViz, QuantAnalyzer: built-in MCS modules
- Python: trivial to implement with
numpy.random.choice - Excel: shuffle trades with
RAND()and recalculate - NinjaTrader/MultiCharts: MCS add-ons available
A 30-line Python script can shuffle a CSV of trade results and produce the full distribution in seconds.
Limitations of MCS
- Trades are assumed independent: real trades cluster (regime-driven losses come together)
- Distribution is fixed: future trade distribution may differ from past
- No regime change modeling: assumes the future resembles the past
- Assumes the backtest itself was unbiased: garbage in, garbage out
For more realism, use block bootstrap — shuffle blocks of consecutive trades to preserve short-term correlation.
Common mistakes
- Treating the median drawdown as the worst case (use the 95th percentile)
- Running MCS on too few trades (need 200+ for stable estimates)
- Using absolute dollar outcomes instead of R-multiples (hides position-size changes)
- Forgetting to model costs (slippage variability)
- Reporting only median final equity (downside tail matters more)
How to interpret results
A robust system shows:
- Median max drawdown close to (or below) the backtested value
- 95th percentile drawdown no more than 2× the backtested value
- Probability of ruin below 1–2%
- Positive median final equity with limited downside tail
A fragile system shows:
- 95th-percentile drawdown 3–5× the backtested value
- Non-trivial probability of ruin
- Wide distribution of final equity — luck dominates skill
Practical workflow
- Generate 200+ trades in a backtest (after fixing biases)
- Export the trade list (R-multiples)
- Run 1,000+ Monte Carlo shuffles
- Read the 95th-percentile drawdown as your planning number
- Set position size so the 99th percentile stays below your ruin threshold
- Re-run quarterly as live trades accumulate
Rule of thumb
If Monte Carlo on your system shows the 95th-percentile drawdown is more than 2.5× your backtested drawdown, your system is more luck-dependent than you think — increase sample size or simplify rules.
Next: even a robust backtest must survive forward demo testing before going live.
Live Chart
Open full chart →Related market data, powered by TradingView.