Common Probability Distributions in Finance › The Lognormal Distribution
Quantitative FinanceAll chapters Common Probability Distributions in Finance › The Lognormal DistributionOne section · Sections in this chapter3 / 8 ↓
Reading tools Definitions & inline links
Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.
Article links
Make inline references clickable
Returns may be approximately normal, but a nonnegative stock-price level cannot follow an exact nondegenerate normal law because that law assigns some probability below zero. A local normal approximation may still be useful. A stock price can rise 50% but cannot fall more than 100%. This asymmetry is captured by the lognormal distribution, which constrains values to be positive. The lognormal distribution arises when multiplicative returns produce an accumulated log return that is normally distributed: exponentiating that normal log return gives a positive, lognormally distributed price. Multiplicative compounding by itself does not determine the distribution.
A probability distribution of a random variable whose logarithm is normally distributed. If with , then follows a lognormal distribution. The constant-parameter GBM model below gives lognormal stock prices at each positive horizon.
From Returns to Prices
The connection between normal returns and lognormal prices is one of the most important relationships in quantitative finance. If log-returns are normally distributed, then prices are lognormally distributed. Consider a stock with initial price and continuously compounded return over some period:
This equation captures a key relationship in how prices evolve. The exponential function converts the additive world of log-returns into the multiplicative world of price changes. When , the stock has grown by a factor of , or about 10.5%. The slight difference between the log-return and the percentage return becomes more pronounced for larger moves.
The components of this price equation are:
- : stock price at time
- : initial stock price
- : continuously compounded return over the period
- : the growth factor, converting log-return to price ratio
If , then follows a lognormal distribution. This relationship is fundamental: the exponential function turns the symmetric, unbounded normal distribution into a right-skewed distribution bounded below by zero, which matches the behavior of asset prices that can rise without limit but cannot fall below zero. The step preserves the elegant properties of the normal distribution while mapping them onto the economically sensible domain of positive prices.
For , the probability density function of the lognormal distribution reveals its connection to the normal:
Compare this to the normal density to see the main differences. The argument of the exponential now involves rather than , which reflects that we are measuring distance in the log-space. The presence of in front of the exponential arises from the chain rule when transforming from the normal to the lognormal through the change of variables.
Each element of this formula serves a distinct purpose:
- : the value at which we evaluate the density (must be positive)
- : the mean of , not the mean of itself
- : the standard deviation of , not of itself
- : this factor (compared to the normal PDF) accounts for the change of variables from to
The key distinction is that and describe the underlying normal log-values, not the lognormal variable itself. A log-return standard deviation of 20% must refer to a specified horizon; it is not the standard deviation of price levels or simple returns. In GBM, the annualized diffusion coefficient instead gives log-return standard deviation over years. The actual mean and variance of a lognormal variable are:
These formulas reveal how the parameters of the underlying normal distribution translate into the moments of the lognormal:
- : the expected value (mean) of the lognormal variable
- : the variance of
- : the mean of , the underlying normal distribution
- : the variance of
- : the mean is greater than when , and equal to it in the degenerate case
The term is a convexity adjustment: for a nondegenerate normal , Jensen's inequality gives , and both expectations are finite. High values of contribute disproportionately to the mean of . Holding the mean log-return fixed, greater therefore raises . In the GBM notation below, however, denotes arithmetic drift: holding that drift fixed, the log-mean falls by as variance rises, and does not depend on .
Geometric Brownian Motion
A standard baseline model for stock price dynamics is geometric Brownian motion (GBM), which produces lognormally distributed prices at a fixed positive horizon. Its constant-volatility stock model underlies the Black-Scholes option pricing formula. A formal derivation uses stochastic calculus, but the explicit solution and simulation can be understood through normal log-return increments. Modeled prices evolve continuously with both a deterministic trend and random fluctuations proportional to the current price.
Under GBM, the stock price evolves according to:
This is Itô differential notation: finite price changes are defined through drift and stochastic integrals, not ordinary infinitesimal derivatives. Over a finite interval , a Brownian increment satisfies . Each term has a clear interpretation:
- : stochastic differential of the stock-price process
- : current stock price
- : drift rate (expected return per unit time)
- : diffusion volatility (annualized when time is measured in years); over an interval , the log-return standard deviation is
- : infinitesimal time increment
- : Brownian stochastic differential; its finite increments have variance equal to elapsed time
The first term represents the drift, while captures random fluctuations proportional to the current price. A $100 stock and a $10 stock with the same parameters have the same percentage return distribution, but the absolute dollar changes are ten times larger for the more expensive stock. This makes GBM a scale-consistent baseline. Whether its continuous-path, constant-volatility assumptions fit a particular market and horizon still requires evidence.
Solving this stochastic differential equation yields:
This solution tells us exactly where the stock price will be at any future time, given the realized path of the Brownian motion. The formula has a clear structure:
- : stock price at time
- : initial stock price at time 0
- : annualized instantaneous proportional-return drift; expected simple return over years is
- : volatility (annualized standard deviation)
- : time horizon in years
- : value of the Wiener process at time , with
- : Itô correction term arising from the quadratic variation of Brownian motion
The Itô correction appears because we apply Itô's lemma to : the second derivative term contributes to the drift. This correction is one of the key differences between ordinary calculus and stochastic calculus. In ordinary calculus, if we know , we would conclude that . However, when follows a diffusion process, the additional term arises from the non-zero quadratic variation of Brownian motion. For , the expected GBM log-growth rate is below its arithmetic drift ; at , the two are equal.
This model forms the foundation of the Black-Scholes option pricing formula.


Simulating Price Paths
Monte Carlo simulation of stock prices under GBM is simple. The approach below draws exact GBM transition increments at each point on the chosen time grid and cumulatively sums them. Unlike an Euler approximation, this produces the exact GBM distribution at the grid points for constant parameters; it does not simulate between-grid extrema.
import numpy as np
def _scaled_product(left, right, divisor=1):
"""Multiply then divide through binary mantissas when intermediates fail."""
import math
lm, le = math.frexp(float(left))
rm, re = math.frexp(float(right))
dm, de = math.frexp(float(divisor))
try:
result = math.ldexp(lm * rm / dm, le + re - de)
except OverflowError as error:
raise FloatingPointError(
"Scaled coefficient exceeds floating-point range"
) from error
if not math.isfinite(result):
raise FloatingPointError("Scaled coefficient exceeds floating-point range")
return result
def simulate_gbm_paths(S0, mu, sigma, T, n_steps, n_paths, rng=None):
"""
Simulate geometric Brownian motion paths.
Parameters:
S0: Initial stock price
mu: Annualized instantaneous proportional-return drift
sigma: Annualized volatility
T: Time horizon in years
n_steps: Number of time steps
n_paths: Number of simulation paths
rng: Optional local NumPy RandomState; defaults to a fresh seed-42 stream
Returns:
Array of shape (n_paths, n_steps + 1) containing price paths
Finite model inputs do not guarantee representable transition coefficients
or prices. Range failures raise FloatingPointError; ordinary floating-point
rounding remains. The time-zero column directly preserves the floating-point
representation of S0, not an arbitrary integer's exact precision.
"""
if not all(np.isfinite(value) for value in (S0, mu, sigma, T)):
raise ValueError("Simulation parameters must be finite")
if S0 <= 0 or sigma < 0 or T < 0:
raise ValueError("Require S0>0, sigma>=0 and T>=0")
if any(
isinstance(value, (bool, np.bool_))
or not isinstance(value, (int, np.integer))
or value <= 0
for value in (n_steps, n_paths)
):
raise ValueError("n_steps and n_paths must be positive integers")
dt = T / n_steps
# Generate random increments
rng = np.random.RandomState(42) if rng is None else rng
Z = rng.standard_normal((n_paths, n_steps))
# Calculate log returns for each step
if T == 0:
# Draws above still advance a supplied stream in the usual order.
return np.full((n_paths, n_steps + 1), S0, dtype=float)
ordinary_step = dt > 0 and sigma <= np.sqrt(np.finfo(float).max)
if ordinary_step:
with np.errstate(over="ignore", invalid="ignore"):
log_returns = (mu - 0.5 * sigma**2) * dt + sigma * np.sqrt(dt) * Z
ordinary_step = np.all(np.isfinite(log_returns))
if not ordinary_step:
# Scale time before squaring volatility or rounding T/n to zero.
volatility_step = _scaled_product(sigma, np.sqrt(T), np.sqrt(n_steps))
drift_step = _scaled_product(mu, T, n_steps)
variance_step = _scaled_product(volatility_step, volatility_step, 2)
log_returns = drift_step - variance_step + volatility_step * Z
# Cumulative sum to get log prices relative to initial
log_prices = np.zeros((n_paths, n_steps + 1))
log_prices[:, 0] = np.log(S0)
log_prices[:, 1:] = np.log(S0) + np.cumsum(log_returns, axis=1)
# Convert to prices
with np.errstate(over="raise", under="ignore", invalid="raise"):
prices = np.exp(log_prices)
prices[:, 0] = S0
if not np.all(np.isfinite(prices) & (prices > 0)):
raise FloatingPointError("Price paths exceed floating-point representability")
return prices
# Simulate 1 year of daily prices
S0 = 100
mu = 0.10 # 10% instantaneous annualized drift; expected one-year simple return ≈10.52%
sigma = 0.25 # 25% annual volatility
T = 1.0
n_steps = 252 # Trading days
n_paths = 1000
paths = simulate_gbm_paths(S0, mu, sigma, T, n_steps, n_paths)
final_prices = paths[:, -1]Initial price: $100.00 Expected final price (theoretical): $110.52 Mean simulated final price: $110.44 Median simulated final price: $108.19 5th percentile: $71.15 95th percentile: $160.84
Notice that the mean simulated price is close to the theoretical expected value of , but the median is lower. This is typical of a non-degenerate lognormal distribution: its mean exceeds its median, and its mode is lower still. These quantities answer different questions. The median describes the middle terminal outcome across simulated paths, the mean describes ensemble expected terminal wealth, and long-run performance of repeatedly compounded wealth is governed by average log growth rather than by the arithmetic mean terminal price alone.

