R中使用蒙特卡罗模拟的风险价值(极值理论)

use*_*086 5 simulation r 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"))
Run Code Online (Sandbox Code Playgroud)

简而言之,我试图在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
Run Code Online (Sandbox Code Playgroud)

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

小智 0

我认为问题是这一行:

lstval <- prices[N]  
Run Code Online (Sandbox Code Playgroud)

因为如果你采用股票价格,它永远不会是负数,你会在函数的这一行生成一个空向量:

lossOnly <- abs(p[p<0])
Run Code Online (Sandbox Code Playgroud)

你应该尝试:

lstval <- min(returns)
Run Code Online (Sandbox Code Playgroud)

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