Advanced Interest Rate Models (HJM and LMM) › The Heath-Jarrow-Morton Framework

Michael BrenndoerferDecember 7, 202516 min read
Quantitative FinanceAll chapters
Part 7 of 15Interest Rate Models and Derivatives
Chapter 39Advanced Interest Rate Models (HJM and LMM) › The Heath-Jarrow-Morton Framework
Reading section 2 of 13 · The Heath-Jarrow-Morton Framework · 16 minSection 2 of 13 · 16 min

Book contents

Section 2 of 13 · 16 min read

Advanced Interest Rate Models (HJM and LMM) › The Heath-Jarrow-Morton FrameworkOne section · Sections in this chapter2 / 13 ↓
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

The HJM framework differs from short-rate modeling. Instead of specifying dynamics for a single rate and deriving forward rates, HJM directly models the evolution of the entire forward rate curve. Modeling the observed rate continuum directly is better than deriving it from a simple process. This section develops the framework step by step, building from the definition of instantaneous forward rates through to the central no-arbitrage condition that constrains all valid HJM models.

Instantaneous Forward Rates

Recall from our discussion of the term structure of interest rates in Part II that the instantaneous forward rate f(t,T)f(t, T) represents the rate at time tt for instantaneous borrowing at future time TT. This concept captures the market's expectation, adjusted for risk, of what very short-term borrowing costs will be at some future date. The instantaneous forward rate relates to zero-coupon bond prices through a fundamental relationship that connects the entire forward curve to tradeable securities:

P(t,T)=exp⁡(−∫tTf(t,u) du)P(t, T) = \exp\left(-\int_t^T f(t, u) \, du\right)

where:

  • P(t,T)P(t, T): price at time tt of a zero-coupon bond maturing at TT
  • f(t,u)f(t, u): instantaneous forward rate at time tt for maturity uu
  • r(t)=f(t,t)r(t) = f(t, t): short rate, representing the instantaneous forward rate for immediate borrowing

This exponential relationship reveals a deep connection: the bond price is determined by accumulating the forward rates along the path from the current time to maturity. Intuitively, you can think of buying a zero-coupon bond as locking in a series of instantaneous forward borrowing rates from today until maturity. The integral in the exponent sums up all these infinitesimal forward rates, and the exponential converts this accumulated rate into a discount factor.

The key insight of HJM is that specifying the dynamics of f(t,T)f(t, T) for all maturities TT simultaneously determines the entire yield curve evolution. This means we can model the term structure as a single infinite-dimensional object evolving through time. However, not all specifications are arbitrage-free. If we were free to choose any dynamics for forward rates, we could inadvertently create money machines by trading in bonds of different maturities. The key insight of HJM is the precise restriction on forward rate dynamics that ensures no arbitrage, thereby identifying exactly which models are economically meaningful.

Forward Rate Dynamics Under HJM

Under the HJM framework, the instantaneous forward rate evolves according to a stochastic differential equation that allows both deterministic trends and random fluctuations:

df(t,T)=α(t,T) dt+σ(t,T) dW(t)df(t, T) = \alpha(t, T) \, dt + \sigma(t, T) \, dW(t)

where:

  • α(t,T)\alpha(t, T): drift of the forward rate for maturity TT
  • σ(t,T)\sigma(t, T): volatility function (can be a vector for multiple factors)
  • W(t)W(t): Brownian motion under the real-world probability measure

The functions α\alpha and σ\sigma can depend on the current time tt, the maturity TT, and potentially on the entire current forward rate curve {f(t,u):u≥t}\{f(t, u) : u \geq t\}. This flexibility is both a strength and a challenge. On one hand, it allows us to capture rich dynamics including level shifts, slope changes, and curvature movements in the yield curve. On the other hand, unrestricted choices of drift and volatility can lead to arbitrage opportunities or economically implausible behavior. The HJM framework addresses this by providing a precise mathematical condition that separates valid models from invalid ones.

The HJM Drift Condition

Under the risk-neutral measure Q\mathbb{Q}, the drift α(t,T)\alpha(t, T) is not free to choose. It is completely determined by the volatility function σ(t,T)\sigma(t, T) through the HJM drift condition:

α(t,T)=σ(t,T)∫tTσ(t,s) ds\alpha(t, T) = \sigma(t, T) \int_t^T \sigma(t, s) \, ds

where:

  • α(t,T)\alpha(t, T): forward rate drift under the risk-neutral measure
  • σ(t,T)\sigma(t, T): volatility function of the forward rate

This result states that once you specify how forward rates fluctuate randomly (through the volatility function), the average direction they move (the drift) is automatically determined. There is no freedom to choose both independently. Defining the cumulative volatility Σ(t,T)=∫tTσ(t,s) ds\Sigma(t, T) = \int_t^T \sigma(t, s) \, ds, this condition can be written compactly as:

α(t,T)=σ(t,T)⋅Σ(t,T)\alpha(t, T) = \sigma(t, T) \cdot \Sigma(t, T)

where:

  • α(t,T)\alpha(t, T): forward rate drift under risk-neutral measure
  • σ(t,T)\sigma(t, T): forward rate volatility function
  • Σ(t,T)=∫tTσ(t,s) ds\Sigma(t, T) = \int_t^T \sigma(t, s) \, ds: cumulative volatility

The cumulative volatility Σ(t,T)\Sigma(t, T) has a natural interpretation: it measures the total volatility accumulated from the current forward rate maturity out to the bond maturity. This quantity appears naturally because it represents the volatility of the zero-coupon bond price itself. The drift condition says that forward rates must drift upward by an amount equal to their own volatility times the bond price volatility.

HJM Drift Condition

The HJM drift condition states that in an arbitrage-free economy, the drift of forward rates under the risk-neutral measure is uniquely determined by the volatility structure. This means you only need to specify the volatility function σ(t,T)\sigma(t, T) to fully characterize the model.

Derivation of the HJM Drift Condition

To understand why this condition must hold, let's derive it step by step. The derivation illuminates the deep connection between forward rate dynamics and bond price behavior, and shows why the no-arbitrage requirement imposes such specific constraints. The zero-coupon bond price satisfies:

P(t,T)=exp⁡(−∫tTf(t,u) du)P(t, T) = \exp\left(-\int_t^T f(t, u) \, du\right)

where:

  • P(t,T)P(t, T): price of a zero-coupon bond maturing at TT
  • f(t,u)f(t, u): instantaneous forward rate

Applying Itô's lemma requires determining the dynamics of the log-price, since the bond price is an exponential function of an integral. Let X(t)=ln⁡P(t,T)=−∫tTf(t,u) duX(t) = \ln P(t, T) = -\int_t^T f(t, u) \, du. Using the Leibniz integral rule for stochastic processes, which tells us how to differentiate an integral when both the integrand and limits change, the differential is:

dX(t)=f(t,t) dt−∫tTdf(t,u) du(Leibniz integral rule)=r(t) dt−∫tT[α(t,u) dt+σ(t,u) dW(t)] du(Substitute dynamics)=(r(t)−∫tTα(t,u) du)dt−Σ(t,T) dW(t)(Rearrange terms)\begin{aligned} dX(t) &= f(t, t) \, dt - \int_t^T df(t, u) \, du && \text{(Leibniz integral rule)} \\ &= r(t) \, dt - \int_t^T [\alpha(t, u) \, dt + \sigma(t, u) \, dW(t)] \, du && \text{(Substitute dynamics)} \\ &= \left( r(t) - \int_t^T \alpha(t, u) \, du \right) dt - \Sigma(t, T) \, dW(t) && \text{(Rearrange terms)} \end{aligned}

where:

  • X(t)X(t): log-price of the zero-coupon bond
  • f(t,t)=r(t)f(t, t) = r(t): instantaneous short rate
  • α(t,u)\alpha(t, u): drift of the forward rate
  • Σ(t,T)=∫tTσ(t,s) ds\Sigma(t, T) = \int_t^T \sigma(t, s) \, ds: cumulative volatility
  • W(t)W(t): Brownian motion

The first term f(t,t) dt=r(t) dtf(t, t) \, dt = r(t) \, dt arises because as time advances, the lower limit of integration moves, and the forward rate at that point "drops out" of the integral. The second term captures how the forward rates within the integral are themselves changing. Notice that the stochastic term simplifies beautifully: integrating the volatility function from tt to TT gives exactly the cumulative volatility Σ(t,T)\Sigma(t, T).

Since P(t,T)=eX(t)P(t, T) = e^{X(t)}, Itô's lemma gives dP/P=dX+12(dX)2dP/P = dX + \frac{1}{2}(dX)^2. The additional term 12(dX)2\frac{1}{2}(dX)^2 is the Itô correction that accounts for the fact that exponentiating a stochastic process is not the same as exponentiating its drift. Substituting dXdX and noting that (dX)2=Σ(t,T)2dt(dX)^2 = \Sigma(t, T)^2 dt (since only the Brownian motion term contributes to the quadratic variation), the bond price dynamics are:

dP(t,T)P(t,T)=(r(t)−∫tTα(t,u) du+12Σ(t,T)2)dt−Σ(t,T) dW(t)\frac{dP(t, T)}{P(t, T)} = \left( r(t) - \int_t^T \alpha(t, u) \, du + \frac{1}{2}\Sigma(t, T)^2 \right) dt - \Sigma(t, T) \, dW(t)

where:

  • r(t)r(t): instantaneous short rate
  • α(t,u)\alpha(t, u): forward rate drift
  • Σ(t,T)=∫tTσ(t,s) ds\Sigma(t, T) = \int_t^T \sigma(t, s) \, ds: volatility of the zero-coupon bond
  • W(t)W(t): Brownian motion

This equation tells us exactly how the bond price evolves. The drift consists of three parts: the short rate r(t)r(t), a negative contribution from the integrated forward rate drifts, and a positive convexity adjustment 12Σ(t,T)2\frac{1}{2}\Sigma(t, T)^2. The volatility of the bond price is simply the cumulative forward rate volatility.

Under the risk-neutral measure Q\mathbb{Q}, all traded assets must have a drift equal to the risk-free rate r(t)r(t). This is the fundamental requirement of risk-neutral pricing: when we discount at the short rate, all asset prices become martingales. Therefore, the term in the parentheses must equal r(t)r(t):

r(t)−∫tTα(t,u) du+12Σ(t,T)2=r(t)r(t) - \int_t^T \alpha(t, u) \, du + \frac{1}{2}\Sigma(t, T)^2 = r(t)

where:

  • r(t)r(t): instantaneous short rate
  • α(t,u)\alpha(t, u): forward rate drift
  • Σ(t,T)\Sigma(t, T): cumulative volatility

Simplifying this equation by canceling r(t)r(t) from both sides:

∫tTα(t,u) du=12Σ(t,T)2\int_t^T \alpha(t, u) \, du = \frac{1}{2}\Sigma(t, T)^2

where:

  • α(t,u)\alpha(t, u): forward rate drift
  • Σ(t,T)\Sigma(t, T): cumulative volatility

This equation says that the integrated drift must equal half the squared cumulative volatility. To extract the drift at a specific maturity, we differentiate both sides with respect to TT. Differentiating both sides with respect to TT yields the HJM drift condition. Using the chain rule for the term 12Σ(t,T)2\frac{1}{2}\Sigma(t, T)^2:

∂∂T(∫tTα(t,u) du)=∂∂T(12Σ(t,T)2)α(t,T)=Σ(t,T)∂Σ(t,T)∂T(Chain rule)=Σ(t,T)⋅σ(t,T)(Fundamental Thm of Calculus)=σ(t,T)∫tTσ(t,s) ds(Substitute definition)\begin{aligned} \frac{\partial}{\partial T} \left( \int_t^T \alpha(t, u) \, du \right) &= \frac{\partial}{\partial T} \left( \frac{1}{2}\Sigma(t, T)^2 \right) \\ \alpha(t, T) &= \Sigma(t, T) \frac{\partial \Sigma(t, T)}{\partial T} && \text{(Chain rule)} \\ &= \Sigma(t, T) \cdot \sigma(t, T) && \text{(Fundamental Thm of Calculus)} \\ &= \sigma(t, T) \int_t^T \sigma(t, s) \, ds && \text{(Substitute definition)} \end{aligned}

where:

  • α(t,T)\alpha(t, T): forward rate drift
  • Σ(t,T)\Sigma(t, T): cumulative volatility
  • σ(t,T)\sigma(t, T): forward rate volatility function

On the left side, the Fundamental Theorem of Calculus tells us that differentiating the integral gives us the integrand evaluated at the upper limit. On the right side, we apply the chain rule: the derivative of 12u2\frac{1}{2}u^2 with respect to uu is uu, and we multiply by the derivative of Σ(t,T)\Sigma(t, T) with respect to TT, which is σ(t,T)\sigma(t, T) by the Fundamental Theorem again.

This restriction ensures that the discounted bond price is a martingale under Q\mathbb{Q}, which is equivalent to the absence of arbitrage. This result applies universally: any arbitrage-free model of forward rates must satisfy this condition, regardless of the specific volatility structure chosen.

Short-Rate Models as HJM Special Cases

The HJM framework encompasses all short-rate models as special cases. By choosing specific volatility functions, we recover familiar models that we studied in the previous chapter. This unification provides important insight: the different short-rate models are not fundamentally different approaches to interest rate modeling but rather different choices of volatility structure within the HJM framework.

Ho-Lee Model: Setting σ(t,T)=σ\sigma(t, T) = \sigma (constant) gives a volatility that does not depend on either time or maturity. This is the simplest possible choice. The drift becomes:

α(t,T)=σ2(T−t)\alpha(t, T) = \sigma^2 (T - t)

where:

  • α(t,T)\alpha(t, T): forward rate drift
  • σ\sigma: constant volatility parameter
  • T−tT - t: time to maturity

The forward rate dynamics become:

df(t,T)=σ2(T−t) dt+σ dWQ(t)df(t, T) = \sigma^2 (T - t) \, dt + \sigma \, dW^{\mathbb{Q}}(t)

where:

Notice that the drift increases linearly with maturity. This reflects the convexity adjustment: longer-maturity forward rates must drift upward faster to compensate for the risk in holding longer-dated bonds. The constant volatility means that all forward rates fluctuate by the same amount, leading to parallel shifts in the yield curve.

Hull-White Model: Setting the volatility function to:

σ(t,T)=σe−κ(T−t)\sigma(t, T) = \sigma e^{-\kappa(T-t)}

where:

  • σ(t,T)\sigma(t, T): volatility function of the forward rate
  • σ\sigma: short rate volatility parameter
  • κ\kappa: mean reversion parameter
  • T−tT - t: time to maturity

This specification recovers the Hull-White model. The mean reversion parameter κ\kappa controls how volatility decreases with maturity. Economically, this captures the intuition that short-term rates are more volatile than long-term rates because the latter represent averages of many future short rates. As maturity increases, the individual rate fluctuations average out, reducing overall volatility.

In[2]:
Code
import numpy as np
from scipy.integrate import quad


def hjm_drift(t, T, sigma_func):
    """
    Calculate HJM drift for a given volatility function.

    Parameters:
    -----------
    t : float
        Current time
    T : float
        Forward rate maturity
    sigma_func : callable
        Volatility function sigma(t, s) for s in [t, T]
    """
    sigma_t_T = sigma_func(t, T)
    integral, _ = quad(lambda s: sigma_func(t, s), t, T)
    return sigma_t_T * integral


# Define volatility functions for different models
def ho_lee_vol(t, T, sigma=0.01):
    """Ho-Lee: constant volatility"""
    return sigma


def hull_white_vol(t, T, sigma=0.01, kappa=0.1):
    """Hull-White: exponentially decaying volatility"""
    return sigma * np.exp(-kappa * (T - t))


# Calculate drifts for different maturities
t = 0
maturities = np.linspace(0.01, 10, 100)

ho_lee_drifts = [hjm_drift(t, T, ho_lee_vol) for T in maturities]
hull_white_drifts = [
    hjm_drift(t, T, lambda t, s: hull_white_vol(t, s, sigma=0.01, kappa=0.1))
    for T in maturities
]
Out[3]:
Visualization
Line plot comparing Ho-Lee constant volatility and Hull-White exponentially decaying volatility across maturities.
HJM volatility functions for Ho-Lee and Hull-White models. Ho-Lee holds volatility at 1% for every maturity, while Hull-White starts near 1% and decays exponentially toward 0.37% at 10 years when the mean-reversion parameter is 0.1.
Out[4]:
Visualization
Line plot of HJM drift versus maturity. The Ho-Lee line rises steadily to 0.001 at 10 years, while the Hull-White line rises more slowly, peaks near 7 years, and then declines slightly.
HJM drift profiles implied by the two volatility specifications. Ho-Lee drift grows linearly from zero to 0.001 at 10 years. The Hull-White drift is bounded: it rises to a maximum near 7 years and then declines as exponential volatility decay dominates.

The Ho-Lee drift grows without bound as maturity increases, which can lead to unrealistic long-term behavior. Forward rates at very long maturities would drift upward at an accelerating pace, potentially reaching implausibly high levels. The Hull-White specification, with its exponentially decaying volatility, produces a bounded drift that stabilizes at longer maturities. This behavior aligns better with economic intuition: long-term rates should not exhibit explosive dynamics.

Simulating Forward Rate Curves Under HJM

To implement HJM in practice, we discretize time and simulate the forward rate curve evolution. Starting from today's observed forward curve f(0,T)f(0, T), we evolve each point on the curve simultaneously. This parallel evolution captures how the entire term structure moves together while respecting the no-arbitrage constraint. The simulation proceeds by applying small increments to each forward rate, with the drift determined by the HJM condition and the random shock drawn from a standard normal distribution scaled by the volatility function.

In[5]:
Code
def simulate_hjm_forward_curves(
    f0_curve, maturities, dt, num_steps, sigma_func, num_paths=1000
):
    """
    Simulate forward rate curve evolution under HJM framework.

    Parameters:
    -----------
    f0_curve : array
        Initial forward rate curve f(0, T) for each maturity
    maturities : array
        Maturity points T
    dt : float
        Time step
    num_steps : int
        Number of time steps
    sigma_func : callable
        Volatility function sigma(t, T)
    num_paths : int
        Number of Monte Carlo paths

    Returns:
    --------
    f_curves : array of shape (num_paths, num_steps+1, len(maturities))
        Simulated forward rate curves
    """
    num_maturities = len(maturities)
    f_curves = np.zeros((num_paths, num_steps + 1, num_maturities))
    f_curves[:, 0, :] = f0_curve

    for step in range(num_steps):
        t = step * dt
        dW = np.random.randn(num_paths) * np.sqrt(dt)

        for j, T in enumerate(maturities):
            if T > t:  # Only evolve rates for maturities beyond current time
                sigma = sigma_func(t, T)
                # Calculate cumulative volatility for drift
                # drift = sigma(t, T) * int_t^T sigma(t, s) ds
                integral, _ = quad(lambda s: sigma_func(t, s), t, T)
                drift = sigma * integral

                f_curves[:, step + 1, j] = (
                    f_curves[:, step, j] + drift * dt + sigma * dW
                )
            else:
                f_curves[:, step + 1, j] = np.nan  # Rate has "expired"

    return f_curves


# Initial flat forward curve at 5%
maturities = np.array([0.5, 1, 2, 3, 5, 7, 10])
f0_curve = np.ones(len(maturities)) * 0.05

# Simulate under Hull-White volatility
np.random.seed(42)
f_curves = simulate_hjm_forward_curves(
    f0_curve,
    maturities,
    dt=0.01,
    num_steps=100,  # 1 year
    sigma_func=lambda t, T: 0.01 * np.exp(-0.1 * (T - t)),
    num_paths=1000,
)
Out[6]:
Visualization
Line chart comparing the initial flat 5% forward curve with the median simulated curve after one year. A shaded band shows the 5th to 95th percentile range across remaining maturities.
Distribution of Hull-White HJM forward curves after one simulated year. The initial 5% curve is shown against the median future curve and its 5th-95th percentile band across remaining maturities. The band summarizes cross-path uncertainty at the one-year observation date rather than uncertainty evolving through calendar time.

The simulation shows how the forward rate curve evolves over time under HJM dynamics. The initial flat curve develops both level shifts and changes in shape, with uncertainty increasing over the simulation horizon. The widening confidence band reflects the accumulation of random shocks over time, while the upward drift of the median reflects the convexity adjustment built into the HJM drift condition. Note that as time passes, short-maturity rates "expire" and are no longer meaningful, which is why we shift the maturities when plotting the future distribution.