Geometric Brownian motion: solution, moments and Python simulation
Geometric Brownian motion, or GBM, is a positive-price diffusion with constant proportional drift and volatility. Its defining equation is , and its exact solution is an exponential of Brownian motion.
It is useful because we can solve its distribution, simulate exact transitions at observation dates, and benchmark option-pricing code. It is also limited: constant volatility and continuous paths leave out important features of real markets.
The first distinction to learn is between price growth and log-price growth. With 8% arithmetic drift and 30% volatility, expected log growth is 3.5% per year. Both numbers can be correct in the same model.
The model and its units
Assume and constant and . Under a specified probability measure,
Here is the instantaneous proportional drift. If time is measured in years, it has units per year. Volatility is quoted per square-root year, so is dimensionless like a proportional price change.
“Geometric” indicates that the noise scales with the current level. A ten-unit price movement is much larger proportionally for a stock at 20 than for one at 200. GBM makes the distribution of future price ratios independent of the current absolute price level when coefficients are constant.
The symbol does not specify the measure by itself. Under a physical forecasting model, it represents an assumed expected return. Under a risk-neutral pricing model for a stock with continuous dividend yield , replace it with . Label that choice before generating draws.
Solve it by taking logarithms
For , Itô’s lemma gives
Integrate from zero to and exponentiate:
The solution remains strictly positive at every finite time. For , its logarithm is normally distributed, so its price is lognormally distributed:
A common error is to use in the exponent. That produces expected price , which is a different model. The correction is needed to preserve the drift stated in the original equation.

Mean, median and expected log return
The Gaussian exponential identity gives
The mean exceeds the median when volatility and horizon are positive. High-price outcomes stretch the right tail of the lognormal distribution and pull up the mean. The median is the point with half the terminal distribution below it; it is not a claim that every path follows a smooth median curve.
Expected log return is . Expected simple return over the horizon is . The instantaneous drift equals neither horizon quantity exactly for an arbitrary horizon, although the simple-return expression is approximately for small .
For , , and ,
import math
s0, mu, sigma, years = 100.0, 0.08, 0.30, 5.0
print(f"mean={s0 * math.exp(mu * years):.2f}")
print(f"median={s0 * math.exp((mu - sigma**2 / 2) * years):.2f}")
# mean=149.18
# median=119.12
The variance is
You can derive it by calculating and subtracting the squared mean. Setting reduces the variance to zero and recovers deterministic exponential growth, a useful boundary check.
The gap between arithmetic and log growth is sometimes called a volatility drag in discussions of compounding. Here it is an exact model identity. It does not establish an empirical forecast or a universal realised penalty across all return processes.
Exact simulation at chosen dates
Over an interval of length , conditional on the current price,
Use independent values across disjoint intervals. For paths on a grid, form cumulative log increments and exponentiate. For a European payoff that depends only on , draw the terminal distribution directly; there is no need to allocate an entire daily path.
import numpy as np
rng = np.random.default_rng(20261015)
s0, mu, sigma, horizon = 100.0, 0.08, 0.30, 1.0
z = rng.standard_normal(200_000)
terminal = s0 * np.exp((mu - sigma**2 / 2) * horizon
+ sigma * np.sqrt(horizon) * z)
print(f"sample mean={terminal.mean():.2f}")
print(f"theory mean={s0 * np.exp(mu * horizon):.2f}")
print(f"all positive={bool(np.all(terminal > 0))}")
# sample mean=108.38
# theory mean=108.33
# all positive=TrueThe sample mean need not equal the theoretical mean. Its standard error is the sample price standard deviation divided by the square root of the number of independent draws. Treat an unexpectedly large difference as a diagnostic, while allowing normal sampling fluctuations.

“Exact transition” means the chosen grid values have the specified model distribution. It does not mean the model is exact for markets, the sample mean has no error, or a line drawn between observations detects all continuous-time barrier events.
Why Euler can produce a negative price
Euler stepping uses
When the current value is positive, the next value is negative if
A Gaussian variable has an unbounded lower tail, so for this event has positive probability for any positive finite step. At small daily steps and moderate volatility, the probability may be extremely small; at large steps it becomes easier to observe.

Clipping negative prices to zero changes the approximation and can introduce a different bias. If the exact GBM transition is available, using it is simpler. For more general stochastic differential equations, the numerical scheme and its convergence properties need their own analysis.
When comparing schemes, use common Brownian increments where possible. Otherwise unrelated noise can obscure the discretisation difference you are trying to measure. A simulation can have both sampling error and time-step bias; raising the path count addresses only the first.
Pricing measure versus forecasting measure
Suppose your forecasting assumption is an 8% stock drift. A risk-neutral European option calculation with and no dividends uses 3% in the stock dynamics. That change is required by the pricing framework, rather than a claim that your forecast was wrong.
Under with constant dividend yield,
Where the model is useful, and where to challenge it
GBM is a strong teaching and implementation benchmark. Its known moments and analytic European option price let you check whether a simulation, discount factor and payoff implementation agree under a shared model.
It is a weak basis for assuming every future market scenario is covered. Constant volatility excludes volatility clustering and changing regimes. Continuous paths exclude jumps. Normal log returns impose particular tail behaviour. A single constant rate and dividend yield may not fit the contract’s actual cash flows.
Parameter estimation adds another issue: drift is difficult to infer precisely from noisy returns. Simulating millions of paths around a poorly supported drift assumption does not make that assumption more accurate. In risk work, distinguish uncertainty about the distribution from numerical uncertainty conditional on it.
For portfolios, dependence assumptions matter alongside each individual GBM. Marginal distributions alone do not determine basket risk or basket option value. For pricing, matching one option does not ensure a constant-volatility model matches the whole implied-volatility surface.
Download and study next
Sources and further study
Go deeper with lessons, derivations and worked exercises behind this article.