← Back to Learn
III AdvancedWeek 8 • Lesson 23Duration: 60 min

MC Monte Carlo Methods for Trading

Simulating thousands of possible futures to validate your system

Learning Objectives

  • Understand Monte Carlo simulation and its role in system validation
  • Learn block bootstrap and why it beats random resampling
  • Interpret Monte Carlo output for breach probability
  • Read a max drawdown distribution chart

Explain Like I'm 5

Monte Carlo simulation runs your trading strategy through thousands of alternate realities. What if trades happened in a different order? What if your luck was worse? Better? By simulating thousands of scenarios, you discover how the strategy performs across the full range of possibilities — not just the one path that actually happened.

Think of It This Way

You're playing poker and you want to know if your strategy is actually good or if you just had a hot night. Monte Carlo replays the entire session 5,000 times with different shuffles. If you profit in 97% of replays, your strategy is real. If only 55%, you might have just been lucky.

1Why One Backtest Isn't Enough

A single backtest gives you one historical path. But there are countless possible orderings of the same trades. Your results depend partially on luck — the sequence of wins and losses. Monte Carlo answers: "across all plausible sequences, how does my strategy perform?" You use this to estimate: • Breach probability — what % of simulations hit the drawdown limit? • Drawdown distribution — what's the 95th and 99th percentile drawdown? • Return distribution — what's the range of expected monthly returns? • Recovery time — after drawdown, how long to recover? Without Monte Carlo, you're making deployment decisions based on a single historical path. That's choosing your poker strategy based on one night. Efron, B. & Tibshirani, R. (1993). "An Introduction to the Bootstrap." Chapman & Hall.

2Block Bootstrap — The Right Way to Resample

Simple bootstrap randomly picks individual trades with replacement. Problem: it destroys the time structure. Winning and losing streaks break apart. Regime effects disappear. Block bootstrap samples chunks of consecutive trades. This preserves: • Autocorrelation — streaks stay intact • Regime effects — clusters of similar conditions remain grouped • Realistic trade sequences — the "feel" of actual trading Block size matters. Too small (1–2 trades) is just random sampling. Too large (100+) means too few unique blocks. The sweet spot for daily trading systems is usually 20–50 trades per block. Getting this right is part science, part judgment. But the difference it makes is significant — random bootstrap consistently underestimates max drawdown by 20–40%.

3Reading the Max Drawdown Distribution

This is the most important chart from any Monte Carlo analysis. It shows the distribution of maximum drawdowns across all simulations. What you want to see: the bulk of the distribution well to the left of your drawdown limit. The further left the peak, the safer your system. The tail reaching toward the limit tells you about rare worst cases. If the 99th percentile is safely below your limit, you're good. If the tail is kissing the limit, you need to reduce risk.

Max Drawdown Distribution (5,000 Monte Carlo Simulations)

4How to Read Monte Carlo Output

Here's how you actually use the numbers: 1. Breach probability < 5% → safe to deploy ✓ 2. 95th percentile DD < 8% → even bad scenarios are survivable ✓ 3. Median monthly return > 2% → profitable after fees and slippage ✓ All three pass? Deploy. Any one fails? Don't deploy until you fix it. No shortcuts. No "it's probably fine." That thinking ends funded accounts.

5Random vs Block Bootstrap — The Gap

This comparison convinced me block bootstrap is non-negotiable. Random bootstrap produces unrealistically smooth equity curves because it breaks up streaks. Block bootstrap preserves the lumpy reality — good periods followed by choppy stretches. Random bootstrap max DD is typically 20–40% lower than block bootstrap. If you use random, you're being dangerously optimistic about your tail risk. The gap widens at higher percentiles — exactly where accuracy matters most for survival.

Max DD Percentiles: Random vs Block Bootstrap

Key Formulas

Block Bootstrap Equity Curve

Equity curve from bootstrap simulation. E₀ is starting capital, r_b(t) are returns drawn from random blocks. Each simulation gives a different curve.

Breach Probability

Fraction of N simulations where max drawdown exceeds limit L. Simple: count how many simulations cross the line, divide by total simulations.

Hands-On Code

Monte Carlo Block Bootstrap

python
import numpy as np

def monte_carlo_analysis(trade_results, n_sims=5000, block_size=30):
    """Block bootstrap Monte Carlo for system validation."""
    n_trades = len(trade_results)
    max_dds = []
    
    for _ in range(n_sims):
        # Build simulated equity from random blocks
        sim_trades = []
        while len(sim_trades) < n_trades:
            start = np.random.randint(0, n_trades - block_size)
            block = trade_results[start:start + block_size]
            sim_trades.extend(block)
        sim_trades = sim_trades[:n_trades]
        
        # Compute max drawdown
        equity = np.cumprod(1 + np.array(sim_trades))
        running_max = np.maximum.accumulate(equity)
        drawdowns = (running_max - equity) / running_max
        max_dds.append(drawdowns.max())
    
    max_dds = np.array(max_dds)
    breach_prob = (max_dds > 0.10).mean()
    
    print(f"Breach probability (10% DD): {breach_prob:.2%}")
    print(f"95th percentile DD: {np.percentile(max_dds, 95):.2%}")
    print(f"99th percentile DD: {np.percentile(max_dds, 99):.2%}")

The core of any serious system validation. Breach probability from 5,000+ simulations gives you the confidence to deploy — or the data to say "not yet."

Knowledge Check

Q1.Why use block bootstrap instead of random resampling?

Assignment

Run a Monte Carlo with 1,000 simulations on your backtest results. Compare block bootstrap (block_size=30) vs random. The random version will likely show lower max drawdown because it breaks the streak structure.