在R

时间:2016-05-09 16:53:47

标签: r simulation montecarlo quantitative-finance

我有使用历史数据基于极值理论成功计算VaR的代码。我试图在多个模拟价格路径上运行相同的代码(即计算每条路径的VaR),然后取这些VaR的中位数或平均值。

我在网上找到的每个例子都有模拟函数在期末返回价格,然后他们多次复制函数X.这对我来说很有意义,除了我基本上需要计算每个模拟路径的风险值。下面是我到目前为止的代码。我可以说代码在使用历史数据时起作用(即" evt"函数工作正常,并且当函数中的lossOnly,u和evtVar行不在时,数据表正确填充)。但是,我一直在尝试在第二个函数中实现模拟并尝试各种组合,这些组合都失败了。

library('RODBC')
library('nor1mix')
library('fExtremes')
library('QRM')
library('fGarch')

#function for computing the EVT VaR
evt <- function(data,u){
  #fit excess returns to gpd to get estimates

  gpdfit = tryCatch({
    gpdfit <- gpdFit(data,u,type="mle")
  }, warning = function(w) {
    gpdfit <- gpdFit(data,u,type="mle",optfunc="nlminb")
    return(gpdfit)
  }, error = function(e) {
    gpdfit <- gpdFit(data,u,type="pwm",optfunc="nlminb")
    return(gpdfit)
  }, finally = {})

  #now calculate VaRs
  xi <- gpdfit@fit$par.ests["xi"]
  beta <- gpdfit@fit$par.ests["beta"]
  Nu <- length(gpdfit@data$exceedances)
  n <- length(data)

  evtVar95 <- (u+((beta/xi)*(((n/Nu)*.05)^(-xi) - 1.)))*100
  evtVar99 <- (u+((beta/xi)*(((n/Nu)*.01)^(-xi) - 1.)))*100
  evtVar997 <- (u+((beta/xi)*(((n/Nu)*.003)^(-xi) - 1.)))*100
  evtVar999 <- (u+((beta/xi)*(((n/Nu)*.001)^(-xi) - 1.)))*100

  #return calculations
  return(cbind(evtVar95,evtVar99,evtVar997,evtVar999,u,xi,beta,Nu,n))
}

#data <- read.table("pricedata.txt")
prices <- data$V1
returns <- diff(log(prices)) #or returns <- log(prices[-1]/prices[-n])
xi <- mean(returns)
std <- sd(returns)
N <- length(prices)
lstval <- prices[N]
options(scipen = 999)
p <- c(lstval, rep(NA, N-1))

gen.path <- function(){
  N <- length(prices)
  for(i in 2:N)
    p[i] <- p[i-1] * exp(rnorm(1, xi, std))
  # plot(p, type = "l", col = "brown", main = "Simulated Price")

  #evt calculation
  #first get only the losses and then make them absolute
  lossOnly <- abs(p[p<0])
  #get threshold
  u <- quantile(lossOnly, probs = 0.9, names=FALSE)
  evtVar <- evt(lossOnly,u)

  return(evtVar)
}

runs <- 10
sim.evtVar <- replicate(runs, gen.path())
evtVar <- mean(sim.evtVar)

#add data to total table
VaR <- c(evtVar[1],evtVar[2],evtVar[3],evtVar[4],evtVar[5],evtVar[6],evtVar[7],evtVar[8],evtVar[9])  
DF <- data.frame(VaR, row.names=c("evtVar95","evtVaR_99","evtVaR_997","evtVaR_999","u","xi","beta","Nu","n"))

简而言之,我试图在monte carlo函数(第二个函数)中运行风险值函数(第一个函数)并尝试将平均模拟值放入数据表中。我知道第一个功能有效,但它是让我疯狂的第二个功能。我遇到了错误:

> sim.evtVar <- replicate(runs, gen.path())
Error in if (xi > 0.5) { : missing value where TRUE/FALSE needed
Called from: .gpdpwmFit(x, u)
Browse[1]> evtVar <- mean(sim.evtVar)
Error during wrapup: object 'sim.evtVar' not found
Browse[1]> 
> #add data to total table
> VaR <- c(evtVar[1],evtVar[2],evtVar[3],evtVar[4],evtVar[5],evtVar[6],evtVar[7],evtVar[8],evtVar[9])  
Error: object 'evtVar' not found
> DF <- data.frame(VaR, row.names=c("evtVar95","evtVaR_99","evtVaR_997","evtVaR_999","u","xi","beta","Nu","n"))
Error in as.data.frame.default(x[[i]], optional = TRUE) : 
  cannot coerce class ""function"" to a data.frame

非常感谢您提供的任何帮助!提前谢谢!

1 个答案:

答案 0 :(得分:0)

我认为问题就在这一行:

lstval <- prices[N]  

因为如果你拿一个股票价格,那就不会是负数,你在函数的这一行产生一个空的向量:

lossOnly <- abs(p[p<0])

你应该尝试改为:

lstval <- min(returns)

如果您想要数据集的最高负回报