Time Value of Money and Interest Rates › Worked Example: Bond Valuation
Quantitative FinanceAll chapters Time Value of Money and Interest Rates › Worked Example: Bond ValuationOne section · Sections in this chapter6 / 9 ↓
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
Let us apply our time value framework to a plain fixed-coupon bond with a stated maturity and principal repaid at maturity. Its cash flows consist of periodic coupons and that final principal repayment. Valuing this bond is a direct application of present value concepts; other bond structures can have different cash flows.
Consider a 5-year bond with:
- Face value: $1,000
- Coupon rate: 4% (annual payments)
- Market yield: 5%
The bond's price equals the present value of all future cash flows:
where:
- : bond price (present value of all cash flows)
- : annual coupon payment ($1,000 × 4%)
- : one plus the yield (1 + 0.05)
- : face value returned at maturity
- The first term : present value of the coupon stream (an annuity)
- The second term : present value of the principal repayment
The structure of this formula reflects the two components of a bond's value. The coupon stream is an annuity: five equal payments of $40, one at the end of each year. We can either discount each payment separately or use the annuity formula. The principal repayment is a single lump sum occurring at maturity, which we discount using the basic present value formula. The bond price is simply the sum of these two present values.
def annuity_pv(payment, r, periods):
"""Present value of ordinary annuity."""
if r == 0:
return payment * periods
annuity_factor = -np.expm1(-periods * np.log1p(r)) / r
return payment * annuity_factor
def bond_price(face_value, coupon_rate, yield_rate, years):
"""
Calculate bond price given face value, coupon rate, yield, and maturity.
Assumes annual coupon payments.
"""
coupon = face_value * coupon_rate
# PV of coupons (annuity)
pv_coupons = annuity_pv(coupon, yield_rate, years)
# PV of face value
pv_face = face_value / (1 + yield_rate) ** years
return pv_coupons + pv_face
# Bond parameters
face_value = 1000
coupon_rate = 0.04
yield_rate = 0.05
years = 5
price = bond_price(face_value, coupon_rate, yield_rate, years)
coupon = face_value * coupon_rateBond Valuation ======================================== Face value: $1,000 Coupon rate: 4.0% ($40/year) Market yield: 5.0% Maturity: 5 years Bond price: $956.71 Discount: $43.29
The bond trades at a discount ($956.71 vs. $1,000 face) because its 4% coupon is below the 5% market yield. Investors require compensation for accepting below-market coupons, which comes in the form of a lower price.
Let's visualize how the bond's cash flows contribute to its price:


The final cash flow of $1,040 (coupon plus principal) accounts for the bulk of the bond's value, but its contribution is substantially reduced when discounted back five years.
