计算债券零息利率通常采用票息剥离法。假设有下表:
券名 | 剩余期限(年) | 票面利率 | 债券价格 | 本金 |
---|---|---|---|---|
牛奔1号 | 0.25 | 0 | 99.42 | 100 |
牛奔2号 | 0.5 | 0 | 98.83 | 100 |
牛奔3号 | 1.0 | 2.77% 每年付息一次 | 100.09 | 100 |
牛奔4号 | 1.5 | 3.46% 半年付息一次 | 101.32 | 100 |
牛奔4号 | 2.0 | 2.53% 半年付息一次 | 99.39 | 100 |
计算这些债券的零息利率实际上就是在求解如下方程组中的r1—r5:
(1)99.42*er1*0.25=100
(2)98.83*er2*0.5=100
(3)100.09*er3*1=100*(1+0.0277)
(4)100*(0.50.0346*e-r2*0.5+ 0.5*0.0346*e-r3+(1+0.5*0.0346)*e-r4*1.5)=101.32
(5)100(0.5*0.0253*e-r2*0.5+ 0.5*0.0253*e-r3+0.5*0.0253*e-r4*1.5+(1+0.5*0.0253)*e-r5*1.5)=99.39
于是接下来开始联立方程组,构建一个函数进行计算:
import numpy as np
def lxll(R):
r1,r2,r3,r4,r5=R
#各支债券价格
p1,p2,p3,p4,p5=99.42,98.83,100.09,101.32,99.39
#债券面值
mz=100.0
#票面利率
c3,c4,c5=0.0277,0.0346,0.0253
#联立等式
b1=p1*np.exp(r1*0.25)-mz
b2=p2*np.exp(r2*0.5)-mz
b3=p3*np.exp(r3)-mz*(1+c3)
b4=mz*(0.5*c4*np.exp(-r2*0.5)+0.5*c4*np.exp(-r3)+(1+0.5*c4)*np.exp(-r4*1.5))-p4
b5=mz*(0.5*c5*np.exp(-r2*0.5)+0.5*c5*np.exp(-r3)+0.5*c5*np.exp(-r4*1.5)+(1+0.5*c5)*np.exp(-r5*2))-p5
return np.array([b1,b2,b3,b4,b5])
方程组的解法使用optimize模块中的fsolve函数:
import scipy.optimize as sci
zt=sci.fsolve(lxll,[0.1,0.1,0.1,0.1,0.1])
for i in range(len(zt)):
print(round(zt[i],6),end=' ')
于是就得到结果啦:
0.023268 0.023538 0.026424 0.025411 0.028313
对这些零息利率绘图:
plt.rcParams['font.sans-serif']='SimHei'
plt.rcParams['axes.unicode_minus']=False
t=np.array([0.25,0.5,1.0,1.5,2.0])
from matplotlib import pyplot as plt
plt.figure(figsize=(10,8))
plt.plot(t,zt,'r-')#画线
plt.plot(t,zt,'rd')#画点
plt.xlabel(u'期限(年)',fontsize=13)
plt.xticks(fontsize=13)
plt.ylabel(u'零息利率',fontsize=13)
plt.yticks(fontsize=13)
plt.title(u'零息利率曲线',fontsize=13)
plt.grid('True')
plt.show()
但是在这个表中,我们发现还少了一些数据,比如:缺少0.75年、1.25年、1.75年的零息利率,如果要将它们算出来,可以采用我们在前面所用的插值法来处理:
import scipy.interpolate as si
func=si.interp1d(t,zt,kind='cubic')
t_new=np.array([0.25,0.5,0.75,1.0,1.25,1.5,1.75,2.0])
zt_new=func(t_new)
zt_new
求得结果为:
array([0.02326754, 0.02353797, 0.02515498, 0.0264237 , 0.02618357,
0.02541116, 0.02561735, 0.028313 ])
再次绘图:
plt.figure(figsize=(10,8))
plt.plot(t_new,zt_new,'r-')#画线
plt.plot(t_new,zt_new,'rd')#画点
plt.xlabel(u'期限(年)',fontsize=13)
plt.xticks(fontsize=13)
plt.ylabel(u'零息利率',fontsize=13)
plt.yticks(fontsize=13)
plt.title(u'零息利率曲线',fontsize=13)
plt.grid('True')
plt.show()
于是补足了之前缺少的数据