Pricing - Zero Coupon Bonds#
In this page we cover the technical aspect of the pricing for zero coupon bonds.
The main public API to revaluate the price of a bond price can be imported from fift_analytics as:
In [1]: from fift_analytics.gilts.zero_coupon import get_zero_coupon_gilt_price
get_zero_coupon_gilt_price#
Input Parameters:
Face Value \(( F )\): The maturity value of the bond.
Annual Yield \(( r )\): The annual yield to maturity as a decimal (e.g., 0.04 for 4%).
Maturity Date: The date when the bond matures.
Settlement Date: The date when the bond is settled (defaults to today if not provided).
Calculate Time to Maturity:
Calculate the number of days between the settlement date and the maturity date. Convert this to years using the Actual/Actual (ISMA) day count convention.
Where:
Compute Price Using Continuous Compounding:
Use the continuous compounding formula to calculate the bond price.
Where:
\(( P )\) is the present price of the bond. \(( F )\) is the face value of the bond. \(( r )\) is the annual yield to maturity. \(( t )\) is the time to maturity in years.
In [2]: import math
In [3]: face_value = 100
In [4]: annual_yield = 0.03
In [5]: time_to_maturity = 0.5
In [6]: present_value = face_value * math.exp(-annual_yield * time_to_maturity)
In [7]: print(round(present_value, 2))
98.51
Handle Edge Cases#
If the time to maturity is very small (approaching zero), return the face value directly.
In [8]: import math
In [9]: face_value = 100
In [10]: annual_yield = 0.03
In [11]: time_to_maturity = 3 / 365
In [12]: present_value = face_value * math.exp(-annual_yield * time_to_maturity)
In [13]: print(round(present_value, 2))
99.98
Example Calculation#
Let's go through an example:
Face Value: £1,000
Annual Yield: 4% (0.04)
Maturity Date: 2025-02-19
Settlement Date: 2025-02-16
Calculate Time to Maturity:
Days to Maturity:
In [14]: from datetime import datetime
In [15]: datetime(2025, 2, 20) - datetime(2025, 2, 17)
Out[15]: datetime.timedelta(days=3)
If we assume it's not a leap year, the year Length is 365,
Time to Maturity:
In [16]: (datetime(2025, 2, 20) - datetime(2025, 2, 17)).days / 365
Out[16]: 0.00821917808219178
Compute Price:
Using the continuous compounding formula:
In [17]: time_to_maturity = (datetime(2025, 2, 20) - datetime(2025, 2, 17)).days / 365
In [18]: print(f"The time to maturity is {time_to_maturity}")
The time to maturity is 0.00821917808219178
In [19]: exp_factor = -0.04 * time_to_maturity
In [20]: print(exp_factor)
-0.0003287671232876712
In [21]: exp_value = math.exp(exp_factor)
In [22]: print(exp_value)
0.9996712869147009
In [23]: face_value = 1000
In [24]: reval_price = round(face_value * exp_value, 2)
In [25]: print(f"The theoretical price of the zero-coupon gilt is £{reval_price}")
The theoretical price of the zero-coupon gilt is £999.67