用R计算风险价值和风险条件价值(预期亏空)

时间:2016-06-03 13:16:57

标签: r optimization var

我是R的新手,对使用Portfolio Analytics软件包计算VaR和CVaR有一些疑问。

我在csv文件中有历史返回数据。例如如下:

    time         return of stock1    return of stock2   return of stock3
    2016-01-01  -0.6184181087       -0.126394629        0.2537283152
    2016-01-02  -0.1738764113       -0.8100882955       -0.3162766513
    2016-01-03  -0.8229430174       -0.5007778048       -0.880233143
    ...         ...                 ...                 ...

(I)我想计算具有相同权重(后来具有不同权重)的该投资组合的风险价值和风险条件值。我想使用历史数据。 (我想要对概率分布做出假设 - 特别是不要假设高斯分布。)例如,对于VaR我基本上想找到百分位数。

(II)我想通过优化CVaR来优化权重。 (再次通过历史方法)。

我有以下问题:

  1. 如果我使用VaR函数并选择method = c(“historical”),它是否会计算我的历史数据的相应百分位数?

  2. 在一些在线教程的帮助下,到目前为止,我已尝试(但尚未完全理解)以下内容:

     *Loading data into file*
     testData_return <- Return.read(filename = "myTest.csv", frequency = "d",format = "%Y-%m-%d", header = TRUE)
    
     *Create the portfolio specification object*
      Wcons <- portfolio.spec(assets = colnames(testData_return))
    
     * Add box constraints *
      Wcons <- add.constraint(portfolio = Wcons, type='box', min=0, max=1)  
      Wcons <- add.constraint( portfolio=Wcons, type = "weight_sum", min_sum=0.99, max_sum=1.01)         * why can't I put min_sum=1, max_sum=1 ? *
    
      * Add an objective * 
      ObjSpec = add.objective(portfolio = Wcons, type = "risk", name = "VaR", arguments=list(p=0.95), enabled=TRUE)
    
    
    * value of the objective function * 
    constrained_objective(w=rep(1/3,3), R=testData_return,portfolio = ObjSpec)
    

    给了我“VaR 0.5707718”。

  3. 为了测试这个结果,我选择了VaR函数

        VaR(testData_return, p = 0.95, method = c("historical"), clean = c("none"), portfolio_method = c("single")) 
    

    这会使我返回结果:

          "stock1     stock2     stock3
          VaR -0.8836453 -0.9002575 -0.9151286"
    

    因此,我不明白为什么我得到不同的结果,我不明白为什么我得到最后一行的三个结果。

    为了进一步测试,我使用python如下:

    我通过将每天的回报加起来并除以3来合并回报,从而产生一个带有一列的csvfile。

        -0.1636948075
        -0.433413786
        -0.7346513217
        ...
    

    然后我计算了这些回报的第95百分位数(与上述相同)。

        percentile = 0.95
    
        * fname is the name of my file with the one column of data *
        returns_values = np.loadtxt(fname, skiprows=0, usecols=[0], unpack=True)
    
         print(np.percentile(returns_values, percentile))
    

    结果这给了我-0.74321324。

    所以,我不明白为什么这个结果与我的第一个结果(-0.74!= 0.57)大不相同。 另外,我不明白为什么我的第二种方法给了我每个股票的VaR。

    提前感谢您的帮助! :)

    最佳, 夏洛特

1 个答案:

答案 0 :(得分:2)

下面的示例代码尝试通过使用三个资产的VaR计算的简单示例来回答您的问题。由于您的帖子没有提供完整的退货时间历史记录,因此该示例首先使用quantmod包从雅虎财务中获取三个股票代码的价格数据,然后计算退货。

代码使用VaR函数和VaR函数计算portfolio_method="single"函数计算的每个股票的quantile。由于有三个股票,每个方法给出VaR的三个值,结果应该对每个股票达成一致。

投资组合计算的约束和目标与您拥有的一致。参数列表已扩展为包含method ="historical“,表示VaR应直接从累积分布函数计算,而不是从模型和portfolio_method="component”计算,以表示{{1}函数应使用输入权重来计算投资组合VaR。具有给定约束和目标的VaR用于找到最佳投资组合。结果包含在optimize.portfolio

最后,投资组合的opt使用VaR为投资组合constrained_objective计算,ObjSpec_hist指定VaR并与使用{{计算的投资组合VaR进行比较1}}用于使用优化权重形成的投资组合。这些结果应该达成一致。

代码如下:

quantile

CVaR计算

要使用CVaR而不是VaR作为目标, library(xts) library(quantmod) library(PerformanceAnalytics) library(PortfolioAnalytics) tickers <- c("AAPL", "MSFT", "AMZN") start_date <- "2016-01-01" percentile <- .95 # confidence level used in VaR calculations # # get Adjusted Close prices from Yahoo Finance # prices <- xts() for( tick in tickers) { prices <- merge(prices, getSymbols(Symbols=tick, from=start_date, auto.assign=FALSE)[,paste(tick,"Adjusted",sep=".")]) } colnames(prices) <- tickers # # transform index from POSIXct to Date class # index(prices) <- as.Date(index(prices)) # # compute returns # testData_return <- diff(prices, arithmetic=FALSE, na.pad=FALSE) - 1 # # Compare VaR with quantile calculations for assets # when portfolio_method = "single" in VaR, the VaR for each column in R is calculated # VaR_asset_hist <- VaR(R = testData_return, p=percentile, method="historical", portfolio_method = "single") print(VaR_asset_hist) quant_asset_hist <- sapply(testData_return, quantile, probs=1-percentile, type=7) print(quant_asset_hist) # # Create the portfolio specification object # Wcons <- portfolio.spec(assets = colnames(testData_return)) # # Add long_only and weight_sum = 1 constraints # Wcons <- add.constraint(portfolio = Wcons, type='box', min=0, max=1) Wcons <- add.constraint( portfolio=Wcons, type = "weight_sum", min_sum=0.99, max_sum=1.01) # # Set the objective to minimize VaR using historical returns # portfolio_method ="component" tells VaR to use values of weights argument and calculate VaR for the portfolio # ObjSpec_hist = add.objective(portfolio = Wcons, type = "risk", name = "VaR", arguments=list(p=percentile, method="historical", portfolio_method="component"), enabled=TRUE) opt <- optimize.portfolio(R =testData_return, portfolio=ObjSpec_hist, search_size = 2000, trace = TRUE) print(opt) # # compare VaR calculated using the optimization results with the quantile case. # the VaR function calculates VaR slightly differently for historical data depending upon whether the # portfolio_method = "single" or "component". The values for the quantile arguments probs and type used below should # give the same results for both the constrained_objective and quantile functions # VaR_port_opt <-constrained_objective(w=weights(opt), R=testData_return,portfolio = ObjSpec_hist) quant_probs <- floor((1-percentile)*nrow(testData_return))/nrow(testData_return) quant_port_opt <- quantile( testData_return%*%weights(opt), probs = quant_probs, type=1) cat(paste("VaR using opt weights =", VaR_port_opt, "\nquantile calculation using opt weights =", quant_port_opt)) 应更改为optimization_method,因为CVaR优化可以表示为二次规划问题。除此之外,"ROI"约束可以替换为设置weight_sum的{​​{1}}约束。代码现在看起来像:

full_investment