Short-Rate Interest Rate Models › Pricing Interest Rate Derivatives
Quantitative FinanceAll chapters Short-Rate Interest Rate Models › Pricing Interest Rate DerivativesOne section · Sections in this chapter8 / 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
Short-rate models enable pricing of various interest rate derivatives. Let's implement a simple example: pricing a zero-coupon bond option.
European Bond Options
Under the Vasicek model, European options on zero-coupon bonds have closed-form solutions. These formulas resemble the famous Black-Scholes formula for stock options, but with modifications appropriate for the interest rate setting. A call option on a -maturity bond, expiring at time , gives the holder the right to purchase the bond at the strike price . The value of this option is:
Each term in this pricing formula has a clear interpretation:
- value of the European call option
- : price of zero-coupon bond maturing at
- : strike price
- : cumulative standard normal distribution function
- : standardized limits for the integration
- : volatility of the forward bond price
The first term represents the expected present value of receiving the bond, weighted by the probability (under an appropriate measure) that the option will be exercised. The second term represents the expected present value of paying the strike price, again weighted by the exercise probability under the risk-neutral measure.
The parameters and measure how far the current forward price is from the strike, scaled by volatility:
The numerator of the first term in compares the forward price of the underlying bond (which equals in a no-arbitrage setting) to the strike price :
- standardized integration limits
- : zero-coupon bond prices
- : strike price
- : volatility of the forward bond price
The volatility term measures how much uncertainty there is about the bond price at the option's expiration. In the Vasicek model, this volatility can be computed analytically:
This expression combines several factors that contribute to bond price uncertainty:
- volatility of the short rate
- : Vasicek bond coefficient
- : option expiration time
- : bond maturity time
- : mean reversion speed
The factor is the underlying volatility of the short rate. The factor translates short-rate volatility into bond price volatility for a bond maturing at , as of the option expiration at . The square-root term accounts for the accumulation of uncertainty from now until the option expiration, adjusted for mean reversion. Stronger mean reversion (larger ) reduces uncertainty because the rate is pulled back toward more quickly.
from scipy.stats import norm
def vasicek_bond_option(r0, kappa, theta, sigma, T1, T2, K, option_type="call"):
"""
Price a European option on a zero-coupon bond under Vasicek model.
Parameters:
-----------
r0 : float
Current short rate
kappa, theta, sigma : float
Vasicek parameters
T1 : float
Option expiration time
T2 : float
Bond maturity time (T2 > T1)
K : float
Strike price
option_type : str
'call' or 'put'
Returns:
--------
float : Option price
"""
# Bond prices
P_T1 = vasicek_bond_price(r0, 0, T1, kappa, theta, sigma)
P_T2 = vasicek_bond_price(r0, 0, T2, kappa, theta, sigma)
# B function for forward bond
B_T1_T2 = (1 - np.exp(-kappa * (T2 - T1))) / kappa
# Bond price volatility
sigma_P = (
sigma * B_T1_T2 * np.sqrt((1 - np.exp(-2 * kappa * T1)) / (2 * kappa))
)
# d1 and d2
d1 = (np.log(P_T2 / (K * P_T1)) / sigma_P) + 0.5 * sigma_P
d2 = d1 - sigma_P
if option_type == "call":
price = P_T2 * norm.cdf(d1) - K * P_T1 * norm.cdf(d2)
else:
price = K * P_T1 * norm.cdf(-d2) - P_T2 * norm.cdf(-d1)
return price# Example: Price a 1-year call option on a 5-year zero-coupon bond
T1 = 1.0 # Option expiration
T2 = 5.0 # Bond maturity
# The underlying bond price today
bond_price = vasicek_bond_price(r0, 0, T2, kappa, theta, sigma)
# Strike at-the-money forward
K_atm = vasicek_bond_price(r0, 0, T2, kappa, theta, sigma) / vasicek_bond_price(
r0, 0, T1, kappa, theta, sigma
)
# Price options at different strikes
strikes = np.linspace(0.75, 0.95, 11)
call_prices = [
vasicek_bond_option(r0, kappa, theta, sigma, T1, T2, K, "call")
for K in strikes
]
put_prices = [
vasicek_bond_option(r0, kappa, theta, sigma, T1, T2, K, "put")
for K in strikes
]
# Calculate ATM prices for summary
atm_call = vasicek_bond_option(r0, kappa, theta, sigma, T1, T2, K_atm, "call")
atm_put = vasicek_bond_option(r0, kappa, theta, sigma, T1, T2, K_atm, "put")
current_bond_1y = vasicek_bond_price(r0, 0, T1, kappa, theta, sigma)
Bond Option Pricing Summary: ---------------------------------------- Current 5-year bond price: 0.824426 Current 1-year bond price: 0.973999 ATM forward strike: 0.846434 ATM Call price: 0.009044 ATM Put price: 0.009044
The option prices follow familiar patterns: calls decrease as strike increases, puts increase as strike increases. The intersection near the ATM forward strike reflects put-call parity for bond options.