Monte Carlo Simulation for Trading Strategy Validation

Your Backtest Is One Roll of the Dice
You must use Monte Carlo simulation for trading strategy validation if you want to avoid ruin. A backtest equity curve is a single, fixed sequence of your trades—the one historical path that happened. Monte Carlo simulation replays that same list of trades thousands of times in randomized order to map the full distribution of possible outcomes you could have experienced. It answers the critical question a standard backtest cannot: how bad could the drawdowns have been, and what is the probability your account is wiped out? This technique is the final validation gate in Kevin Davey’s proven build → backtest → Monte Carlo → live trading pipeline. The concept, invented by Stanislaw Ulam during his work at Los Alamos, applies directly to trading strategy validation by resampling your actual trade results with replacement to generate thousands of alternative equity paths Source: AmiBroker Documentation.
How This Guide Was Built
Research for this guide was compiled on 2026-08-11, and every source URL was verified live (HTTP 200) on that date. Primary sources are the AmiBroker official documentation, Kevin Davey (a practitioner, Wiley author, and three-time consecutive winner of >100% returns in the World Cup Championship of Futures Trading), QuantInsti, QuantDojo, and backtrex practitioner guides, along with the academic papers of Bailey & López de Prado on Probability of Backtest Overfitting (PBO) and the Deflated Sharpe Ratio. No proprietary backtests were run for this post. All worked examples are synthetic or quoted directly from the cited sources, and every factual claim is linked inline to its verified source.
What Monte Carlo Adds to Walk-Forward Analysis
Walk-forward analysis tests the robustness of your edge across time by testing on rolling out-of-sample periods. Monte Carlo simulation tests robustness across paths by testing your edge under thousands of random trade sequences. These two questions are orthogonal; together, they form the core tests that separate real strategies from curve-fits Source: AlphaBench. Walk-forward validates that your parameter selection isn’t overfit to one historical period. Monte Carlo validates that even if your edge is real, the sequence of wins and losses you experience won’t blow you up before you realize it. Both are mandatory in a rigorous validation stack, with Kevin Davey placing MC as the final step before live trading Source: Kevin Davey’s Wiley Book. See our walk-forward analysis guide for the complementary time-series validation.
Two Approaches: Bootstrap vs. Parametric
The most common and practical Monte Carlo approach is the non-parametric bootstrap. You resample your actual backtest trade list with replacement to build new paths. This requires no distributional assumptions and preserves the empirical fat tails of your real trade returns. The alternative, parametric simulation, fits a normal, Student-t, or log-normal distribution to your returns and then samples from that fitted curve. While this smooths small samples, it dangerously assumes a shape that real financial returns often violate Source: QuantInsti. A list of N trades can be sequenced in N^N unique realizations. AmiBroker documents two modes: “simulate using trade list” (non-overlapping trades, one trade at a time) and “simulate using portfolio equity changes” (overlapping trades, if your strategy holds multiple positions) Source: AmiBroker. Crucially, you must use fixed position sizing. Sizing as a percentage of current equity makes one trade’s P&L depend on the P&L of all prior trades, creating serial dependence and invalidating the i.i.d. assumption. The bootstrap should be done with fixed risk per trade Source: AmiBroker. Bootstrapping was introduced by Bradley Efron Source: Wikipedia.
Why Order Beats Composition
The same set of trade results can produce wildly different equity curves depending on their order, especially for max drawdown. Consider this synthetic example: 7 winners of +$200 and 3 losers of -$400. The total P&L is +$200 regardless of order. But if the three losers cluster early in a path, the max drawdown could be -$1,200, risking ruin before the winners accumulate. If the losers are spread out, the drawdown might be only ~5% of peak equity. Your actual backtest order is just one draw from the full permutation distribution of your trades. This is why the observed historical max drawdown is often the optimistic, best-case drawdown. Kevin Davey notes that a strategy has roughly a 40% chance of experiencing 4 consecutive losers, so a drawdown cluster does not inherently mean your edge has vanished Source: KJ Trading Systems.
What the Output Tells You
The Monte Carlo simulation produces distributions for key metrics. The max-drawdown distribution is paramount; its 95th percentile is often called the “design drawdown”—the level you must size your account to survive Source: DanAnalytics. A common rule of thumb is that the 5th-percentile MC drawdown is typically 1.5×–3× the historical max drawdown observed in your single backtest; you should size your capital for this larger figure Source: BackTrex. Other outputs include risk of ruin (the percentage of simulations where equity drops below a threshold like 50% partial ruin, 100% total ruin, or a prop-firm’s 8–10% drawdown cap), Prob>0 (the percentage of sims ending with a profit), and confidence intervals on final equity, CAGR, and Sharpe ratio. The canonical output is a percentile table. For example, AmiBroker’s documented output shows a 90th-percentile max DD of 38.48% and a 99th-percentile max DD of 63.82% Source: AmiBroker. An equity fan chart visualizes consistency—a tight fan indicates the strategy outcome is sequence-independent, while a wide fan warns of high path dependency.
How Many Simulations Do You Need
You need a minimum of 1,000 simulations. AmiBroker states the number “should be 1000 or more” Source: AmiBroker. QuantInsti and QuantDojo recommend starting with 1,000 and scaling up to 5,000–10,000 for greater stability Source: QuantDojo. The error of Monte Carlo estimates shrinks proportionally to 1/√N, so beyond ~10,000 runs, the marginal gain in precision is negligible Source: Wikipedia. Most importantly, your simulation is only statistically meaningful with a large enough trade sample—generally 200+ trades and 5–10 years of backtest data Source: KJ Trading Systems.
Monte Carlo Simulation in Python with NumPy
The following is a complete, copy-paste runnable Python script that performs a bootstrap Monte Carlo simulation on a synthetic trade list. It uses fixed fractional compounding, calculates max drawdown per path, and outputs a percentile summary table.
import numpy as np
# --- 1. Setup: Synthetic trade list (replace with your own backtest trade P&L) ---
# Using log-returns for realistic compounding
np.random.seed(42) # For reproducibility
n_trades = 200
# Synthetic win rate ~50%, avg win > avg loss (positive expectancy)
trade_returns = np.random.choice(
np.array([0.015, -0.01, 0.02, -0.008, 0.01, -0.012, 0.018, -0.005]),
size=n_trades
)
# --- End of synthetic data ---
n_sims = 10000 # 10,000 simulations. Min recommended: 1,000.
start_equity = 100000.0
threshold_ruin = 0.5 # 50% of starting equity (partial ruin)
rng = np.random.default_rng(42) # Reproducible RNG
# --- 2. Resample Trade Sequences (With Replacement) ---
# Generate random indices for each simulation
idx = rng.integers(0, n_trades, size=(n_sims, n_trades))
# --- 3. Generate Equity Curves ---
# Compounding: equity = start * product(1 + return)
# Vectorized: trade_returns[idx] gives (n_sims, n_trades) matrix
compounded_growth = np.cumprod(1 + trade_returns[idx], axis=1)
equity_paths = start_equity * compounded_growth
# --- 4. Calculate Max Drawdown per Path ---
running_max = np.maximum.accumulate(equity_paths, axis=1)
drawdowns = equity_paths / running_max - 1 # Drawdown as negative fraction
max_drawdowns = drawdowns.min(axis=1) # Most negative drawdown per path
# --- 5. Compute Final Statistics ---
terminal_equity = equity_paths[:, -1]
total_return = (terminal_equity / start_equity) - 1
# Approximate CAGR (assuming 252 trading days per year, 1 trade/day)
n_years = n_trades / 252
cagr = (terminal_equity / start_equity) ** (1 / n_years) - 1
# Risk of Ruin: % of sims where equity ever dropped below threshold
ever_below_ruin = np.any(equity_paths < start_equity * threshold_ruin, axis=1)
risk_of_ruin = ever_below_ruin.mean()
prob_positive = (terminal_equity > 0).mean()
# --- 6. Output Percentile Table ---
percentiles = [1, 5, 25, 50, 75, 90, 95, 99]
print("Monte Carlo Simulation Results (n_sims={:,}, n_trades={})".format(n_sims, n_trades))
print("="*70)
print(f"{'Percentile':<12} {'Terminal Equity':>18} {'Total Return':>14} {'Max Drawdown':>15}")
print("-"*70)
for p in percentiles:
q_equity = np.percentile(terminal_equity, p)
q_return = np.percentile(total_return, p)
q_dd = np.percentile(max_drawdowns, p)
print(f"{p:>5}th ${q_equity:>14,.2f} {q_return:>13.1%} {q_dd:>14.1%}")
print("-"*70)
print(f"\nRisk of Ruin (>{threshold_ruin:.0%} DD): {risk_of_ruin:.1%}")
print(f"Probability of Profit (Prob>0): {prob_positive:.1%}")
print(f"Median Terminal Equity: ${np.median(terminal_equity):,.2f}")
print(f"Median Max Drawdown: {np.median(max_drawdowns):.1%}")
Example Output from this Script:
Monte Carlo Simulation Results (n_sims=10,000, n_trades=200)
======================================================================
Percentile Terminal Equity Total Return Max Drawdown
----------------------------------------------------------------------
1th $ 135,275.15 35.3% -14.4%
5th $ 152,457.99 52.5% -11.6%
25th $ 180,575.85 80.6% -8.5%
50th $ 204,606.84 104.6% -7.0%
75th $ 230,212.99 130.2% -5.8%
90th $ 255,991.97 156.0% -5.0%
95th $ 273,579.00 173.6% -4.6%
99th $ 307,854.80 207.9% -3.9%
----------------------------------------------------------------------
Risk of Ruin (>50% DD): 0.0%
Probability of Profit (Prob>0): 100.0%
Median Terminal Equity: $204,606.84
Median Max Drawdown: -7.0%
Decision Rules: Green Flags and Red Flags
Drawdowns in the table above are negative fractions, so the 1st and 5th percentile rows represent the deepest worst-case drawdowns — your design drawdown for capital sizing.
Green flags for a strategy passing Monte Carlo validation include: a risk of ruin below 5%, a 5th-percentile terminal equity that is still positive, a tight equity fan chart indicating consistency, and a 95th-percentile drawdown (design drawdown) that fits within your capital plan Source: DanAnalytics. Red flags are: risk of ruin exceeding 10%, a negative 5th-percentile terminal equity, a wide fan chart, and a high probability (e.g., >5%) of a drawdown exceeding 30%. BackTrex provides an illustrative drawdown distribution: ≥10% drawdown in 72% of sims, ≥20% in 28%, ≥30% in 8%, and ≥50% in 1.2% Source: Backtestic. The cardinal rule is to size your capital for the 95th-percentile Monte Carlo drawdown, not the single historical max drawdown from your backtest.
Pitfalls That Will Still Fool You
Monte Carlo simulation is powerful but flawed. Its core assumption is that trades are independent and identically distributed (i.i.d.) Source: Backtestic and Kevin Davey. Serial correlation in your returns violates this. Overlapping trades (holding multiple positions) and percent-of-equity sizing create serial dependence Source: AmiBroker. Regime changes in the market (like the SNB peg removal on Jan 15, 2015) invalidate the historical sample entirely, making all simulations based on it meaningless Source: KJ Trading Systems. Most critically, an overfit backtest produces overconfident Monte Carlo results—“Masterpiece In, Masterpiece Out” Source: KJ Trading Systems. Garbage in, garbage out (GIGO). Small sample sizes (fewer than 200 trades) yield unstable results Source: QuantDojo. Transaction costs and slippage must be embedded in each trade’s net P&L beforehand. Finally, remember: MC is NOT a significance test. It cannot fix a contaminated trade sample or predict regime changes; it only stress-tests the sequencing risk of the sample you provide Source: QuantDojo.
FAQ
How many Monte Carlo simulations do I need to run?
A minimum of 1,000 simulations is required for basic stability, with 5,000 to 10,000 being typical for production validation. The error of MC estimates decreases proportionally to 1/√N, so gains diminish beyond 10,000 runs. Your results are only statistically meaningful with a large underlying trade sample of at least 200 trades over 5-10 years of data Source: AmiBroker.
Is Monte Carlo simulation a test of whether my edge is real?
No. Monte Carlo simulation is not a test of statistical significance or edge robustness. It assumes your trade list already contains a real, validated edge. Its purpose is to quantify sequence risk—the randomness in the order of wins and losses that a single backtest hides. It answers “how bad could it get?” not “does my strategy work?” Source: QuantDojo.
What is the difference between Monte Carlo and walk-forward analysis?
Walk-forward analysis (WFA) tests the robustness of your strategy’s edge across time by validating on rolling out-of-sample periods. Monte Carlo (MC) tests robustness across paths by randomizing the order of your out-of-sample trades. They answer orthogonal questions; together they form the two core tests separating curve-fits from real strategies Source: AlphaBench. Read our walk-forward analysis guide for the complementary temporal validation method.
Where to Go Next
The full quantitative validation stack consists of: walk-forward analysis for edge robustness across time, Monte Carlo simulation for sequence risk, Probability of Backtest Overfitting (PBO) and the Deflated Sharpe Ratio for selection bias across trials, and leverage-space sizing like the Kelly criterion to size for the drawdown distribution you just mapped. This sequence moves you from curve-fit to a strategy that has a statistically validated edge and a capital plan designed to survive its worst-case scenarios. For more methodology guides, visit our blog index.
The Monte Carlo simulation is not a crystal ball. It is the rigorous stress test that forces you to confront the full range of your strategy’s possible fates before you risk real capital.
← Back to all posts

