FAQ > 金融建模 > 建模问题 > 债券相关

Q:CB_ImpliedVolatility()相邻两日计算差异特别大?    

  • A:举例SH110059在20250620T时隐含波动率为7.69%,而在20250623T 时则突变为0.71%。
    原因:在20250623T该可转债期权价值超越了边界限制,导致隐含波动率计算异常。
    由于CB_ImpliedVolatility()底层隐藏了函数体,不便于使用时进行调试,因此针对此种异常情况我们增加了中间详情参数以及提示信息。运行以下代码可以看到中间的具体情况。
    setsysparam(pn_stock(),"SH110059");
    setsysparam(pn_date(),20250623T);
    CBIm:=CB_ImpliedVolatility(nil,nil,out_ret);
    out_ret[array("当前日","到期日")]::=datetoint(mcell);
    return out_ret;

    返回:


    【提醒警告】


    可以看到,在20250623T该可转债的单位期权价值理论下界为0.45,但此时的真实估计单位期权价值只有0.33,低于理论下界,因此此时隐含波动率相较于前一天发生了突变。并且此时会出现警告,提示此时的价值已经超过理论边界,计算异常。
    如果我们循环期权价值,便可以看到在0.45前后隐含波动率的突变情况如下


    可以看到,在期权价值低于0.45时,所计算出的隐含波动率发生了异常,结果都为0.70617,而在正常期权价值范围内的隐含波动率会随着期权价值变动而变动。
    当然,若单位期权价值超过了上界,那么同样会有类似的突变现象,此时计算出的隐含波动率会尤其的大(隐含波动率计算上界我们设置为了500%)

    对于上述情况,推荐采用历史波动率进行计算,即第一个参数填3,如:
      setsysparam(pn_stock(),"SH110059");
      setsysparam(pn_date(),20250623T);
      return CB_ImpliedVolatility(3);
    // 20.0426186375925


    PS:若需要查看多日的隐含波动率及相关中间变量数据,可结合nday实现如下:
    setsysparam(pn_stock(),"SH110059");
    setsysparam(pn_date(),20250628T);
    ret:=array();
    t:= Nday(10,'隐含波动率',v:=CB_ImpliedVolatility(nil,nil,out_ret),
         'r',(ret[k]:=out_ret,ret[k++]["隐含波动率"]:=v));
    ret[:,array("当前日","到期日")]::=datetoint(mcell);
    return ret;

    结果: