【R语言】可转债隐含波动率的逆推计算教程

近些年可转债的量化项目越来越火了,从某种思路上来说,可将转债视为场内奇异期权来看待,即一份债券加上若干份看涨香草期权,所以无论是定价还是套利策略都逃不开隐含波动率和贴现率 。从定价逻辑来看,由于转债价格=贴现后的债券价格+n份的香草期权价格,所以其中的债券价格应该是低于转债价格的,这样推出来的期权价格才是正值 。但国内的二级市场有时并不理智,会发生恐慌性抛售行为,使得转债价格甚至低于了本身作为债券的价格,所以在使用Wind等金融终端的数据时会出现IV:即隐含波动率缺失的情况,这就意味着第三方数据商贴现债底时使用的贴现率有不合理的地方,对此感兴趣的朋友可以自己去思考一些新的算法,本文对此不做延伸 。
先简短说一下IV的算法逻辑,期权的Black--定价模型含有5个参数,分别为执行价k、标的现货价s、期限t、无风险收益率r以及标的波动率v,然后计算唯一的未知量:期权价格p 。现在已知p和前4个参数,唯一的未知量变为v,所以反算出来的v’即为隐含波动率,也叫做实际波动率(通常BSM算出来的期权价格和实际相差较大,且由于只有波动率是无法直接观测的,所以需要IV来描绘反应市场情绪的真实波动) 。但由于波动率的逆算牵扯到概率密度的计算,无法直接运算,所以需要计算机的帮助 。
直观点,现在我们考虑一个简单的计算,求出根号5的解(精确到小数点后3位),思考过程:
先确定个位数:依次代入1、2、3,发现在解在2~3之间;再确定十分位:依次代入1、2、3,发现也在2~3之间 。即解在2.2 ~2.3之间;同理不断地迭代下去,直到需要的精度…
【【R语言】可转债隐含波动率的逆推计算教程】这种不断试凑出来的方法便可以推广至IV的逆算 。它的好处是你不需要知道反算的解析式,而且可以通过牺牲算力来获取理论上无限精确的解 。
现在开始具体操作,还是以看涨期权为例:

【R语言】可转债隐含波动率的逆推计算教程

文章插图
我们先创建一个BSM的函数(R语言也有自带的包,但自建这个函数很简单,可供展示):
option<-function(n,s,k,r,sig){###BSM表达式###d<-(log(s/k)+(r+sig^2/2)*n)/(sig*sqrt(n))d2<-d-sig*sqrt(n)c<-s*pnorm(d)-k*exp(-r*n)*pnorm(d2)return(c)}###n为期限,s为标的现货价,k为执行价,r为利率,sig为波动率###
这里提一嘴,R语言中用的标准正态分布累计密度函数的代码是 pnorm(x),官方给的相关函数还有这些,可自行在help中查看详情,使用时注意根据情况区分:
有了BSM的函数,我们就可以开始凑结果了,首先我们并不知道反算的解有几个,但是可以肯定的我们需要的那个解处于0~1之间,所以在代码中一定会有限制其范围的内容 。普遍的,我们可以从0开始算起,也就是初始估计值cest为0:
cest<-0 ##初始值##up<-1 ##上界##low<-0 ##下界##sigma<-0.5 ##初始假设的波动率#
已知实际的期权价格为c,反算的期权价格为cest,那么当两者之差的绝对值大于了某个我们设定的值,比如0.0001的精度(一般精确到小数点后四位就足够用了),我们就认为这个反算价格是不够精确的,此时需要用上文中的BSM函数算出该波动率下的期权价格理论值:
while (abs(c-cest)>0.00001) { ##用while而不是if语句是为了循环之后的算法##cest<-option(n,s,k,rf,sigma)
然后通过一种算法进行精确,可以用实际值c-新的估计值cest的差(注意不再是绝对值)再次与精度0.00001进行比较,如果差大于0.00001,那就说明估计量太小了,需要把下界提升至范围的中位数(0~1的中位数),也就是0.5,那么此时的IV就是之前(sigma+up)/2,比如(0.5+1)/2=0.75,就从刚开始的0 ~1区间缩小到了0.5 ~0.75,此时再把0.75这个估计值代入BSM函数算出新的期权价格,再次比较,循环往复 。