R - NLEQSLV循环 - 糟糕的结果

时间:2016-04-16 15:28:38

标签: r

我使用R-nleqslv软件包进行了十多年的Merton模型实施以及几家公司。我的问题是结果消息:超出了迭代限制最大值。起初它是" Jacobian太病了"但是我通过" allowSingular"克服了它。控制参数。 以下是我在R中为60家公司之一运行的内容:

    library(nleqslv)
    firm.txt<-"Q K r X.E t E0
    1  570397892    0.037368583 0.233290565 0.712328767 87670471 
    2  298421077    0.041952083 0.253988381 0.715068493 95393513 
    3  33869138     0.040477083 0.664630887 0.717808219 48896391 
    4  38419643     0.032099417 0.475755744 0.715068493 56174054 
    5  35286530     0.027812167 0.252814225 0.715068493 53598838 
    6  36801905     0.027028333 0.552871571 0.712328767 42849195 
    7  37798118     0.015626667 0.374539554 0.715068493 62628367 
    8  40594887     0.015787417 0.227146212 0.715068493 82262449 
    9  35638457     0.012659167 0.205291468 0.715068493 75268900 
    10  34889369    0.005081417 0.602946469 0.715068493 80139925"
    firm<-read.table(textConnection(firm.txt),header=TRUE,stringsAsFactors=FALSE)
    #Loop with solver for 10 dates:
    for(i in 1:10) {
    K<-firm[i,2]
    r<-firm[i,3]
    X.E<-firm[i,4]
    t<-firm[i,5]
    E0<-firm[i,6]
    BS<-function(x){
    f <- rep(NA, length(x))
    f[1] <- (x[1] * pnorm(log (x[1]/K)+(r+( (x[1]^2) / 2) ) * T ) / ( x[2] *sqrt(t))-exp(-r*t)*K*pnorm(log (x[1]/K)+(r-((x[1]^2)/2))*t)/(x[2]*sqrt(t)))-E0
    f[2]<-((x[1]*exp(-t)*pnorm(log (x[1]/K)+(r+((x[1]^2) / 2) ) *t)/( x[2] *sqrt(t))* x[2]) /E0)-X.E
    f
    }
    p0<-c((E0+K),X.E*(V.E/(V.E+K)))
    print(p0)
    ans<-nleqslv(p0,BS,control=list(allowSingular=TRUE))
    print(ans)
    }

nleqslv函数需要添加什么? 我真的希望你能帮助我!谢谢!

1 个答案:

答案 0 :(得分:1)

我认为BS函数中的公式不正确。 见Black Scholes model。 前段时间有人在Stackoverflow上问过类似的问题:Solving nonlinear equations。 您还通过不使用中间变量使公式不可读,这使得分析和调试几乎不可能。

将您的BS功能写为

BS<-function(x){
    f <- rep(NA, length(x))
    d1 <- (log(x[1]/K)+(r+((x[2]^2) / 2) ) * t ) / (x[2]*sqrt(t))
    d2 <- d1 - x[2]*sqrt(t)
    f[1] <- x[1] * pnorm(d1) -exp(-r*t)*K*pnorm(d2)-E0
    f[2]<- ((x[1]*exp(-t)*pnorm(d1)* x[2]) /E0)-X.E
    f
}

并按如下方式更正p0的作业

p0<-c((E0+K),X.E*(E0/(E0+K)))

来自你的评论。

如果你使用它,你会得到更好的结果。仍有问题,但解决这些问题取决于你。

警告:我对Black-Scholes模型一无所知。只解决非线性方程(有时)。

如果您使用testnslv包中的nleqslv功能,则可以调查是否可以找到解决方案。函数testnslvglobal的所有nleqslv方法生成摘要。 像这样:

for(i in 1:10) {
    K<-firm[i,2]
    r<-firm[i,3]
    X.E<-firm[i,4]
    t<-firm[i,5]
    E0<-firm[i,6]

    BS<-function(x){
        f <- rep(NA, length(x))
        d1 <- (log(x[1]/K)+(r+((x[2]^2) / 2) ) * t ) / (x[2]*sqrt(t))
        d2 <- d1 - x[2]*sqrt(t)
        f[1] <- x[1] * pnorm(d1) -exp(-r*t)*K*pnorm(d2)-E0
        f[2]<- ((x[1]*exp(-t)*pnorm(d1)* x[2]) /E0)-X.E
        f
    }
    p0<-c((E0+K),X.E*(E0/(E0+K)))
    print(p0)
    z <- testnslv(p0,BS,control=list(allowSingular=TRUE))
    print(z)
}

你会发现你的方程系统相当敏感。 您必须分析结果以获得正确的解决方案。

<强>附录

解决方程组时遇到的困难是由于函数值的非常差的缩放造成的。 您可以在代码中的print(BS(p0))之后插入print(p0)来查看此内容。与f[1]相比,您会发现f[2]非常大。

解决方案非常简单:使用f[1] <- ...缩放K的右侧。换句话说,除去K。 然后f[1]的等式读取:

f[1] <- (x[1]/K) * pnorm(d1) -exp(-r*t)*pnorm(d2)-E0/K

使用testnslv重新运行代码并欢欣鼓舞。所有方法和全局策略都找到了一个解决方案,其函数值的范数接近于零。