我目前正在做有关Merton KMV模型的硕士论文,我需要将其应用于一系列公司。这是我使用的csv file的链接。
我正在尝试循环求解非线性方程组。到目前为止,我已经找到了一种解决方案,可以通过手动实现每个参数来解决它,但是现在我需要将其应用于整个数据帧。
这是我到目前为止提出的代码:
library(nleqslv) #this is a package that solve a non linear equation to compute both the value of teh asset and its volatility according to the Black and Scholes formula in the Merton model
df <- read.csv("/AREX_D.csv")
rownames(df) <- df$Date
start <- as.Date("31-12-16",format="%d-%m-%y")
end <- as.Date("31-12-17",format="%d-%m-%y")
theDate <- start
E <- df$Market.Cap
D <- df$Default.point
T <- 1
sigmaE <- df$stdev
r <- -0.017
df$Asset <- NA
df$sigmaA <- NA
df$DD <- NA
df$PD <- NA
fnewton <- function(x)
{
y <- numeric(2)
d1 <- (log(x[1]/D)+(r+x[2]^2/2)*T)/x[2]*sqrt(T)
d2 <- d1-x[2]*sqrt(T)
y[1] <- E-(x[1]*pnorm(d1)-exp(-r*T)*D*pnorm(d2))
y[2] <- sigmaE*E-pnorm(d1)*x[2]*x[1]
y
}
xstart <- c(E+D, sigmaE)#initialising the x-values (asset value and volatility for the function to solve the non linear equation
while (theDate<=end)
{
out <- nleqslv(xstart,fnewton,method="Newton")
df$Asset <- out[1]
df$sigmaA <- out[2]
theDate <- theDate+1
}
print(tail(df))
我的两个问题是:
我发现了一个可以解决此问题的软件包:ifrogs,但R版本3.5.1中没有该软件包
如果任何人对这两个问题有任何见解,那将有很大帮助。
预先感谢您:)
答案 0 :(得分:1)
您应该使用来阅读csv
df <- read.csv("AREX_D.csv", stringsAsFactors=FALSE)
将日期保留为字符。有关原因,请参见下文。
您的函数fnewton
包含错误。它使用D
,E
和sigmaE
,但它们是向量。
该函数接受一个向量作为参数(参数x
),并使用该向量的各个元素。
此组合将生成错误消息。
在您的代码中xstart
是单个长向量。 nleqslv
不会接受。
函数定义应更改为
fnewton <- function(x, D, E, sigmaE)
{
y <- numeric(2)
d1 <- (log(x[1]/D)+(r+x[2]^2/2)*T)/x[2]*sqrt(T)
d2 <- d1-x[2]*sqrt(T)
y[1] <- E-(x[1]*pnorm(d1)-exp(-r*T)*D*pnorm(d2))
y[2] <- sigmaE*E-pnorm(d1)*x[2]*x[1]
y
}
D
等的值应作为标量传递给函数。
nleqslv
返回包含各种项目的列表。其中之一是x
:参数x
的最终值。
您不能以out[1]
的身份访问它们,也不能以[2] .
的身份访问
您需要将输出存储在数据框的每一行中。
您要将它们存储在数据框中,因此请使用out$x[1]
和out$x[2]
。
起始值xstart
的一些初始值包含NA
。
因此,需要在调用xstart
之前测试NA
是否包含nleqslv
。
您的代码和最后的while
循环中还有其他错误。
因此,将最终循环更改为此
df$termcd <- -1
kstart <- which(df$Date == "03/01/2017")
kend <- NROW(df)
for( k in kstart:kend ) {
xstart <- c(E[k]+D[k], sigmaE[k])
if(anyNA(xstart)) { next } # skip NA in input
out <- nleqslv(xstart,fnewton,method="Newton", D=D[k],E=E[k],sigmaE=sigmaE[k])
df$Asset[k] <- out$x[1]
df$sigmaA[k] <- out$x[2]
df$termcd[k] <- out$termcd
}
现在检查df$termcd
是否已获得解决方案。