KMV信用风险模型的R实践
2020-04-10 本文已影响0人
六胜一平
KMV模型近年来被广泛应用于上市企业信用风险评估评级,在金融风险管理领域风头正茂。KMV模型将企业的股权价值E、资产价值V和负债D整合到Black-Scholes期权定价公式中,把股权价值E看做一份标的物初始价格为V,敲定价格为D的欧式看涨期权的价格,用可以观测到的股权价值、负债、股价波动率等数据,通过求解非线性方程组来得到资产价值V及其波动率σ。下面几个公式就是KMV模型的核心。



求解上面的非线性方程组看起来并不困难,R中的nleqslv,或者MATLAB中的fsolve应该均可胜任,R代码如下
KMVF<-function(x) {
V0=x[1]
sigmav=x[2]
y <- numeric(2)
d1<-( log(V0/D)+(r+0.5*sigmav^2)*T ) / ( sigmav*sqrt(T))
d2<-d1-sigmav*sqrt(T)
y[1]<-V0*pnorm(d1)-exp(-r*T)*D*pnorm(d2)-E
y[2]<-(V0*sigmav/E)*pnorm(d1)-EquityTheta
return(y)
}
z<-nleqslv(x0,KMVF,method="Newton",control = list(allowSingular=T))
但上述代码存在一个大问题,由于需要求解的两个参数V和σ在数量级上差异太大(一般V/σ~1e+10),用牛顿法求根时,雅可比矩阵往往是奇异的,导致算法不收敛。为了解决这个问题,有人考虑对方程组作变形处理,引入E和D的比值,以对V进行标准化处理,如下面的代码所示。
EtoD <- E/D;
KMVfun<-function(x) {
y <- numeric(2);
d1<-( log(x[1]*EtoD)+(r+0.5*x[2]^2)*T ) / ( x[2]*sqrt(T))
d2<-d1-x[2]*sqrt(T)
y[1]<-x[1]*pnorm(d1)-exp(-r*T)*pnorm(d2)/EtoD-1
y[2]<-pnorm(d1)*x[1]*x[2]-EquityTheta
y
}
z<-nleqslv(x0,KMVfun,method="Newton",control = list(allowSingular=T))
通过上面的变形,nleqslv能很快收敛,求得变形后方程组的根roota。这个方法在网上流传很广,然而该变形是如何推导出来的,理论上有无依据,还需费些思量。
其实除此以外,还有一个更简单直观的方法可以解决参数量级差异问题,就是将E和D按比例缩小,再将求出的V按同等比率放大。记该方法求得的根为rootx,我们用一个简单的算例比较上面两种方法求得的根。
roota
V=2.588850e+08 sigma=5.796537e-01
y1=-8.072788e+06 y2=-1.778516e-02
rootx
V=2.681669e+08 sigma=5.626448e-01
y1=8.940697e-08 y2=-6.661338e-16
资产价值上的差距达到九百万,真是失之毫厘、谬以千里,而且方程组在rootx处更接近0点,roota则看起来根本就不是原方程组的根,表明这个在网上流传甚广的方法其正确性是值得商榷的。V和sigma的值将直接影响后续的违约距离计算,不能不谨慎对待。