Latticework

Command Palette

Search for a command to run...

Monte Carlo Simulation

Simulating Stock Paths

20 min

Explanation

Geometric Brownian motion (GBM) is the standard model for simulating a stock price path: each tiny time step, the price is multiplied by a random factor built from a drift term (mu, the expected return) and a random shock scaled by volatility (sigma):

import random, math

random.seed(42)
price = 100.0
dt = 1 / 252   # one trading day, as a fraction of a year
mu, sigma = 0.08, 0.20   # 8% expected annual return, 20% annual volatility

for _ in range(252):   # simulate one year, day by day
    z = random.gauss(0, 1)   # a standard normal random shock
    price *= math.exp((mu - 0.5*sigma**2)*dt + sigma*math.sqrt(dt)*z)

print(round(price, 2))

The - 0.5*sigma**2 term looks odd at first — it's a correction so that the AVERAGE simulated price actually grows at rate mu, compensating for the fact that multiplying by random factors and then averaging isn't the same as averaging first (a consequence of how lognormal distributions work, not a typo).

Try it

A single simulated path is just one possible future — real usage always runs thousands of paths and looks at the distribution of outcomes, which is exactly what the next exercise does for option pricing.

Loading editor…
Explanation

A single price path only tells you one possible future. Monte Carlo option pricing runs thousands of independent simulated paths, computes each one's payoff, and averages — the same "many random samples, average the results" idea from the previous module, applied to finance:

payoffs = []
for _ in range(10_000):
    z = random.gauss(0, 1)
    s_t = s0 * math.exp((r - 0.5*sigma**2)*T + sigma*math.sqrt(T)*z)
    payoffs.append(max(s_t - strike, 0))   # call option payoff

price_today = math.exp(-r * T) * (sum(payoffs) / len(payoffs))

max(s_t - strike, 0) is a call option's payoff: worth s_t - strike if the stock finishes above the strike price, worthless otherwise. exp(-r*T) discounts the average future payoff back to today's dollars. This is a real, working (simplified) implementation of Monte Carlo option pricing — the same core idea underlies far more sophisticated versions used in practice.

Exercise

Write `simulate_gbm_path(s0, mu, sigma, days, seed=42)`: simulate a stock price path over `days` trading days using geometric Brownian motion (`dt = 1/252`; each step: `price *= exp((mu - 0.5*sigma**2)*dt + sigma*sqrt(dt)*z)` where `z = random.gauss(0, 1)`), starting from `s0`. Return the final price rounded to 2 decimals.

Exercise

Write `monte_carlo_call_price(s0, k, r, sigma, days, n_sims, seed=42)`: estimate a European call option's price by simulating `n_sims` final prices (each via one GBM step over the full period, `T = days/252`), computing each payoff `max(S_T - k, 0)`, discounting the average payoff by `exp(-r*T)`, and returning the result rounded to 2 decimals.

Quiz

In geometric Brownian motion, what does increasing sigma (volatility) do to the spread of simulated final prices?

Checkpoint

You can simulate a GBM stock price path and use Monte Carlo simulation to estimate an option's price by averaging discounted payoffs across many simulated paths.