風險

如何在 PerformanceAnalytics 包中計算修改後的 CVaR?

  • March 4, 2018

我的目標是在給定權重和證券回報矩陣的情況下測量投資組合的修正 CVAR。幸運的是,出色的 PerformanceAnalytics 包有一個 ES() 函式可以做到這一點。

我遇到的問題是修改後的 CVAR 需要幾分鐘來計算,而根據這篇論文(由同一作者),算法應該只需要幾秒鐘:“……我們提供了一個長而明確的公式來計算 mES 的導數. 雖然得到的公式相當複雜,但它們有助於有效地轉換成一種簡單的算法,該算法可以在不到一秒的時間內計算出 mES 和組件 mES,即使對於具有大量資產的投資組合也是如此。” (第 14 頁)

我從一個小插圖重新生成程式碼,它在使用method = "gaussian"但不是method = "modified". 我還查看了 PerformanceAnalytics 包的CRAN 參考,儘管它不像論文(上面連結)那麼清楚。

library(PerformanceAnalytics)

tickers = c( "VNO" , "VMC" , "WMT" , "WAG" , "DIS" , "WPO" , "WFC" , "WDC" ,
"WY" , "WHR" , "WMB" , "WEC" , "XEL" , "XRX" , "XLNX" ,"ZION" ,"MMM" ,
"ABT", "ADBE" , "AMD" , "AET" , "AFL" , "APD" , "ARG" ,"AA" , "AGN" ,
"ALTR" , "MO" , "AEP" , "AXP" , "AIG" , "AMGN" , "APC" ,"ADI" , "AON" ,
"APA", "AAPL" , "AMAT" ,"ADM" , "T" , "ADSK" , "ADP" , "AZO" , "AVY" ,
"AVP", "BHI" , "BLL" , "BAC" , "BK" , "BCR" , "BAX" , "BBT" , "BDX" ,
"BMS" , "BBY" , "BIG" , "HRB" , "BMC" , "BA" , "BMY" , "CA" , "COG" ,
"CPB" , "CAH" , "CCL" , "CAT" , "CELG" , "CNP" , "CTL" , "CEPH", "CERN" ,
"SCHW" , "CVX" , "CB" , "CI" ,"CINF" ,"CTAS" , "CSCO" , "C" , "CLF" ,
"CLX", "CMS" , "KO" , "CCE" , "CL" , "CMCSA" ,"CMA" , "CSC" , "CAG" ,
"COP" , "ED" , "CEG" ,"GLW" , "COST" , "CVH" , "CSX" , "CMI" , "CVS" ,
"DHR" , "DE")

library(quantmod)
getSymbols(tickers, from = "2000-12-01", to = "2010-12-31")
P <- NULL; seltickers <- NULL
for(ticker in tickers) {     
tmp <- Cl(to.monthly(eval(parse(text=ticker))))
if(is.null(P)){ timeP = time(tmp) }
if( any( time(tmp)!=timeP )) next
else P<-cbind(P,as.numeric(tmp))
seltickers = c( seltickers , ticker )
}


P = xts(P,order.by=timeP)
colnames(P) <- seltickers
R <- diff(log(P))
R <- R[-1,]
dim(R)

mu <- colMeans(R)
sigma <- cov(R)

obj <- function(w) {
if (sum(w) == 0) {
w <- w + 1e-2
}
w <- w / sum(w)
CVaR <- ES(weights = w,
method = "gaussian",
portfolio_method = "component",
mu = mu,
sigma = sigma)
tmp1 <- CVaR$ES
tmp2 <- max(CVaR$pct_contrib_ES - 0.05, 0)
out <- tmp1 + 1e3 * tmp2 
return(out)
} 

N <- ncol(R)
minw <- 0
maxw <- 1
lower <- rep(minw,N)
upper <- rep(maxw,N)

w<-rep(100/120 , 100)

# works
CVaR1 <- ES(weights = w, method = "gaussian",  portfolio_method = "component", mu = mu, sigma = sigma)

# takes too long
date()
CVaR4 <- ES(R = R , weights = w, method = "modified" , portfolio_method = "component" , clean = "boudt")
date()

更新:

事實證明,如果您想估計 m3 和 m4(偏度和峰度),您需要建構維度(資產數量)提升到 3 次和 4 次方的矩陣。因此,對於標準普爾 500 等大型矩陣,記憶體需求很大——我的信封背面計算為 25Gb。所以這個過程遭受了維度的詛咒。

的“組件 ES”部分?ES說:

對於高斯 ES 的分解,需要估計的均值和共變異數矩陣。對於修改後的 ES 的分解,還需要估計 coskewness 和 cokurtosis 矩陣。

估計 coskewness 和 cokurtosis 矩陣需要很長時間。您可以預先計算它們並將它們傳遞給ES. ?ES說:

矩陣可以通過函式’skewness.MM’和’kurtosis.MM’來估計。

但我沒有在我的系統上安裝的 PerformanceAnalytics 版本中看到這些功能。 ES本身使用未導出的函式M3.MMand M4.MM,因此您可以顯式呼叫它們:

m3 <- PerformanceAnalytics:::M3.MM(R)
m4 <- PerformanceAnalytics:::M4.MM(R)
CVaR4 <- ES(R=R , weights=w, method="modified", portfolio_method="component",
 clean="boudt", m3=m3, m4=m4)

引用自:https://quant.stackexchange.com/questions/1997