Geometric Brownian Motion: The Maths Behind Stock Price Simulation

A walkthrough of the GBM model, from the stochastic differential equation to the code that generates 5,000 price paths. If you haven't read the intro article, start here.

Why geometric Brownian motion?

When you simulate a stock price, you need a mathematical model for how prices change over time. The standard choice in quantitative finance is geometric Brownian motion (GBM). It was central to the Black-Scholes option pricing model and remains the default starting point for Monte Carlo stock simulation.

GBM captures two things that matter about stock prices: they tend to drift upward over time (on average, stocks go up), and they bounce around unpredictably on any given day. It also enforces that prices can't go negative, which is physically correct for a stock.

The stochastic differential equation

GBM is defined by this equation:

dS = μS dt + σS dW

Where:

  • S is the stock price
  • μ (mu) is the drift, the expected annualised return
  • σ (sigma) is the annualised volatility
  • dW is a Wiener process increment (random noise)

The key detail is that both the drift and the noise are proportional to the current price S. This is what makes it "geometric": percentage changes are modelled, not absolute changes. A £10 stock and a £1,000 stock both move by the same percentage on average.

Solving it: the discrete-time formula

For simulation, you don't work with the continuous equation directly. You use the exact solution for one time step:

S(t+Δt) = S(t) × exp((μ - σ²/2)Δt + σ√(Δt) × Z)

Where Z is a standard normal random variable (mean 0, variance 1) and Δt is the time step in years. For daily simulation, Δt = 1/252 (there are roughly 252 trading days per year).

Notice the σ²/2 correction term. This comes from Itô's lemma and accounts for the difference between arithmetic and geometric returns. Without it, the simulation would systematically overestimate the expected price. It's a common mistake to leave it out.

Measuring drift and volatility from data

Both μ and σ come from the stock's historical price data. Here's how:

Calculating returns

Take the log of each day's closing price divided by the previous day's close:

r(t) = ln(S(t) / S(t-1))

Log returns have a nice property: they're additive over time. The return over 5 days is the sum of the 5 daily log returns.

Volatility

Take the standard deviation of the daily log returns, then annualise:

σ = std(r) × √252

Multiplying by √252 converts daily volatility to annual. This comes from the property that variance scales linearly with time for independent returns, so standard deviation scales with the square root.

Drift

Take the mean daily log return and annualise:

μ = mean(r) × 252

Turning it into code

Here's the simulation loop in pseudocode:

dt = 1 / 252
for each simulation (1 to 5,000):
    price = currentPrice
    for each day (1 to horizonDays):
        Z = random normal(0, 1)
        price = price * exp((drift - vol² / 2) * dt + vol * sqrt(dt) * Z)
    store final price

Each iteration of the outer loop gives one price path. After 5,000 iterations, you sort the final prices and compute percentiles. The 50th percentile is the median expected price. P10 and P90 give the range that 80% of outcomes fall within.

Interpreting the output

The simulator shows several things at once. Here's what each one tells you:

  • Individual paths (the blue lines): each one is one possible future. No single path is the prediction; the collection of all paths is the result.
  • Confidence bands (P10-P90): the shaded region where 80% of simulated outcomes fall. Wider bands mean more uncertainty.
  • Median line (P50): the middle outcome. Half the simulations finish above this, half below. The median is lower than the mean because of the log-normal distribution's skew.
  • Histogram: the distribution of final prices across all simulations. You can see the skew: the left side (low outcomes) is compressed, while the right tail (high outcomes) stretches out.
  • Probability of gain: the percentage of simulations that finish above the current price. A stock with positive drift and moderate volatility might show 55-65% probability of gain over one year.

Limitations of GBM you should know about

Constant volatility assumption

GBM assumes σ stays the same every day. In reality, volatility clusters: calm periods are followed by turbulent ones (think March 2020). More advanced models like GARCH or stochastic volatility address this, but they add a lot of complexity.

No fat tails

The normal distribution used for Z underestimates extreme moves. Real stock returns have fatter tails than a bell curve. The 2008 crash and the 2021 meme stock mania both involved moves that a normal distribution considers almost impossible.

Independence of returns

GBM treats each day's return as independent. In practice, momentum (trends continuing) and mean-reversion (extreme moves correcting) both exist. The simulation won't capture those patterns.

Backward-looking calibration

Drift and volatility are measured from the past. If a company's business changes (new product, new competitor, new regulation), past data may not reflect future behaviour. The model has no way to account for that.

Beyond GBM

If you want to go further, there are models that relax GBM's assumptions:

  • Heston model: volatility itself follows a random process, capturing volatility clustering
  • Jump-diffusion models: add sudden jumps to capture crashes and spikes
  • GARCH models: volatility changes based on recent return magnitude

Each adds realism at the cost of more parameters to estimate and more computation. For a first look at how your stock might behave, GBM gets you 80% of the way there.

Try it yourself

The Monte Carlo Stock Simulator uses everything described in this article. Pick any stock, run 5,000 GBM simulations, and see the confidence bands, median path, and probability of gain. All calibrated from real market data.