R解非线性方程中的KMV

时间:2018-10-21 14:28:25

标签: r loops dataframe while-loop

我目前正在做有关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

nleqslv软件包中的函数,用于解决非线性方程式

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))

我的两个问题是:

  1. 我需要为数据集中的每个选定行求解方程式
  2. 方程式的输出是一个列表,我需要将list的每个值附加到两个单独的列中。我不知道是否可能。

我发现了一个可以解决此问题的软件包:ifrogs,但R版本3.5.1中没有该软件包

如果任何人对这两个问题有任何见解,那将有很大帮助。

预先感谢您:)

1 个答案:

答案 0 :(得分:1)

您应该使用来阅读csv

df <- read.csv("AREX_D.csv", stringsAsFactors=FALSE)

将日期保留为字符。有关原因,请参见下文。

您的函数fnewton包含错误。它使用DEsigmaE,但它们是向量。 该函数接受一个向量作为参数(参数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是否已获得解决方案。