【问题标题】:KMV in r solving non linear equationsr中的KMV求解非线性方程
【发布时间】:2019-03-25 18:15:57
【问题描述】:

我目前正在完成关于 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. 等式的输出是一个列表,我需要将列表的每个值附加到两个单独的列中。不知道有没有可能。

我找到了一个可以解决这个问题的包:ifrogs,但它在 R 版本 3.5.1 中不可用

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

提前谢谢你:)

【问题讨论】:

  • 请提供一个可重现的例子。见here。请在&lt;- 前后使用空格,避免使用r&lt;--0.017 之类的内容。 r &lt;- -0.017 更容易阅读和理解。
  • 感谢您的精确。我已经编辑了代码并包含了对我使用的 CSV 文件的引用。我希望它更接近于一个可重现的例子。

标签: r loops dataframe while-loop


【解决方案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] 和 out[2]. 的身份访问这些内容 您需要将输出存储在数据帧的每一行中。

您想将这些存储在数据框中,因此请使用 out$x[1]out$x[2]。 起始值xstart 的一些初始值包含NA。 所以在调用nleqslv之前需要测试xstart是否包含NA

您的代码和最终的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 来检查是否已获得解决方案。

【讨论】:

  • 哇,非常感谢你,它现在看起来就像一个魅力!我无法弄清楚的唯一想法是df$termcd 列的有用性但我认为 sigma_a 和 Asset 计算正确,所以再次感谢您!抱歉这么久才回复
  • 阅读nleqslv的文档。它告诉你termcd 是什么;它是nleqslv 的返回码,告诉您nleqslv 是否成功。如果您很满意,请给答案投赞成票。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-10-02
  • 2021-12-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多