我使用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函数需要添加什么? 我真的希望你能帮助我!谢谢!
答案 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
功能,则可以调查是否可以找到解决方案。函数testnslv
为global
的所有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
重新运行代码并欢欣鼓舞。所有方法和全局策略都找到了一个解决方案,其函数值的范数接近于零。