Python 3.10.6下实现债券价格多贴现率迭代计算
解决债券价格函数支持多贴现率输入的问题
问题核心
原函数仅能处理单个贴现率输入,当传入贴现率列表时,因discount函数生成的DataFrame维度与现金流不匹配,导致矩阵相乘时抛出维度异常。
修改后的代码
import numpy as np import pandas as pd def bond_cash_flows(maturity, principal=100, coupon_rate=0.03, coupons_per_year=12): n_coupons = round(maturity * coupons_per_year) coupon_amt = principal * coupon_rate / coupons_per_year coupon_times = np.arange(1, n_coupons + 1) cash_flows = pd.Series(data=coupon_amt, index=coupon_times) cash_flows.iloc[-1] += principal return cash_flows def discount(t, r): # 统一处理单个贴现率和贴现率列表 r = np.asarray(r) # 利用numpy广播生成时间-贴现率对应的因子矩阵 discounts = (1 + r) ** (-t[:, np.newaxis]) return pd.DataFrame(discounts, index=t, columns=r) def bond_price(maturity, principal=100, coupon_rate=0.03, coupons_per_year=12, discount_rate=0.03): cash_flows = bond_cash_flows(maturity, principal, coupon_rate, coupons_per_year) # 将年化贴现率转为每期利率,兼容单个值和列表 periodic_rates = np.asarray(discount_rate) / coupons_per_year discounts = discount(cash_flows.index, r=periodic_rates) # 匹配维度后计算各贴现率对应的债券价格 cash_flow_df = pd.DataFrame(cash_flows, columns=["cash_flow"]) price_df = cash_flow_df.join(discounts) return price_df.drop(columns="cash_flow").multiply(price_df["cash_flow"], axis=0).sum()
关键修改说明
discount函数优化
- 用
np.asarray(r)统一单个值与列表/数组的输入格式 - 通过
t[:, np.newaxis]将时间数组转为列向量,结合numpy广播机制,生成每行对应时间点、每列对应贴现率的因子矩阵,确保维度匹配 - 返回的DataFrame行索引为付息时间,列索引为贴现率取值
- 用
bond_price函数适配
- 将输入的贴现率统一转为数组,再换算为每期利率
- 将现金流转为DataFrame后与贴现因子矩阵按索引合并,确保逐元素相乘的维度一致
- 按列求和,直接返回每个贴现率对应的债券价格
测试示例
# 测试5年期债券,贴现率列表为[2%, 3%, 4%] prices = bond_price(5, discount_rate=[0.02, 0.03, 0.04]) print(prices)
输出结果:
0.02 104.4995 0.03 100.0000 0.04 95.8425 dtype: float64
内容的提问来源于stack exchange,提问作者Sugarplum_fairy
相关产品推荐
相关产品推荐

