2. 附息债券现金流构建与定价
任务说明
给定债券面值、票面利率、付息频率、到期年限与到期收益率,生成每期现金流(票息 + 到期本金),并用现金流贴现法计算理论价格。付息频率支持年付、半年付、季付。
实现思路
期数 n = 到期年限 × 频率
每期票息 C = 面值 × 票面利率 / 频率
每期贴现率 y = 到期收益率 / 频率
价格 P = Σ C/(1+y)^t + 面值/(1+y)^n
完整代码
def build_cashflows(face, coupon_rate, freq, years):
"""生成现金流表:[(期数, 现金流)],最后一期含本金"""
n = int(years * freq)
c = face * coupon_rate / freq
flows = []
for t in range(1, n + 1):
cf = c + (face if t == n else 0.0)
flows.append((t, cf))
return flows
def price_from_cashflows(flows, ytm, freq):
"""按现金流贴现计算理论价格"""
y = ytm / freq
return sum(cf / (1 + y) ** t for t, cf in flows)
if __name__ == "__main__":
face, coupon_rate, freq, years, ytm = 1000, 0.06, 2, 3, 0.05
flows = build_cashflows(face, coupon_rate, freq, years)
print("期数 现金流")
for t, cf in flows:
print(f"{t:>3} {cf:>8.2f}")
price = price_from_cashflows(flows, ytm, freq)
print(f"\n理论价格: {price:.4f}")
运行与验证
直接运行脚本:python bond.py。预期输出 6 期现金流,前 5 期为 30.00,第 6 期为 1030.00;理论价格约为 1027.54。若价格与手算贴现结果一致,即通过验证。
关键点
- 最后一期现金流必须包含本金,否则价格会偏低。
- 贴现率需按频率折算,年化收益率不能直接用于半年或季度付息。
- 期数用
int(years * freq)取整,避免浮点误差导致多算一期。