Trading Dev AcademyFree quant education

Free lesson · Stochastic calc

SDEs, Euler–Maruyama and an Ornstein–Uhlenbeck example

Open interactive lessonPractice calculationsExplore labs

Start with the idea

  • A stochastic differential equation combines systematic drift with random fluctuations.
  • Its solution is a distribution of paths.
  • Fixing the initial condition does not fix future shocks; numerical simulation must specify both the time grid and the stochastic increments.
Symbols, units & horizon
  • X_t: stochastic state at t
  • κ: positive reversion speed in inverse time
  • θ: equilibrium state
  • η: absolute state volatility in state units per square-root time
  • W_t: Brownian motion
  • h: step length
  • Z: standard normal draw
  • m_h: conditional mean after h
  • v_h: conditional variance after h
  • exp: exponential function
  • dt: time increment
  • dW_t: stochastic increment
  • s: integration time variable
  • Y_s: state deviation multiplied by the integrating factor exp(κs)
  • u: substituted time remaining
  • m_h and √v_h have state units

When and why to use this

Use the exact OU transition as a benchmark for a stochastic numerical scheme and to distinguish expected dynamics from realised path risk.

  • Euler–Maruyama evaluates drift and diffusion coefficients at the beginning of a step, then adds a Brownian increment.
  • Under suitable regularity conditions it has different rates of strong path error and weak expectation error.
  • These rates are not guarantees for arbitrary discontinuous or explosive coefficients.
  • The Ornstein–Uhlenbeck model adds constant Brownian noise to deterministic mean reversion.
  • Its conditional mean follows the ODE, while its conditional variance increases from zero toward a stationary value.
  • A mean path is not a sample path.
dXt=κ(θ−Xt)dt+ηdWt,Xt+h≈Xt+κ(θ−Xt)h+ηhZ
Calculus: derivation and arithmetic

SDEs, Euler–Maruyama and an Ornstein–Uhlenbeck example

  1. Replace the drift integral over one short step by κ(θ−X_t)h and the constant diffusion integral by η√h Z. This gives Euler–Maruyama.
  2. For the exact transition, set Y_s=exp(κs)(X_s−θ). The time-product rule cancels the drift: dY_s=ηexp(κs)dW_s. Integrate from t to t+h, then divide by exp(κ(t+h)). The result is X_(t+h)=θ+(X_t−θ)exp(−κh)+η∫ₜᵗ⁺ʰ exp(−κ(t+h−s))dW_s. The future stochastic integral has conditional mean zero, giving m_h=θ+(X_t−θ)exp(−κh).
  3. The noise term is η∫ₜᵗ⁺ʰ exp(−κ(t+h−s))dW_s. By Itô isometry its conditional variance is η²∫ₜᵗ⁺ʰ exp(−2κ(t+h−s))ds. Substitute u=t+h−s, reverse the bounds, and integrate exp(−2κu) over [0,h] to obtain v_h=η²(1−exp(−2κh))/(2κ). With deterministic integrand it is Gaussian, so sample m_h+√v_h Z.
Work it by hand

X_t=2, θ=0, κ=1, η=.5, h=1: exact mean=.735759 and variance=.108083. Euler’s one-step mean is zero and variance .25. Reducing the step addresses discretisation error, not whether the OU model fits the market.

An analogy to remember

A cooling object subjected to random small disturbances moves toward room temperature on average, while each realised temperature path wanders around that tendency.

How this becomes a building block

OU dynamics can be a full toy model for a state or one latent factor inside a larger system. Itô integration supplies the variance, ODE calculus supplies the mean, and numerical stepping supplies a simulator. A tradable spread additionally needs a valid hedge, estimation procedure and cost model.

For current applications and implementation limits, see the research checkpoint in Differential Equations.

Python implementation

Self-contained teaching example. Python 3.10+; dependencies and input conventions are shown in the code and notation. Run in your own Python environment.

from math import exp,expm1,sqrt

def ou_transition(current,equilibrium,speed,noise,h,z):
    if speed<=0 or noise<0 or h<0: raise ValueError("Positive speed, nonnegative noise and time required")
    mean=equilibrium+(current-equilibrium)*exp(-speed*h)
    variance=noise**2*(-expm1(-2*speed*h))/(2*speed)
    return mean,variance,mean+sqrt(variance)*z

def ou_euler(current,equilibrium,speed,noise,h,z):
    return current+speed*(equilibrium-current)*h+noise*sqrt(h)*z

print(ou_transition(2,0,1,.5,1,0),ou_euler(2,0,1,.5,1,0))

Continue learning

Stochastic Calculus — all lessons
  1. Start with one random step before continuous noise
  2. Before Itô: random walks, Brownian motion and information
  3. Itô integration and quadratic variation
  4. SDEs, Euler–Maruyama and an Ornstein–Uhlenbeck example
  5. Geometric Brownian motion: the model under Black–Scholes
  6. Itô's lemma: why gamma exists
  7. Black–Scholes and delta hedging in production
  8. Put–call parity and a full Greek P&L budget

Quantitative finance and development glossary · Python resources and libraries · Research sources and limitations