Path: blob/master/demo/demo_robustCovMatForPA.R
1433 views
## ----setup, include=FALSE-------------------------------1knitr::opts_chunk$set(echo = TRUE, fig.width = 6, fig.height = 4, fig.align = "center")234## ---- warning = FALSE, message = FALSE------------------5library(PCRA)6library(PortfolioAnalytics)7library(CVXR)8library(xts)91011## -------------------------------------------------------12stocksCRSPweekly <- getPCRAData("stocksCRSPweekly")13dateRange <- c("2006-01-01", "2012-12-31")14stockItems <- c("Date", "TickerLast", "CapGroupLast", "Return", "MktIndexCRSP")15returnsAll <- selectCRSPandSPGMI("weekly",16dateRange = dateRange,17stockItems = stockItems,18factorItems = NULL,19subsetType = "CapGroupLast",20subsetValues = "SmallCap",21outputType = "xts")22returns <- returnsAll[,1:30]23MARKET <- returnsAll[, 107]24returns10 <- returnsAll[140:300, 21:30]25range(index(returns))26range(index(returns10))272829## -------------------------------------------------------30tsPlotMP(MARKET)313233## -------------------------------------------------------34tsPlotMP(returns[, 21:30])353637## -------------------------------------------------------38tsPlotMP(returns10)394041## -------------------------------------------------------42funds <- colnames(returns10)43pspec <- portfolio.spec(funds)44pspec <- add.constraint(pspec, type="full_investment")45pspec <- add.constraint(pspec, type="long_only")46pspec <- add.objective(pspec, type="risk", name="var")474849## -------------------------------------------------------50opt <- optimize.portfolio(returns10, pspec, optimize_method = "CVXR")515253## -------------------------------------------------------54opt555657## -------------------------------------------------------58outCovClassic <- opt.outputMvo(opt, returns10, digits = 3, frequency = "weekly")59(WtsCovClassic <- outCovClassic$Wgts)606162## ---- eval = FALSE--------------------------------------63## custom.covRob.MM <- function(R, ...){64## out <- list()65## if(hasArg(tol)) tol = match.call(expand.dots = TRUE)$tol else tol = 1e-466## if(hasArg(maxit)) maxit = match.call(expand.dots = TRUE)$maxit else maxit = 5067## robustCov <- RobStatTM::covRobMM(X=R, tol=tol, maxit=maxit)68## out$sigma <- robustCov$cov69## out$mu <- robustCov$center70## return(out)71## }727374## -------------------------------------------------------75opt <- optimize.portfolio(returns10, pspec,76optimize_method = "CVXR",77momentFUN = "custom.covRob.MM",78maxit = 100, tol = 1e-5)79outCovRobMM <- opt.outputMvo(opt, returns10, digits = 3, frequency = "weekly")80(WtsCovRobMM <- outCovRobMM$Wgts)818283## ---- eval = FALSE--------------------------------------84## custom.covRob.Rocke <- function(R, ...){85## out <- list()86## if(hasArg(tol)) tol = match.call(expand.dots = TRUE)$tol else tol = 1e-487## if(hasArg(maxit)) maxit = match.call(expand.dots = TRUE)$maxit else maxit = 5088## if(hasArg(initial)) initial = match.call(expand.dots = TRUE)$initial else initial = 'K'89## if(hasArg(maxsteps)) maxsteps = match.call(expand.dots = TRUE)$maxsteps else maxsteps = 590## if(hasArg(propmin)) propmin = match.call(expand.dots = TRUE)$propmin else propmin = 291## if(hasArg(qs)) qs = match.call(expand.dots = TRUE)$qs else qs = 5092##93## robustCov <- RobStatTM::covRobRocke(X = R, initial = initial, maxsteps = maxsteps, propmin = propmin,94## qs = qs, tol = tol, maxit = maxit)95##96## out$sigma <- robustCov$cov97## out$mu <- robustCov$center98## return(out)99## }100101102## -------------------------------------------------------103opt <- optimize.portfolio(returns10, pspec,104optimize_method = "CVXR",105momentFUN = "custom.covRob.Rocke",106tol = 1e-5, maxit =100, maxsteps = 7)107outCovRobRocke <- opt.outputMvo(opt, returns10, digits = 3, frequency = "weekly")108(WtsCovRobRocke <- outCovRobRocke$Wgts)109110111## ---- eval = FALSE--------------------------------------112## custom.covRob.Mcd <- function(R, ...){113##114## if(hasArg(control)) control = match.call(expand.dots = TRUE)$control else control = MycovRobMcd()115## if(hasArg(alpha)) alpha = match.call(expand.dots = TRUE)$alpha else alpha = control$alpha116## if(hasArg(nsamp)) nsamp = match.call(expand.dots = TRUE)$nsamp else nsamp = control$nsamp117## if(hasArg(nmini)) nmini = match.call(expand.dots = TRUE)$nmini else nmini = control$nmini118## if(hasArg(kmini)) kmini = match.call(expand.dots = TRUE)$kmini else kmini = control$kmini119## if(hasArg(scalefn)) scalefn = match.call(expand.dots = TRUE)$scalefn else scalefn = control$scalefn120## if(hasArg(maxcsteps)) maxcsteps = match.call(expand.dots = TRUE)$maxcsteps121## else maxcsteps = control$maxcsteps122##123## if(hasArg(initHsets)) initHsets = match.call(expand.dots = TRUE)$initHsets124## else initHsets = control$initHsets125##126## if(hasArg(seed)) seed = match.call(expand.dots = TRUE)$seed else seed = control$seed127## if(hasArg(tolSolve)) tolSolve = match.call(expand.dots = TRUE)$tolSolve else tolSolve = control$tolSolve128## if(hasArg(wgtFUN)) wgtFUN = match.call(expand.dots = TRUE)$wgtFUN else wgtFUN = control$wgtFUN129##130## if(hasArg(use.correction)) use.correction = match.call(expand.dots = TRUE)$use.correction131## else use.correction = control$use.correction132##133## robustMCD <- robustbase::covMcd(x = R, alpha = alpha,134## nsamp = nsamp, nmini = nmini,135## kmini = kmini, seed = seed,136## tolSolve = tolSolve, scalefn = scalefn,137## maxcsteps = maxcsteps,138## initHsets = initHsets,139## wgtFUN = wgtFUN, use.correction = use.correction)140##141## return(list(mu = robustMCD$center, sigma = robustMCD$cov))142## }143144145## -------------------------------------------------------146opt <- optimize.portfolio(returns10, pspec,147optimize_method = "CVXR",148momentFUN = "custom.covRob.Mcd",149alpha = 0.75, nsamp = 600)150outCovRobMcd <- opt.outputMvo(opt, returns10, digits = 3, frequency = "weekly")151(WtsCovRobMcd <- outCovRobMcd$Wgts)152153154## ---- eval = FALSE--------------------------------------155## MycovRobMcd <- function(alpha = 1/2,156## nsamp = 500, nmini = 300, kmini = 5,157## scalefn = "hrv2012", maxcsteps = 200,158## seed = NULL, tolSolve = 1e-14,159## wgtFUN = "01.original", beta,160## use.correction = TRUE161## ){162## if(missing(beta) || !is.numeric(beta))163## beta <- 0.975164##165## return(list(alpha = alpha, nsamp = nsamp,166## nmini = as.integer(nmini), kmini = as.integer(kmini),167## seed = as.integer(seed),168## tolSolve = tolSolve, scalefn = scalefn,169## maxcsteps = as.integer(maxcsteps),170## wgtFUN = wgtFUN, beta = beta,171## use.correction = use.correction))172## }173174175## ---- eval = FALSE--------------------------------------176## covMcd.params <- MycovRobMcd(alpha = 0.75, nsamp = 600)177## opt <- optimize.portfolio(returns, pspec,178## optimize_method = "CVXR",179## momentFUN = "custom.covRob.Mcd",180## control = covMcd.params)181182183## ---- eval = FALSE--------------------------------------184## custom.covRob.TSGS <- function(R, ...){185## if(hasArg(control)) control = match.call(expand.dots = TRUE)$control else control = MycovRobTSGS()186## if(hasArg(filter)) filter = match.call(expand.dots = TRUE)$filter else filter = control$filter187##188## if(hasArg(partial.impute)) partial.impute = match.call(expand.dots = TRUE)$partial.impute189## else partial.impute = control$partial.impute190##191## if(hasArg(tol)) tol = match.call(expand.dots=TRUE)$tol else tol=control$tol192## if(hasArg(maxiter)) maxiter = match.call(expand.dots = TRUE)$maxiter else maxiter = control$maxiter193## if(hasArg(loss)) loss = match.call(expand.dots = TRUE)$loss else loss = control$loss194## if(hasArg(init)) init = match.call(expand.dots = TRUE)$init else init = control$init195##196## tsgsRob <- GSE::TSGS(x = R, filter = filter,197## partial.impute = partial.impute, tol = tol,198## maxiter = maxiter, method = loss,199## init = init)200##201## return(list(mu = tsgsRob@mu, sigma = tsgsRob@S))202##203## }204205206## -------------------------------------------------------207opt <- optimize.portfolio(returns10, pspec,208optimize_method = "CVXR",209momentFUN = "custom.covRob.TSGS")210outCovRobTSGS <- opt.outputMvo(opt, returns10, digits = 3, frequency = "weekly")211(WtsCovRobTSGS <- outCovRobTSGS$Wgts)212213214## ---- eval = F------------------------------------------215## MycovRobTSGS <- function(filter = c("UBF-DDC","UBF","DDC","UF"),216## partial.impute = FALSE, tol = 1e-4, maxiter = 150,217## loss = c("bisquare","rocke"),218## init = c("emve", "qc", "huber", "imputed", "emve_c")){219##220## filter <- match.arg(filter)221## loss <- match.arg(loss)222## init <- match.arg(init)223##224## return(list(filter = filter, partial.impute = partial.impute,225## tol = tol, maxiter = as.integer(maxiter),226## loss = loss,init))227## }228229230## -------------------------------------------------------231dat <- data.frame(rbind(WtsCovClassic, WtsCovRobMM, WtsCovRobRocke,232WtsCovRobMcd, WtsCovRobTSGS))233print.data.frame(dat)234235236## -------------------------------------------------------237dat.mat <- rbind(outCovClassic[2:4], outCovRobMM[2:4], outCovRobRocke[2:4],238outCovRobMcd[2:4], outCovRobTSGS[2:4])239dat <- as.data.frame(dat.mat)240row.names(dat) <- c("GmvLOcovClassic", "GmvLOcovRobMM", "GmvLOcovRobRocke",241"GmvLOcovRobMcd", "GmvLOcovRobTSGS")242print.data.frame(dat)243244245## -------------------------------------------------------246# Plot function247robPlot <- function(GMV, MARKET, plot=1){248# Optimize Portfolio at Monthly Rebalancing and 5-Year Training249if(plot == 1){250momentEstFun = 'custom.covRob.Rocke'251name = "GmvLOCovRobRocke"252}else if(plot == 2){253momentEstFun = 'custom.covRob.Mcd'254name = "GmvLOCovMcd"255}else if(plot == 3){256momentEstFun = 'custom.covRob.TSGS'257name = "GmvLOTSGS"258}else{259print("plot should be 1, 2 or 3")260return()261}262263bt.gmv.rob <- optimize.portfolio.rebalancing(returns, pspec,264optimize_method = "CVXR",265rebalance_on = "weeks",266training_period = 100,267momentFUN = momentEstFun)268269# Extract time series of portfolio weights270wts.gmv.rob <- extractWeights(bt.gmv.rob)271# Compute cumulative returns of portfolio272GMV.rob <- Return.rebalancing(returns, wts.gmv.rob)273274# Combine GMV.LO and MARKET cumulative returns275ret.comb <- na.omit(merge(GMV.rob, GMV, MARKET, all=F))276names(ret.comb) <- c(name, "GmvLO", "MARKET")277278plot <- backtest.plot(ret.comb, colorSet = c("darkgreen", "black",279"red"), ltySet = c(1,2,3))280281return(list(ret = ret.comb, plot = plot))282}283284285286## -------------------------------------------------------287bt.gmv <- optimize.portfolio.rebalancing(returns, pspec,288optimize_method = "CVXR",289rebalance_on="weeks",290training_period = 100)291# Extract time series of portfolio weights292wts.gmv <- extractWeights(bt.gmv)293# Compute cumulative returns of portfolio294GMV <- Return.rebalancing(returns, wts.gmv)295296res.covRob <- robPlot(GMV=GMV, MARKET=MARKET, plot=1)297res.covRob$plot298299300## -------------------------------------------------------301table.Drawdowns(res.covRob$ret$GmvLOCovRobRocke, top=1)302303304## -------------------------------------------------------305table.Drawdowns(res.covRob$ret$GmvLO, top=1)306307308## -------------------------------------------------------309table.Drawdowns(res.covRob$ret$MARKET, top=1)310311312## -------------------------------------------------------313set.seed(1234)314res.covMcd = robPlot(GMV=GMV, MARKET=MARKET, plot=2)315res.covMcd$plot316317318## -------------------------------------------------------319# longest drawdown for robust based portfolio320table.Drawdowns(res.covMcd$ret$GmvLOCovMcd, top=1)321322323## -------------------------------------------------------324res.TSGS = robPlot(GMV=GMV, MARKET=MARKET, plot=3)325res.TSGS$plot326327328## -------------------------------------------------------329# longest drawdown for robust based portfolio330table.Drawdowns(res.TSGS$ret$GmvLOTSGS, top=1)331332333## ---- eval = FALSE--------------------------------------334## user.covRob.Rocke <- function(R){335## out <- list()336## robustCov <- RobStatTM::covRobRocke(X = R, maxit = 200, maxsteps = 10)337## out$sigma <- robustCov$cov338## out$mu <- robustCov$center339## return(out)340## }341342343## ---- eval = FALSE--------------------------------------344## opt <- optimize.portfolio(returns, pspec,345## optimize_method = "CVXR",346## momentFUN = "user.covRob.Rocke")347348349## ---- eval = FALSE--------------------------------------350## user.covRob.OGK <- function(R){351## robustCov <- robustbase::covOGK(x = R)352## return(list(mu = robustCov$center, sigma = robustCov$cov))353## }354355356## ---- eval = FALSE--------------------------------------357## opt <- optimize.portfolio(returns, pspec,358## optimize_method = "CVXR",359## momentFUN = "user.covMcd.OGK")360361## opt$moment_values362363364