QuantLib Python如何计算零息债券价格?代码结果与预期不符求助
问题描述
我希望计算面值1000美元、利率10%、期限5年的零息债券价格,预期价格为620.92美元,计算公式为:
$$620.92 = 1000/((1.10)^5)$$
以下是使用Python 3.9.12和QuantLib 1.29编写的尝试代码:
import QuantLib as ql # Set up the bond parameters face_value = 1000 interest_rate = 0.10 maturity_date = ql.Date(9, 3, 2028) # Maturity in 5 years issue_date = ql.Date(9, 3, 2023) # Issue date today # Create a bond object bond = ql.ZeroCouponBond(0, ql.NullCalendar(), face_value, maturity_date) # Set up the bond engine spot_curve_handle = ql.YieldTermStructureHandle(ql.FlatForward(issue_date, interest_rate, ql.Actual365Fixed())) bond_engine = ql.DiscountingBondEngine(spot_curve_handle) # Assign the bond engine to the bond object bond.setPricingEngine(bond_engine) # Calculate the bond price price = bond.cleanPrice() print(f"The price of the bond is: {price:.2f}")
运行后bond.cleanPrice()返回60.67美元,bond.NPV()返回606.20美元,均与预期的620.92美元不符。请问如何修改代码以得到该“教科书式”债券价格?
解决方案及代码修改
问题核心在于复利方式不匹配:教科书计算采用的是年度复利(Annual Compounding),而QuantLib中FlatForward默认使用连续复利(Continuous Compounding),同时cleanPrice()返回的是面值的百分比,而非实际美元金额。
修改后的代码如下:
import QuantLib as ql # 债券参数设置 face_value = 1000 interest_rate = 0.10 maturity_date = ql.Date(9, 3, 2028) issue_date = ql.Date(9, 3, 2023) # 创建零息债券对象 bond = ql.ZeroCouponBond(0, ql.NullCalendar(), face_value, maturity_date) # 构建收益率曲线:指定年度复利方式 # 关键改动:添加Compounding和Frequency参数,匹配教科书的年度复利 spot_curve_handle = ql.YieldTermStructureHandle( ql.FlatForward( issue_date, interest_rate, ql.Actual365Fixed(), ql.Compounded, # 复利方式:离散复利 ql.Annual # 复利频率:每年一次 ) ) bond_engine = ql.DiscountingBondEngine(spot_curve_handle) bond.setPricingEngine(bond_engine) # 获取结果:cleanPrice是面值百分比,乘以面值/100得到实际价格;或直接用NPV clean_price_percent = bond.cleanPrice() actual_price = clean_price_percent * face_value / 100 npv_price = bond.NPV() print(f"教科书式债券价格(cleanPrice转换): {actual_price:.2f}") print(f"教科书式债券价格(NPV直接获取): {npv_price:.2f}")
改动说明
- 复利方式调整:在
FlatForward构造中明确指定ql.Compounded(离散复利)和ql.Annual(年度频率),完全匹配教科书公式的复利规则。 - 价格数值转换:
cleanPrice()返回的是债券价格相对于面值的百分比(例如62.09代表面值的62.09%),因此需要乘以face_value/100得到实际美元金额;而bond.NPV()会直接返回基于面值的实际现值,结果与转换后的cleanPrice一致。
运行修改后的代码,将输出预期的620.92美元。
内容的提问来源于stack exchange,提问作者D I
相关产品推荐
相关产品推荐

