Skip to content

Monte Carlo Simulation

★★★★★ Intermediate

Estimate outcomes by running thousands of random experiments. When analytical solutions are intractable, simulate. Widely used in finance, risk analysis, and portfolio optimization.

Core Idea

  1. Define a model with random inputs
  2. Run many simulations (1000+)
  3. Aggregate results for probability estimates

Stock Price Simulation

Geometric Brownian Motion (GBM):

import numpy as np

def simulate_prices(S0, mu, sigma, days, n_sims):
    """
    S0: initial price, mu: expected daily return
    sigma: daily volatility, days: trading days
    """
    prices = np.zeros((days, n_sims))
    prices[0] = S0
    for t in range(1, days):
        Z = np.random.standard_normal(n_sims)
        prices[t] = prices[t-1] * np.exp(
            (mu - 0.5*sigma**2) + sigma*Z
        )
    return prices

# Historical volatility
returns = df['price'].pct_change().dropna()
volatility = returns.std()
annualized_vol = volatility * np.sqrt(252)  # 252 trading days

Portfolio Optimization

n_sims = 10000
n_assets = len(tickers)
results = np.zeros((3, n_sims))  # return, std, sharpe

for i in range(n_sims):
    weights = np.random.random(n_assets)
    weights /= weights.sum()

    port_return = weights @ daily_returns.mean() * 252
    port_std = np.sqrt(weights @ cov_matrix @ weights) * np.sqrt(252)
    sharpe = port_return / port_std

    results[0, i] = port_return
    results[1, i] = port_std
    results[2, i] = sharpe

# Best Sharpe ratio portfolio
best_idx = results[2].argmax()

Risk Metrics

Value at Risk (VaR)

Maximum expected loss at given confidence level.

# Historical VaR (95% confidence)
var_95 = np.percentile(returns, 5)  # 5th percentile

# Parametric VaR
var_95 = returns.mean() - 1.645 * returns.std()

Sharpe Ratio

Risk-adjusted return: (return - risk_free_rate) / std_dev

sharpe = (returns.mean() - risk_free_rate) / returns.std()
annualized_sharpe = sharpe * np.sqrt(252)

Practical Tips

  • More simulations = more stable estimates. Use 10,000+ for serious analysis
  • Vectorize with NumPy - never use Python loops for simulation
  • Always set random seed for reproducibility
  • Visualize: scatter plot of risk vs return colored by Sharpe ratio
  • Business days: 20/month, 252/year in finance

Applications Beyond Finance

  • Sports prediction (simulate tournaments)
  • Project timeline estimation (simulate task durations)
  • A/B test power analysis
  • Bayesian inference (MCMC)
  • Physics simulations

See Also