1

I am currently doing my master thesis on Merton KMV model and I need to implement it to a set of companies. Here is the link to the csv file I used.

I am trying to loop the process to solve the nonlinear equations. So far I have found a solution to solve it once by implementing each parameters manually but now I need to apply it to the whole dataframe.

This is the code I have come up with so far:

Loading file and Library, setting the index

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

Definition of the variables

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

Function from the nleqslv package that solve the non linear equation

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
  }

Loop that should implement the function to every row in the dataset for the selected dates.

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

My two problems are:

  1. I need to solve the equation for each selected row in the dataset
  2. The output of the equation is a list and I need to append each value of teh list to two separate columns. I don't know if it is possible.

I have found a package that could solve this issue: ifrogs but it is not available through R version 3.5.1

If anyone has any insight on either problem that would be of termendous help.

Thank you in advance :)

Bhas
  • 1,844
  • 1
  • 11
  • 9
  • Please provide a reproducible example. See [here](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example). And please use a space before and after `<-` avoiding things like `r<--0.017`. `r <- -0.017` is a lot easier to read and understand. – Bhas Oct 22 '18 at 06:25
  • Thank you for those precisions. I have edited the code and included a reference to the CSV file I used. I hope it is closer to a reproducible example. – Grégoire Caye Oct 22 '18 at 07:59

1 Answers1

1

You should read the csv with

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

to keep the dates a characters. See below for why.

Your function fnewton contains errors. It uses D, E and sigmaE but these are vectors. The function accepts a vector as argument (argument x) and uses the individual elements of this vector. This combination will generate error messages. In your code xstart is a single long vector. This will not be accepted by nleqslv.

The function definition should be changed to

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
  }

The values for D etc. should be passed to the function as scalars.

nleqslv returns a list consisting of various items. One of these is x: the final value for the argument x. You cannot access these as out[1] and out[2]. You need to store the output in each row of the dataframe.

You want to store these in the dataframe so use out$x[1] and out$x[2]. Some initial values for the starting value xstart contain NA. So one needs to test if xstart contains NA before calling nleqslv.

There are other errors in your code and the final while loop. So change the final loop to this

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
}

And now check if solutions have been obtained by inspecting df$termcd.

Bhas
  • 1,844
  • 1
  • 11
  • 9
  • Wow thank you so much it seems to work like a charm now ! The only thinkg I cannot figure out is the usefullness of the column `df$termcd` But i think that the sigma_a and Asset are properly calculated so thank you again ! Sorry it took so long to reply – Grégoire Caye Oct 22 '18 at 14:54
  • Read the documentation of `nleqslv`. It tells you what `termcd` is; it is a return code of `nleqslv` and tells you if `nleqslv` was successful or not. Give the answer an up vote if you are so satisfied. – Bhas Oct 22 '18 at 14:58