Lesson 8.3: Interest rate models, curves and bond maths
Learn bond pricing, duration and convexity, discount factors and forward rates, how a curve is bootstrapped, and the Vasicek mean-reverting short-rate model.
By the end of this lesson you will be able to price a bond from its yield, compute its duration, convexity and DV01, use them to estimate and hedge the effect of a rate move, convert a set of par yields into discount factors, zero rates and forward rates by bootstrapping, and describe and use the Vasicek model of a mean-reverting short rate to price zero-coupon bonds. You will show that a five-year 7 per cent bond priced at par has a modified duration of 4.10 and a DV01 of ₹41,002 on a ₹10 crore holding, that a one-point rise in yield cuts its price by 3.99 where duration alone predicts 4.10 and duration with convexity predicts 3.99, that par yields of 6.0, 6.3 and 6.5 per cent imply a one-year rate one year forward of 6.62 per cent, and that a Vasicek model with a short rate of 6 per cent and a long-run level of 7 per cent produces a yield curve rising from 6.04 to 6.84 per cent. You should have read Lessons 7.2 and 7.3 and the Ornstein–Uhlenbeck material of Lesson 5.2. The mathematics is discounting, derivatives of a present value and a mean-reverting stochastic equation. This course is education about how markets and research work, not investment advice.
Equities have one price per company. Interest rates have a price for every maturity, and the whole set of them, the yield curve, moves together in several ways at once. That makes rates both more demanding and more important than any single stock: every asset in this course is discounted with them, and every borrower and lender in an economy is exposed to them. This lesson covers the working tools of the fixed-income quant: how a bond is priced and how its price responds to rates, how a curve is built from market prices, and the simplest dynamic model of how rates move, which is the counterpart for interest rates of the geometric Brownian motion of Lesson 7.2.
Bonds: price and yield
A bond pays fixed amounts, called coupons, at regular dates, and its face value at maturity. Its price is the present value of those payments. With a single yield y used to discount every payment, the price of a bond with annual coupons c per 100 of face value and n years to maturity is
P = c ÷ (1 + y) + c ÷ (1 + y)² + ... + (c + 100) ÷ (1 + y)ⁿ
The yield to maturity y is the single discount rate that makes this equal to the market price. A higher yield means a lower price: prices and yields move in opposite directions.
Worked example 1. Take a five-year bond with a 7 per cent annual coupon, an illustrative bond for the arithmetic. At a yield of 7 per cent it is priced at par, 100.00. At 6 per cent it is worth 104.21, and at 8 per cent 96.01. The price rises by 4.21 when the yield falls by one point and falls by 3.99 when it rises by one point. The relationship is not a straight line: it is convex, curving up, so a fall in yield raises the price by more than an equal rise lowers it.
Duration, convexity and DV01
How much does the price move for a small change in yield? The first-order answer is duration.
Macaulay duration is the average time, in years, to receive the payments, weighting each date by the present value of what is paid then: D = Σ t × PV(payment at t) ÷ P. For our bond at a 7 per cent yield, D = 4.387 years: it pays over five years, but the coupons bring forward the average.
Modified duration is D ÷ (1 + y) = 4.387 ÷ 1.07 = 4.100. It measures the percentage change of the price for a 1 per cent change in yield: ΔP ÷ P ≈ −(modified duration) × Δy.
DV01, the dollar value of a basis point, is the price change for a one basis point rise in yield: DV01 = modified duration × P × 0.0001. Here it is 4.100 × 100 × 0.0001 = 0.0410 per 100 of face value. For a holding of ₹10 crore of face value, the DV01 is ₹41,002 per basis point.
Convexity, the second-order term, measures the curvature: C = [Σ t(t + 1) × PV(payment at t) ÷ (1 + y)²] ÷ P. It is 21.96 for this bond. The improved approximation is
ΔP ÷ P ≈ −Dmod × Δy + ½ × C × (Δy)²
Yield change · Exact price change · Duration only · Duration and convexity+1 point · −3.993 · −4.100 · −3.990
−1 point · +4.212 · +4.100 · +4.210
+3 points · −11.372 · −12.301 · −11.313
Duration alone overstates the fall and understates the rise, because it ignores the curvature. For small moves it is fine. For a three-point move it is out by 0.93, nearly 8 per cent of the change, and adding convexity brings the error down to 0.06. Convexity is valuable to the holder: a convex bond gains more when yields fall than it loses when they rise by the same amount, and the market pays for it in the price.
Compute the figures for any bond below, with the exact price and the move for a chosen shift in yield.
Hedging with duration
Because DV01 measures the exposure to a rate move, two positions can be matched by their DV01. To hedge ₹10 crore of the five-year bond, with a DV01 of 0.0410 per 100, you could sell a ten-year 7 per cent bond priced at par, which has a modified duration of 7.024 and a DV01 of 0.0702 per 100. The hedge ratio is 0.0410 ÷ 0.0702 = 0.584: sell ₹5.84 crore of the ten-year bond. The result is neutral to a small parallel shift of the curve, where all yields move by the same amount. It is not neutral to a twist, where short and long rates move differently, so a careful desk measures key-rate durations, the sensitivity to the yield at each maturity separately, and hedges each.
The yield curve: discount factors, zero rates and forwards
A single yield for a bond hides the fact that money paid in two years is discounted at a different rate from money paid in one. The proper way to discount is with a discount factor for each date, DF(T): the price today of ₹1 paid at T. Every bond price is then a sum of payments times discount factors, and every maturity has its own rate.
The zero rate z(T) is the yield of a zero-coupon bond maturing at T: z(T) = DF(T)^(−1/T) − 1.
The forward rate from T₁ to T₂ is the rate locked in today for borrowing between those dates: f = DF(T₁) ÷ DF(T₂) − 1 for a one-year interval. It follows from no-arbitrage: investing for T₂ years must give the same as investing for T₁ years and then rolling over at the forward rate.
Bootstrapping
Markets quote par yields, the coupon rates at which bonds of different maturities sell at par. To get discount factors from them, work outwards from the shortest maturity, a method called bootstrapping. At each maturity n, a par bond with coupon yn satisfies yn × (DF₁ + ... + DFn) + DFn = 1, so
DFn = (1 − yn × (DF₁ + ... + DF{n−1})) ÷ (1 + yn)
Worked example 2. The one-, two- and three-year par yields are 6.0, 6.3 and 6.5 per cent (illustrative).
DF₁ = 1 ÷ 1.06 = 0.9434.
DF₂ = (1 − 0.063 × 0.9434) ÷ 1.063 = 0.9406 ÷ 1.063 = 0.8848.
DF₃ = (1 − 0.065 × (0.9434 + 0.8848)) ÷ 1.065 = 0.8812 ÷ 1.065 = 0.8274.
The zero rates are 6.000, 6.309 and 6.520 per cent. The forward rates are 6.0 per cent for year 1, 0.9434 ÷ 0.8848 − 1 = 6.620 per cent for the year from 1 to 2, and 0.8848 ÷ 0.8274 − 1 = 6.942 per cent for the year from 2 to 3. Forwards rise faster than zero rates, which in turn rise faster than par yields, because each is an average of the one that follows it. A curve that slopes up has forwards above zero rates above par yields.
Real curves are built from many instruments, government securities, swaps and futures, with interpolation between points and checks that forward rates stay sensible. For the rupee, the curve is built mainly from government securities and overnight-index swaps tied to the overnight benchmark rate, and conventions change, so the market's current benchmark definitions and day-count rules should be checked before any real calculation.
Why we need a model of interest rates
A curve describes rates today. To price an option on a rate, a bond that the issuer can call back, a cap that pays when rates rise above a level, or to measure how risky a portfolio is over a year, we need a model of how rates change. The first models describe the short rate rt, the rate for borrowing over a very short interval, and build the whole curve from its dynamics. A short rate differs from a share price in two ways: it does not trend upwards without limit, and it moves within a range set by monetary policy and the economy. So it is modelled as mean-reverting, like the spreads of Lesson 5.2.
The Vasicek model
Oldřich Vasicek's 1977 model gives the short rate the Ornstein–Uhlenbeck dynamics:
dr = a × (b − r) dt + σ dW
where b is the long-run level, a the speed of reversion and σ the volatility of the rate, in absolute terms (not proportional to r). The solution is known: r at a future time T is normal, with
mean b + (r₀ − b) e^(−aT)
variance σ² × (1 − e^(−2aT)) ÷ (2a)
As T grows, the mean tends to b, and the standard deviation to σ ÷ √(2a), the long-run spread. The price today of a zero-coupon bond maturing at T has a closed form, since a bond price is the expectation of exp(−∫r dt) under the risk-neutral measure of Lesson 7.3, and it turns out to be exponential in r₀:
P(0, T) = A(T) × e^(−B(T) r₀), with B(T) = (1 − e^(−aT)) ÷ a and A(T) = exp[ (B − T)(a² b − σ² ÷ 2) ÷ a² − σ² B² ÷ (4a) ]
The yield is −ln P ÷ T.
Worked example 3. Take a = 0.3, b = 7 per cent, σ = 1 per cent and a current short rate of 6 per cent. These are illustrative numbers.
In five years the short rate has a mean of 0.07 + (0.06 − 0.07) × e^(−1.5) = 6.777 per cent and a standard deviation of 0.01 × √((1 − e^(−3)) ÷ 0.6) = 1.258 per cent. It is normal, so it could in principle be negative, but the chance of a rate below zero at five years is about 4 in 100 million.
Bond yields from the formula:
Maturity · 0.25 yr · 1 yr · 2 yr · 5 yr · 10 yr · 30 yrVasicek yield · 6.04% · 6.13% · 6.24% · 6.47% · 6.65% · 6.84%
The curve starts at the current short rate of about 6 per cent and rises towards a long-run level a little below b, because the model pulls the short rate up to 7 per cent over time and the convexity term lowers long yields. We checked the formula by simulation: 40,000 paths of the short rate with 2,000 steps over five years gave a mean short rate of 6.775 per cent, a standard deviation of 1.260 per cent and a five-year bond price of 0.7238, against the formula's 6.777 per cent, 1.258 per cent and 0.7237.
Change the parameters below to see how the speed of reversion, the long-run level and the volatility shape the curve.
Other short-rate models
Ho–Lee and Hull–White add a time-dependent drift so that the model reproduces today's yield curve exactly, which Vasicek with constant parameters cannot do. Hull–White is the workhorse for pricing and risk on interest-rate options.
Cox–Ingersoll–Ross (CIR) makes the volatility proportional to √r, which keeps the rate positive if the reversion is strong enough and makes volatility rise with the level.
Black–Karasinski models the logarithm of the rate, so the rate is positive and lognormal.
Heath–Jarrow–Morton (HJM) models the whole forward curve at once, with a drift fixed by no-arbitrage. The market models that price caps and swaptions in line with market conventions are built on it.
Benchmark reform. After the end of the LIBOR benchmark, markets moved to overnight risk-free rates, so curves and models are now built on those, and conventions differ by currency.
None of these is right in every respect. Real rates show regimes, jumps at central-bank decisions, and, in some economies, periods of negative rates and of rates pinned near zero.
Putting it to work
Risk. Use DV01 and key-rate durations to measure exposure, convexity to second-order effects, and scenarios of parallel and twist shifts to stress a book.
Relative value. Compare bonds against the fitted curve to find those that look cheap or dear, and trade the spread between maturities.
Carry and roll-down. A bond earns its yield, and as time passes it rolls down the curve to a lower yield if the curve slopes up, which adds to the return if the curve does not move.
Pricing options on rates. Calibrate a short-rate model to caps and swaptions and use it, with the numerical methods of Lessons 8.1 and 8.2, to value products with embedded options.
Discounting everywhere. The discount curve is an input to every pricing model in this course.
The code below prices the bond, computes its duration, convexity and DV01, tests the approximations, bootstraps the curve, computes the Vasicek yields, checks them by simulation and works out the hedge ratio.
python
import numpy as np
from math import exp, log, sqrt
from scipy.stats import norm
1. bond price, duration, convexity
def price(c, y, n, face=100.0):
return sum(c / (1 + y) t for t in range(1, n + 1)) + face / (1 + y) n
c, n = 7.0, 5
for y in (0.06, 0.07, 0.08):
print("yield", y, "price", round(price(c, y, n), 3))
y = 0.07
P = price(c, y, n)
macaulay = (sum(t c / (1 + y) t for t in range(1, n + 1)) + n 100 / (1 + y) n) / P
modified = macaulay / (1 + y)
convexity = (sum(t (t + 1) c / (1 + y) (t + 2) for t in range(1, n + 1)) + n (n + 1) 100 / (1 + y) (n + 2)) / P
print("Macaulay", round(macaulay, 3), "| modified", round(modified, 3), "| convexity", round(convexity, 2), "| DV01 per 100", round(modified P 1e-4, 4),
"| DV01 on Rs 10 crore of face value: Rs", round(modified P / 100 10e7 1e-4))
for dy in (0.01, -0.01, 0.03):
exact = price(c, y + dy, n) - P
print(f" yield change {dy:+.2f}: exact {exact:+.3f} | duration only {-modified P dy:+.3f} | with convexity {-modified P dy + 0.5 convexity P dy 2:+.3f}")
hedge a 5-year bond with a 10-year bond by DV01
P10 = price(7.0, 0.07, 10)
mac10 = (sum(t 7.0 / 1.07 t for t in range(1, 11)) + 10 100 / 1.07 10) / P10
dv015, dv0110 = modified P 1e-4, mac10 / 1.07 P10 1e-4
print("10-year modified duration", round(mac10 / 1.07, 3), "| hedge ratio", round(dv015 / dv0110, 3))
2. bootstrapping three par yields
par = {1: 0.060, 2: 0.063, 3: 0.065}
df = {1: 1 / (1 + par[1])}
df[2] = (1 - par[2] df[1]) / (1 + par[2])
df[3] = (1 - par[3] (df[1] + df[2])) / (1 + par[3])
print("discount factors", {k: round(v, 4) for k, v in df.items()})
print("zero rates", {k: round(df[k] (-1 / k) - 1, 5) for k in df}, "| forwards 1y1y", round(df[1] / df[2] - 1, 5), "2y1y", round(df[2] / df[3] - 1, 5))
3. Vasicek: closed-form yields and the distribution of the short rate
a, b, sg, r0 = 0.3, 0.07, 0.01, 0.06
def vasicek(T):
B = (1 - exp(-a T)) / a
A = exp((B - T) (a a b - sg sg / 2) / (a a) - sg sg B B / (4 a))
P0 = A exp(-B r0)
return -log(P0) / T, P0
for T in (0.25, 1, 2, 5, 10, 30):
print(f" maturity {T:>5}: yield {vasicek(T)[0] 100:.2f}%")
T = 5
meanr, sdr = b + (r0 - b) exp(-a T), sg sqrt((1 - exp(-2 a T)) / (2 a))
print("short rate at 5 years: mean", round(meanr 100, 3), "% | sd", round(sdr 100, 3), "% | chance of a negative rate", f"{norm.cdf(-meanr / sdr):.1e}")
check by simulation
rng = np.random.defaultrng(4)
steps, paths = 2000, 40000
dt = T / steps
r = np.full(paths, r0)
integral = np.zeros(paths)
for in range(steps):
integral += r dt
r = r + a (b - r) dt + sg sqrt(dt) rng.standardnormal(paths)
print("simulation: mean", round(r.mean() 100, 3), "% | sd", round(r.std() 100, 3), "% | five-year bond price", round(np.exp(-integral).mean(), 4),
"| formula", round(vasicek(5)[1], 4))
Common mistakes
Treating duration as exact. It is a first-order estimate that fails for large moves. Add convexity.
Hedging with duration and forgetting twists. Matching DV01 protects against parallel shifts only.
Using one yield for all payments. Cash flows at different dates need different discount factors.
Mixing quoting conventions. Par yields, zero rates, forward rates, annual and semiannual compounding and day counts must be kept straight.
Bootstrapping with inconsistent instruments. Mix bonds, swaps and futures with care, since each carries its own conventions and spreads.
Assuming a short-rate model fits the curve. Vasicek with constant parameters does not, and Hull–White does.
Forgetting that Vasicek allows negative rates. That may be unrealistic in some markets, and realistic in others.
Simulating rates under the real-world measure for pricing. Pricing needs the risk-neutral measure, with the market price of risk built in.
Ignoring convexity when valuing long-dated bonds. It grows with the square of the maturity and can be large.
Key takeaways
A bond's price is the present value of its payments, and it falls when yield rises. A five-year 7 per cent bond is worth 104.21 at 6 per cent, 100.00 at 7 per cent and 96.01 at 8 per cent.
Modified duration (4.100) gives the first-order price change and DV01 the rupee change per basis point: ₹41,002 on ₹10 crore. Convexity (21.96) corrects the curvature: for +1 point the exact change is −3.993, duration alone −4.100 and with convexity −3.990.
A DV01 hedge matches the exposure to a parallel shift: ₹10 crore of the five-year bond is offset by selling ₹5.84 crore of a ten-year bond. Twist risk needs key-rate durations.
Bootstrapping turns par yields into discount factors, zero rates and forwards. Par yields of 6.0, 6.3 and 6.5 per cent give discount factors of 0.9434, 0.8848 and 0.8274, and forwards of 6.00, 6.62 and 6.94 per cent.
The Vasicek model, dr = a(b − r)dt + σdW, makes the short rate normal with mean b + (r₀ − b)e^(−aT), and gives zero-coupon bonds in closed form. With a = 0.3, b = 7 per cent, σ = 1 per cent and r₀ = 6 per cent, yields rise from 6.04 to 6.84 per cent from three months to thirty years.
Hull–White fits today's curve, CIR keeps rates positive, HJM models the whole forward curve, and the benchmark transition from LIBOR to overnight rates changed the market conventions.
Use DV01 and scenarios for risk, carry and roll-down for return, and calibrated models with Monte Carlo or finite differences for options on rates.
Check yourself
1. A bond has a modified duration of 6.5 and a price of 102. By roughly how much does its price change if the yield rises by 25 basis points?
ΔP ≈ −6.5 × 102 × 0.0025 = −1.66.
2. A portfolio's DV01 is ₹80,000 per basis point. A ten-year bond position has a DV01 of ₹6,000 per ₹1 crore of face value. How much face value must you sell to hedge a parallel move?
80,000 ÷ 6,000 = 13.3, so ₹13.3 crore of face value.
3. Zero rates are 5.0 per cent for one year and 5.5 per cent for two years, annual compounding. What is the one-year forward rate for the second year?
DF₁ = 1 ÷ 1.05 = 0.95238 and DF₂ = 1 ÷ 1.055² = 0.89845. The forward rate = 0.95238 ÷ 0.89845 − 1 = 6.00 per cent.
4. In a Vasicek model with b = 5 per cent and a = 0.5, the short rate is 3 per cent. What is its mean in two years?
0.05 + (0.03 − 0.05) × e^(−1) = 0.05 − 0.02 × 0.3679 = 4.26 per cent.
5. Why can two bonds with the same duration still differ in how they behave in a large rate move?
Duration is a first-order measure. The bond with higher convexity gains more when yields fall and loses less when they rise, so for large moves their prices diverge.
Try this
Set aside forty-five minutes. You need Python and the code in this lesson.
1. Run the code. Check the bond prices, duration, convexity, bootstrapped curve, Vasicek yields and the simulation check.
2. Price a bond with semiannual coupons, and compare its duration with the annual-coupon version.
3. Get the par yields of a government security curve for a handful of maturities, bootstrap them and plot the zero and forward curves.
4. Compute the DV01 of a portfolio of three bonds of different maturities, and design a hedge with two other bonds that neutralises the DV01 and the convexity.
5. Change a, b and σ in the Vasicek simulator, and describe how each changes the shape of the curve.
6. Simulate the Vasicek short rate for 10 years, with 1,000 paths, and estimate the chance that it falls below 0.
7. Write a short note: what a parallel shift and a twist would do to your hedged position, and which risk you would measure next.
A good result is a bootstrapped curve with its zero and forward rates, a DV01 hedge that you can explain and a Vasicek yield curve whose shape you can relate to its parameters. The last lesson of this module takes the equity side of model risk: local and stochastic volatility, how models are calibrated, and why two models that match the same options can price others differently.
Read more
Oldřich Vasicek's 1977 paper "An Equilibrium Characterization of the Term Structure" in the Journal of Financial Economics is the original source. John Hull and Alan White's 1990 paper "Pricing Interest-Rate Derivative Securities" in the Review of Financial Studies extends it to fit the curve. John Hull's Options, Futures and Other Derivatives has chapters on duration, curves and the main models. Damiano Brigo and Fabio Mercurio's Interest Rate Models: Theory and Practice is the standard reference for the models, and Frank Fabozzi's Fixed Income Mathematics covers bond maths in detail. For Indian markets, read the benchmark and day-count notes on the websites of the Reserve Bank of India and Financial Benchmarks India.
Tags: Quant Trader Interest rates Duration and convexity Yield curve Vasicek model