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) 取整,避免浮点误差导致多算一期。