债券是一串承诺
债券是被拆分成可交易份额的贷款。发行人承诺每期支付固定票息,并在到期日偿还面值。面值 1000、票息 5%、每年付两次的 10 年期债券,承诺每半年付 25,最后一次另加 1000。它的价格就是这些承诺在今天的价值:用市场目前对该风险和期限所要求的收益率对现金流折现得到的现值。
import numpy as np
def bond_cashflows(face, coupon_rate, years, freq):
n = int(round(years * freq)) # number of payments
times = np.arange(1, n + 1) / freq # in years: 0.5, 1.0, 1.5, ...
flows = np.full(n, face * coupon_rate / freq) # a coupon each time
flows[-1] += face # and the face value with the last one
return times, flows
times, flows = bond_cashflows(1000, 0.05, 2, 2) # a 2-year bond, to keep the output short
print(times.tolist()) # [0.5, 1.0, 1.5, 2.0]
print(flows.tolist()) # [25.0, 25.0, 25.0, 1025.0]价格与收益率反向变动
对每笔现金流按 (1 + ytm / freq) ** (freq * time) 折现再相加。当收益率等于票息率时,债券恰好值其面值(平价交易)。如果市场收益率升到票息之上,新债券付得比这只多,它的价格就会跌到面值以下(折价);收益率下降则溢价交易。机制与上一节相同,只是现在有真实的付款日期。当期收益率(年票息除以价格)简单但不完整,因为它忽略了到期时的盈亏。
def bond_price(face, coupon_rate, ytm, years, freq=2):
times, flows = bond_cashflows(face, coupon_rate, years, freq)
return (flows / (1 + ytm / freq) ** (freq * times)).sum()
for ytm in (0.03, 0.05, 0.06, 0.08):
print(ytm, round(bond_price(1000, 0.05, ytm, 10), 2))
# 0.03 1171.69 yield below the coupon: premium
# 0.05 1000.0 yield = coupon: par
# 0.06 925.61 yield above the coupon: discount
# 0.08 796.15
print(round(50 / bond_price(1000, 0.05, 0.06, 10), 5)) # 0.05402 current yield: 5.40%, not the 6% yield to maturity期限越长反应越大
收益率变动一定幅度时,价格的相对变化取决于期限。远期的付款被高次幂折现,因此对利率非常敏感。收益率上升一个点,1 年期债券约跌 1%,10 年期约跌 7%,30 年期近 14%。这就是债券投资者谈论利率风险的原因,也是后面几节要建立度量指标(到期收益率、久期)来量化它的原因。
for years in (1, 5, 10, 30):
change = bond_price(1000, 0.05, 0.06, years) / 1000 - 1 # the coupon is 5%, the yield rises to 6%
print(years, round(change, 4))
# 1 -0.0096
# 5 -0.0427
# 10 -0.0744
# 30 -0.1384# The same 6% yield with annual, semiannual and monthly coupons: the quoting convention matters a little
for freq in (1, 2, 12):
print(freq, round(bond_price(1000, 0.05, 0.06, 10, freq), 2))
# 1 926.4
# 2 925.61
# 12 924.94报价收益率遵循某种约定每半年付息、收益率 6% 并不等于实际年利率 6%:它一年复利两次,实际利率是 6.09%。报告收益率时务必注明复利频率(
freq)。真实债券在付息日之间还有应计利息和日计数约定,本实验只在付息日定价,因此忽略了这些。- 价格 =
现金流 / (1 + ytm / freq) ** (freq * 时间)之和;每期付票息,最后一期另付面值。 - 收益率 = 票息率时价格 = 面值;收益率高于票息则折价,低于则溢价。价格与收益率反向变动。
- 期限越长,同样的收益率变动引起的价格变化越大;这种利率风险正是下一步久期要度量的。
下一节:到期收益率,反过来由市场价格求收益率。
实验:评分内容
- 用
bond_cashflows列出债券的各期付款25 分 - 用
bond_price把各期付款折现为价格25 分 - 用
current_yield比较票息与价格25 分 - 用
price_change观察收益率变动的影响25 分