Path: blob/master/sandbox/paper_analysis/insample/EfficientFrontier.R
1433 views
setwd("c:/Documents and Settings/Administrator/Desktop/risk budget programs")12# Equal risk portfolio3cAssets = 4;4p = priskbudget = 0.95;56mincriterion = "mES" ; percriskcontribcriterion = "mES";78# Load programs910source("R_Allocation/Risk_budget_functions.R");11library(zoo); library(fGarch); library("PerformanceAnalytics"); library("PortfolioAnalytics")1213clean = TRUE14# Load the data1516firstyear = 1976 ; firstquarter = 1; lastyear = 2010; lastquarter = 2;1718data = read.table( file= paste("data/","/data.txt",sep="") ,header=T)19date = as.Date(data[,1],format="%Y-%m-%d")202122monthlyR = indexes = zoo( data[,2:(1+cAssets)] , order.by = date )2324if(clean){25indexes = monthlyR = clean.boudt2(monthlyR,alpha=0.05)[[1]]26}2728mu = apply(indexes,2,'mean')29sigma = cov(indexes)30M3 = PerformanceAnalytics:::M3.MM(indexes)31M4 = PerformanceAnalytics:::M4.MM(indexes)3233# Summary stats individual assets3435head(indexes[,1:2],2); tail(indexes[,1:2],2)36apply(indexes[,1:2],2,'mean')*1237apply(indexes[,1:2],2,'sd')38ES(indexes[,1],method="modified")39ES(indexes[,2],method="modified")4041#################################################################################42# Make Exhibit 3 Risk budget paper: Efficient frontier plot43#################################################################################4445mESfun = function( series ){ return( operMES( series , alpha = 0.05 , r = 2 ) ) }46assetmu = apply( monthlyR , 2 , 'mean' )47assetCVaR = apply( monthlyR , 2 , 'mESfun' )48minmu = min(assetmu); maxmu = max(assetmu); print(minmu*12); print(maxmu*12);4950# Do the optimization: given a return target minimize the largest percentage CVaR in the portfolio51#---------------------------------------------------------------------------------------------------5253# unconstrained solution is Minimum CVaR Concentration portfolio (having the equal risk contribution property):54# sol = MinMaxCompCVaRconportfolio(R=monthlyR, Riskupper = Inf ,Returnlower= -Inf )55minmu = min( apply(monthlyR,2,'mean' ));56sol = PortfolioOptim( minriskcriterion = "mES" , MinMaxComp = T, percriskcontribcriterion = "mES" ,57Riskupper = Inf , mu = mu, sigma = sigma, M3=M3, M4=M4)5859W = as.vector( sol[[1]] ) ; vmu = as.vector( sol[[2]] )60vrisk = as.vector( sol[[3]] ) ; mPercrisk = as.vector( sol[[4]] )61vmaxpercrisk = max( sol[[4]] ) ; vmaxriskcontrib = max( sol[[5]] )6263for( mutarget in seq(minmu+0.00001,maxmu,0.00001) ){64sol = PortfolioOptim( minriskcriterion = "mES" , MinMaxComp = T, percriskcontribcriterion = "mES" ,65Riskupper = Inf ,Returnlower= mutarget,66mu = mu, sigma = sigma, M3=M3, M4=M4)67W = rbind( W, as.vector( sol[[1]] ) )68mPercrisk = rbind( mPercrisk , as.vector( sol[[4]] ) )69vmu = c( vmu , as.vector( sol[[2]] ))70vrisk = c( vrisk , as.vector( sol[[3]] ) )71vmaxpercrisk = c( vmaxpercrisk , max( sol[[4]] ) )72vmaxriskcontrib = c( vmaxriskcontrib , max( sol[[5]] ) )73}7475# For the highest return targets, a very high penalty parameter is (sometimes) needed7677for( mutarget in c(seq( max(vmu) , maxmu, 0.000001),maxmu) ){78print( c("mutarget equal to",mutarget) )79sol = PortfolioOptim( minriskcriterion = "mES" , MinMaxComp = T, percriskcontribcriterion = "mES" ,80Riskupper = Inf ,Returnlower= mutarget, penalty = 1e9,81mu = mu, sigma = sigma, M3=M3, M4=M4)82W = rbind( W, as.vector( sol[[1]] ) )83mPercrisk = rbind( mPercrisk , as.vector( sol[[4]] ) )84vmu = c( vmu , as.vector( sol[[2]] ))85vrisk = c( vrisk , as.vector( sol[[3]] ) )86vmaxpercrisk = c( vmaxpercrisk , max( sol[[4]] ) )87vmaxriskcontrib = c( vmaxriskcontrib , max( sol[[5]] ) )88}899091if(clean){92write.csv( W , file = "EffFrontierMinCVaRConc_weights_clean.csv" )93write.csv( mPercrisk , file = "EffFrontierMinCVaRConc_percrisk_clean.csv" )94EffFrontier_stats = cbind( vmu , vrisk , vmaxpercrisk , vmaxriskcontrib)95write.csv( EffFrontier_stats , file = "EffFrontierMinCVaRConc_stats_clean.csv" )96}else{97write.csv( W , file = "EffFrontierMinCVaRConc_weights.csv" )98write.csv( mPercrisk , file = "EffFrontierMinCVaRConc_percrisk.csv" )99EffFrontier_stats = cbind( vmu , vrisk , vmaxpercrisk , vmaxriskcontrib)100write.csv( EffFrontier_stats , file = "EffFrontierMinCVaRConc_stats.csv" )101}102103104105# Do the optimization: given a return target minimize the portfolio CVaR106#--------------------------------------------------------------------------107108# unconstrained solution is Minimum CVaR portfolio (having the property that percentage CVaR corresponds to porfolio weights):109minmu = min( apply(monthlyR,2,'mean' ));110sol = PortfolioOptim( minriskcriterion = "mES" , MinMaxComp = F, percriskcontribcriterion = "mES" ,111Riskupper = Inf , mu = mu, sigma = sigma, M3=M3, M4=M4)112113W = as.vector( sol[[1]] ) ; vmu = as.vector( sol[[2]] )114vrisk = as.vector( sol[[3]] ) ; mPercrisk = as.vector( sol[[4]] )115vmaxpercrisk = max( sol[[4]] ) ; vmaxriskcontrib = max( sol[[5]] )116117for( mutarget in seq(minmu+0.00001,maxmu,0.00001) ){118sol = PortfolioOptim( minriskcriterion = "mES" , MinMaxComp = F, percriskcontribcriterion = "mES" ,119Riskupper = Inf ,Returnlower= mutarget,120mu = mu, sigma = sigma, M3=M3, M4=M4)121W = rbind( W, as.vector( sol[[1]] ) )122mPercrisk = rbind( mPercrisk , as.vector( sol[[4]] ) )123vmu = c( vmu , as.vector( sol[[2]] ))124vrisk = c( vrisk , as.vector( sol[[3]] ) )125vmaxpercrisk = c( vmaxpercrisk , max( sol[[4]] ) )126vmaxriskcontrib = c( vmaxriskcontrib , max( sol[[5]] ) )127}128129# For the highest return targets, a very high penalty parameter is (sometimes) needed130131for( mutarget in c(seq( max(vmu) , maxmu, 0.000001),maxmu) ){132print( c("mutarget equal to",mutarget) )133sol = PortfolioOptim( minriskcriterion = "mES" , MinMaxComp = F, percriskcontribcriterion = "mES" ,134Riskupper = Inf ,Returnlower= mutarget, penalty = 1e9,135mu = mu, sigma = sigma, M3=M3, M4=M4)136W = rbind( W, as.vector( sol[[1]] ) )137mPercrisk = rbind( mPercrisk , as.vector( sol[[4]] ) )138vmu = c( vmu , as.vector( sol[[2]] ))139vrisk = c( vrisk , as.vector( sol[[3]] ) )140vmaxpercrisk = c( vmaxpercrisk , max( sol[[4]] ) )141vmaxriskcontrib = c( vmaxriskcontrib , max( sol[[5]] ) )142}143144if(clean){145write.csv( W , file = "EffFrontierMinCVaR_weights_clean.csv" )146write.csv( mPercrisk , file = "EffFrontierMinCVaR_percrisk_clean.csv" )147EffFrontier_stats = cbind( vmu , vrisk , vmaxpercrisk , vmaxriskcontrib)148write.csv( EffFrontier_stats , file = "EffFrontierMinCVaR_stats_clean.csv" )149}else{150write.csv( W , file = "EffFrontierMinCVaR_weights.csv" )151write.csv( mPercrisk , file = "EffFrontierMinCVaR_percrisk.csv" )152EffFrontier_stats = cbind( vmu , vrisk , vmaxpercrisk , vmaxriskcontrib)153write.csv( EffFrontier_stats , file = "EffFrontierMinCVaR_stats.csv" )154}155156157158159# Do the optimization: given a return target minimize the portfolio standard deviation (use quadprog)160#------------------------------------------------------------------------------------------------------161162library(quadprog)163N = 4 ; maxweight = 1; minweight = 0; sumweights = 1;164Amat = rbind( rep(1,N) , diag(x =1,nrow=N,ncol=N) , diag(x =-1,nrow=N,ncol=N) , as.numeric(mu) );165bvec = c( sumweights , rep(minweight,N), rep(-maxweight,N) )166dvec = matrix( rep(0,N) , ncol=1 )167168mutarget = -10000;169# min(-d^T b + 1/2 b^T D b) with the constraints A^T b >= b_0.170optw = solve.QP( Dmat = sigma , dvec = dvec , Amat = t(Amat) ,171bvec = matrix( c(bvec,mutarget) , ncol = 1) , meq =1 )$solution172sol = ES(weights=optw, portfolio_method="component", mu = mu, sigma = sigma, m3=M3, m4=M4,invert=FALSE)173W = optw ; vmu = sum(optw*mu)174vrisk = sol$MES ; mPercrisk = as.vector( sol$pct_contrib_MES )175vmaxpercrisk = max( sol$pct_contrib_MES ) ; vmaxriskcontrib = max( sol$contribution )176177# unconstrained solution is Minimum CVaR portfolio (having the property that percentage CVaR corresponds to porfolio weights):178minmu = min( apply(monthlyR,2,'mean' ));179180181for( mutarget in seq(minmu+0.00001,maxmu,0.00001) ){182optw = solve.QP( Dmat = sigma , dvec = dvec , Amat = t(Amat) ,183bvec = matrix( c(bvec,mutarget) , ncol = 1) , meq =1 )$solution184sol = ES(weights=optw, portfolio_method="component", mu = mu, sigma = sigma, m3=M3, m4=M4,invert=FALSE)185W = rbind( W, optw )186mPercrisk = rbind( mPercrisk , as.vector( sol$pct_contrib_MES ) )187vmu = c( vmu , sum(optw*mu) )188vrisk = c( vrisk , sol$MES )189vmaxpercrisk = c( vmaxpercrisk , max( sol$pct_contrib_MES ) )190vmaxriskcontrib = c( vmaxriskcontrib , max( sol$contribution ) )191}192193if(clean){194write.csv( W , file = "EffFrontierMinVar_weights_clean.csv" )195write.csv( mPercrisk , file = "EffFrontierMinVar_percrisk_clean.csv" )196EffFrontier_stats = cbind( vmu , vrisk , vmaxpercrisk , vmaxriskcontrib)197write.csv( EffFrontier_stats , file = "EffFrontierMinVar_stats_clean.csv" )198}else{199write.csv( W , file = "EffFrontierMinVar_weights.csv" )200write.csv( mPercrisk , file = "EffFrontierMinVar_percrisk.csv" )201EffFrontier_stats = cbind( vmu , vrisk , vmaxpercrisk , vmaxriskcontrib)202write.csv( EffFrontier_stats , file = "EffFrontierMinVar_stats.csv" )203}204205206207208# Plotting209#----------------------------------------------------------------------210211# Layout 3212source("R_interpretation/chart.StackedBar.R");213214mESfun = function( series ){ return( operMES( series , alpha = 0.05 , r = 2 ) ) }215assetmu = apply( monthlyR , 2 , 'mean' )216assetCVaR = apply( monthlyR , 2 , 'mESfun' )217minmu = min(assetmu); maxmu = max(assetmu); print(minmu*12); print(maxmu*12);218219220221####################################222# Min CVaR Concentration223####################################224labelnames = c( "US bond" , "S&P 500" , "EAFE" , "GSCI" )225226clean = TRUE227if(clean){228# Portfolio weights229W_MCC = read.csv( file = "EffFrontierMinCVaRConc_weights_clean.csv" )[,2:(1+cAssets)]230W_minCVaR = read.csv( file = "EffFrontierMinCVaR_weights_clean.csv" )[,2:(1+cAssets)]231W_minVar = read.csv( file = "EffFrontierMinVar_weights_clean.csv" )[,2:(1+cAssets)]232# Percentage CVaR contributions233PercCVaR_MCC = read.csv( file = "EffFrontierMinCVaRConc_percrisk_clean.csv" )[,2:(1+cAssets)]234PercCVaR_minCVaR = read.csv( file = "EffFrontierMinCVaR_percrisk_clean.csv" )[,2:(1+cAssets)]235PercCVaR_minVar = read.csv( file = "EffFrontierMinVar_percrisk_clean.csv" )[,2:(1+cAssets)]236# Summary stats237EffFrontier_stats_MCC = read.csv(file = "EffFrontierMinCVaRConc_stats_clean.csv")[,2:5]238EffFrontier_stats_minVar = read.csv(file = "EffFrontierMinVar_stats_clean.csv")[,2:5]239EffFrontier_stats_minCVaR = read.csv(file = "EffFrontierMinCVar_stats_clean.csv")[,2:5]240}else{241# Portfolio weights242W_MCC = read.csv(file = "EffFrontierMinCVaRConc_weights.csv")[,2:(1+cAssets)]243W_minCVaR = read.csv(file = "EffFrontierMinCVaR_weights.csv")[,2:(1+cAssets)]244W_minVar = read.csv(file = "EffFrontierMinVar_weights.csv")[,2:(1+cAssets)]245# Percentage CVaR contributions246mPercrisk_MCC = read.csv( file = "EffFrontierMinCVaRConc_percrisk.csv" )[,2:(1+cAssets)]247mPercrisk_minCVaR = read.csv( file = "EffFrontierMinCVaR_percrisk.csv" )[,2:(1+cAssets)]248mPercrisk_minVar = read.csv(file = "EffFrontierMinVar_percrisk.csv")[,2:(1+cAssets)]249# Summary stats250EffFrontier_stats_MCC = read.csv(file = "EffFrontierMinCVaRConc_stats.csv")[,2:5]251EffFrontier_stats_minVar = read.csv(file = "EffFrontierMinVar_stats.csv")[,2:5]252EffFrontier_stats_minCVaR = read.csv(file = "EffFrontierMinCVar_stats.csv")[,2:5]253}254255vmu_MCC = EffFrontier_stats_MCC[,1] ; vmu_minCVaR = EffFrontier_stats_minCVaR[,1] ;256vrisk_MCC = EffFrontier_stats_MCC[,2] ; vrisk_minCVaR = EffFrontier_stats_minCVaR[,2] ;257vmaxpercrisk_MCC = EffFrontier_stats_MCC[,3] ; vmaxpercrisk_minCVaR = EffFrontier_stats_minCVaR[,3] ;258vriskconc_MCC = EffFrontier_stats_MCC[,4] ; vriskconc_minCVaR = EffFrontier_stats_minCVaR[,4] ;259260vmu_minVar = EffFrontier_stats_minVar[,1] ;261vrisk_minVar = EffFrontier_stats_minVar[,2] ;262vriskconc_minVar = EffFrontier_stats_minVar[,4] ;263264# The MCC and Min CVaR were obtained with DEoptim. The solutions are not always optimal. Correct for this:265266order_MCC = sort(vmu_MCC,index.return=T)$ix ; order_minCVaR = sort(vmu_minCVaR,index.return=T)$ix267vmu_MCC = vmu_MCC[order_MCC] ; vmu_minCVaR = vmu_minCVaR[order_minCVaR]268vrisk_MCC = vrisk_MCC[order_MCC] ; vrisk_minCVaR = vrisk_minCVaR[order_minCVaR]269vmaxpercrisk_MCC = vmaxpercrisk_MCC[order_MCC] ; vmaxpercrisk_minCVaR = vmaxpercrisk_MCC[order_minCVaR]270vriskconc_MCC = vriskconc_MCC[order_MCC] ; vriskconc_minCVaR = vriskconc_minCVaR[order_minCVaR]271W_MCC = W_MCC[order_MCC,] ; W_minCVaR = W_minCVaR[order_minCVaR,]272PercCVaR_MCC = PercCVaR_MCC[order_MCC,] ; PercCVaR_minCVaR = PercCVaR_minCVaR[order_minCVaR,]273274# eliminate duplicates in mu275# Determines which elements of a vector or data frame are duplicates of elements with smaller subscripts,276# and returns a logical vector indicating which elements (rows) are duplicates.277a_MCC = duplicated(vmu_MCC) ; a_minCVaR = duplicated(vmu_minCVaR)278vmu_MCC = vmu_MCC[!a_MCC] ; vmu_minCVaR = vmu_minCVaR[!a_minCVaR]279vrisk_MCC = vrisk_MCC[!a_MCC] ; vrisk_minCVaR = vrisk_minCVaR[!a_minCVaR]280vmaxpercrisk_MCC = vmaxpercrisk_MCC[!a_MCC] ; vmaxpercrisk_minCVaR = vmaxpercrisk_minCVaR[!a_minCVaR]281vriskconc_MCC = vriskconc_MCC[!a_MCC] ; vriskconc_minCVaR = vriskconc_minCVaR[!a_minCVaR]282W_MCC = W_MCC[!a_MCC,] ; W_minCVaR = W_minCVaR[!a_minCVaR,]283PercCVaR_MCC = PercCVaR_MCC[!a_MCC,] ; PercCVaR_minCVaR = PercCVaR_minCVaR[!a_minCVaR,]284285# eliminate (efficiency: lower mu, higher CVaR alloc286287sel_MCC = sel_minCVaR = c(); nmu_MCC = length(vmu_MCC); nmu_minCVaR = length(vmu_minCVaR);288for( i in 1:(nmu_MCC-1) ){289if( any(vriskconc_MCC[(i+1):nmu_MCC]<=vriskconc_MCC[i]) ){ }else{sel_MCC = c(sel_MCC, i) }290}291for( i in 1:(nmu_minCVaR-1) ){292if( any(vrisk_minCVaR[(i+1):nmu_minCVaR]<=vrisk_minCVaR[i]) ){ }else{sel_minCVaR = c(sel_minCVaR, i) }293}294vmu_MCC = vmu_MCC[sel_MCC] ; vmu_minCVaR = vmu_minCVaR[sel_minCVaR]295vrisk_MCC = vrisk_MCC[sel_MCC] ; vrisk_minCVaR = vrisk_minCVaR[sel_minCVaR]296vmaxpercrisk_MCC = vmaxpercrisk_MCC[sel_MCC] ; vmaxpercrisk_minCVaR = vmaxpercrisk_minCVaR[sel_minCVaR]297vriskconc_MCC = vriskconc_MCC[sel_MCC] ; vriskconc_minCVaR = vriskconc_minCVaR[sel_minCVaR]298W_MCC = W_MCC[sel_MCC,] ; W_minCVaR = W_minCVaR[sel_minCVaR,]299PercCVaR_MCC = PercCVaR_MCC[sel_MCC,] ; PercCVaR_minCVaR = PercCVaR_minCVaR[sel_minCVaR,]300301wEW <- rep(1/4,4)302muEW = mean(assetmu*12)303outES = ES(weights=wEW, portfolio_method="component", mu = mu, sigma = sigma, m3=M3, m4=M4,invert=FALSE)304riskEW = outES$MES305riskconcEW = max(outES$contribution)306307postscript('frontier_fourassets.eps')308309layout( matrix( c(1,2,3,1,2,3), ncol = 2 ) , height= c(5,5,1), width=c(1,1) )310ylim = c( min(assetmu) , max(assetmu) )311par( mar = c(4.5,5,2,2), las=1 ,cex=0.9 , cex.axis=0.9, cex.main=0.95)312plot( vrisk_MCC , vmu_MCC*12 , type="l", lty = 1,313main = "" ,314ylab="Annualized mean return" , xlab="Monthly 95% Portfolio CVaR" ,315lwd=2, xlim = c(0.02,0.13) , ylim = (ylim*12+c(0,0.01)) , col="black" )316lines( vrisk_minCVaR , vmu_minCVaR*12, lty = 1, lwd=2, col="darkgray" )317lines( vrisk_minVar , vmu_minVar*12, lty = 3, lwd=2, col="black" )318319c = 1; text(y=assetmu[c]*12,x= assetCVaR[c] , label=labelnames[c] , cex = 0.7, offset = 0.2, pos = 1); points(y=assetmu[c]*12,x= assetCVaR[c] )320for( c in 2:cAssets ){321text(y=assetmu[c]*12,x= assetCVaR[c] , label=labelnames[c] , cex = 0.7, offset = 0.2, pos = 3)322points(y=assetmu[c]*12,x= assetCVaR[c] )323};324# Plot also EW portfolio325326text(y=muEW,x=riskEW, label="EW" , cex = 0.7, offset = 0.2, pos = 3)327points(y=muEW,x= riskEW )328329par( mar = c(4.5,5,2,2), las=1 ,cex=0.9 , cex.axis=0.9, cex.main=0.95)330plot( vriskconc_MCC/vrisk_MCC , vmu_MCC*12 , type="l", lty = 1,331main = "" ,332ylab="Annualized mean return" , xlab="Largest Perc. CVaR contribution" ,333lwd=2, xlim = c(0.2,1.1), ylim = c(ylim*12+c(0,0.01)) , col="black" )334lines( vriskconc_minCVaR/vrisk_minCVaR , vmu_minCVaR*12, lty = 1, lwd=2, col="darkgray" )335lines( vriskconc_minVar/vrisk_minVar , vmu_minVar*12, lty = 3, lwd=2, col="black" )336337text(y=muEW,x=riskconcEW/riskEW, label="EW" , cex = 0.7, offset = 0.2, pos = 1)338points(y=muEW,x= riskconcEW/riskEW )339for( c in 1:cAssets ){340text(y=assetmu[c]*12,x= 1 , label=labelnames[c] , cex = 0.7, offset = 0.2, pos = 4)341points(y=assetmu[c]*12,x= 1 )342};343344par( mar = c(0,1,1,0) )345plot.new()346legend("center",legend=c("Mean/StdDev" , "Mean/CVaR","Mean/CVaR concentration" ),347lty=c("dashed","solid","solid"), cex=0.8,ncol=3,lwd=2,col=c("black","darkgray","black"))348dev.off()349350351# cbind( vmu_minVar*12 , vriskconc_minVar/vrisk_minVar ) : 0.0816 is turning point352# cbind( vmu_minCVaR*12 , vriskconc_minCVaR/vrisk_minCVaR ) : 0.0816 is turning point353354355# Make the weight/CVaR allocation plots356#---------------------------------------357358Wsel_MCC = PercCVaRsel_MCC = Wsel_minCVaR = PercCVaRsel_minCVaR = Wsel_minVar = PercCVaRsel_minVar = c();359vmusel_MCC = vrisksel_MCC = vriskconcsel_MCC = vmusel_minCVaR = vrisksel_minCVaR = vriskconcsel_minCVaR = vmusel_minVar = vrisksel_minVar = vriskconcsel_minVar = c();360lm = minmu = min( c(vmu_MCC,vmu_minCVaR) ) ; maxmu = max( c(vmu_MCC,vmu_minCVaR) );361ylim = c( min(assetmu) - 0.0003 , max(assetmu) + 0.0003 )362xlim = c( 0 , max(assetCVaR) + 0.01 )363364binning = T # for the weight plots, binned data such that no visual misinterpretation is possible365step = quantile( diff(vmu_MCC) , 0.1 )366if( binning ){367for( rm in seq( minmu+step , maxmu , step ) ){368selection = c(vmu_MCC >= lm & vmu_MCC < rm) ;369if( any(selection) ){370selection = c(1:length(selection))[selection]371selone = sort(vriskconc_MCC[ selection ],index.return=T)$ix[1]372selone = selection[selone]373vmusel_MCC = c( vmusel_MCC , mean(vmu_MCC[selone ] ));374Wsel_MCC = rbind( Wsel_MCC , apply( W_MCC[selone,] ,2,'mean' ))375PercCVaRsel_MCC = rbind( PercCVaRsel_MCC , apply( PercCVaR_MCC[selone,] ,2,'mean' ))376vrisksel_MCC = c( vrisksel_MCC , mean(vrisk_MCC[ selone ]) );377vriskconcsel_MCC = c( vriskconcsel_MCC , mean(vriskconc_MCC[ selone ]) )378}else{379vmusel_MCC = c( vmusel_MCC , NA );380Wsel_MCC = rbind( Wsel_MCC , rep(NA,cAssets) )381PercCVaRsel_MCC = rbind( PercCVaRsel_MCC , rep(NA,cAssets) )382vrisksel_MCC = c( vrisksel_MCC , NA );383vriskconcsel_MCC = c( vriskconcsel_MCC , NA )384}385selection = c(vmu_minCVaR >= lm & vmu_minCVaR < rm) ;386if( any(selection) ){387selection = c(1:length(selection))[selection]388selone = sort(vrisk_minCVaR[ selection ],index.return=T)$ix[1]389selone = selection[selone]390vmusel_minCVaR = c( vmusel_minCVaR , mean(vmu_minCVaR[selone ] ));391Wsel_minCVaR = rbind( Wsel_minCVaR , apply( W_minCVaR[selone,] ,2,'mean' ))392PercCVaRsel_minCVaR = rbind( PercCVaRsel_minCVaR , apply( PercCVaR_minCVaR[selone,] ,2,'mean' ))393vrisksel_minCVaR = c( vrisksel_minCVaR , mean(vrisk_minCVaR[ selone ]) );394vriskconcsel_minCVaR = c( vriskconcsel_minCVaR , mean(vriskconc_minCVaR[ selone ]) )395}else{396vmusel_minCVaR = c( vmusel_minCVaR , NA );397Wsel_minCVaR = rbind( Wsel_minCVaR , rep(NA,cAssets) )398PercCVaRsel_minCVaR = rbind( PercCVaRsel_minCVaR , rep(NA,cAssets) )399vrisksel_minCVaR = c( vrisksel_minCVaR , NA );400vriskconcsel_minCVaR = c( vriskconcsel_minCVaR , NA )401}402selection = c(vmu_minVar >= lm & vmu_minVar < rm) ;403if( any(selection) ){404selection = c(1:length(selection))[selection]405selone = sort(vrisk_minVar[ selection ],index.return=T)$ix[1]406selone = selection[selone]407vmusel_minVar = c( vmusel_minVar , mean(vmu_minVar[selone ] ));408Wsel_minVar = rbind( Wsel_minVar , apply( W_minVar[selone,] ,2,'mean' ))409PercCVaRsel_minVar = rbind( PercCVaRsel_minVar , apply( PercCVaR_minVar[selone,] ,2,'mean' ))410vrisksel_minVar = c( vrisksel_minVar , mean(vrisk_minVar[ selone ]) );411vriskconcsel_minVar = c( vriskconcsel_minVar , mean(vriskconc_minVar[ selone ]) )412}else{413vmusel_minVar = c( vmusel_minVar , NA );414Wsel_minVar = rbind( Wsel_minVar , rep(NA,cAssets) )415PercCVaRsel_minVar = rbind( PercCVaRsel_minVar , rep(NA,cAssets) )416vrisksel_minVar = c( vrisksel_minVar , NA );417vriskconcsel_minVar = c( vriskconcsel_minVar , NA )418}419420lm = rm;421}422}else{423vmusel_MCC = vmu_MCC ; vmusel_minCVaR = vmu_minCVaR424Wsel_MCC = W_MCC ; Wsel_minCVaR = W_minCVaR ;425vrisksel_MCC = vrisk_MCC ; vrisksel_minCVaR = vrisk_minCVaR426vriskconcsel_MCC = vriskconc_MCC ; vriskconcsel_minCVar = vriskconc_minCVaR427PercCVaRsel_MCC = PercCVaR_MCC ; PercCVaRsel_minCVar = PercCVaR_minCVar ;428}429430library(zoo)431cAssets = ncol(monthlyR)432colorset = gray( seq(0,(cAssets-1),1)/cAssets ) ;433colnames( Wsel_MCC ) = colnames( Wsel_minCVaR ) = labelnames434rownames( Wsel_MCC ) = rownames( PercCVaRsel_MCC ) = round( interpNA(vmusel_MCC)*12,4);435rownames( Wsel_minCVaR ) = rownames( PercCVaRsel_minCVaR ) = round( interpNA(vmusel_minCVaR)*12,4) ;436437rownames( Wsel_minVar ) = rownames( PercCVaRsel_minVar ) = round( interpNA(vmusel_minVar)*12,4) ;438colnames( Wsel_minVar ) = labelnames439440441442w.names = c( "US bond" , "S&P 500", "EAFE" , "GSCI" )443namelabels = c("Mean/StdDev" , "Mean/CVaR","Mean/CVaR concentration" )444l = 2445mar1 =c(2,l,2,1.1)446mar2 =c(0,l,2,1)447mar3 = c(3,l+1,3,0.1)448mar4 = c(2,l+1,2,0.1)449450source("R_interpretation/chart.StackedBar.R");451452# Stacked weights plot:453postscript('stackedweightsriskcont_efficientfrontier_withNA.eps')454layout( matrix( c(1,2,3,4,5,6,7,4), ncol = 2 ) , height= c(1.5,1.5,1.5,0.7), width=1)455456par(mar=mar3 , cex.main=1)457chart.StackedBar2(Wsel_minVar ,col=colorset,space=0, main = namelabels[1], ylab="Weight allocation", las=1, l=3.9, r=0, cex.axis=1, cex.lab=1, cex.main=1, axisnames=T,legend.loc = NULL,ylim=c(0,1),border = F )458chart.StackedBar2(Wsel_minCVaR,col=colorset,space=0, main = namelabels[2], ylab="Weight allocation", las=1, l=3.9, r=0, cex.axis=1, cex.lab=1, cex.main=1, axisnames=T,legend.loc = NULL,ylim=c(0,1),border = F )459chart.StackedBar2(Wsel_MCC ,col=colorset,space=0, main = namelabels[3], ylab="Weight allocation", las=1, l=3.9, r=0, cex.axis=1, cex.lab=1, cex.main=1, axisnames=T, legend.loc = NULL,ylim=c(0,1),border = F )460461par(mar=mar1 , cex.main=1)462plot.new()463legend("center",legend=w.names,fill=colorset,ncol=4)464465par(mar=mar3 , cex.main=1)466chart.StackedBar2(PercCVaRsel_minVar,col=colorset,space=0, main = namelabels[1], ylab="CVaR allocation", las=1, l=3.9, r=0, cex.axis=1, cex.lab=1, cex.main=1, axisnames=T,legend.loc = NULL,ylim=c(0,1),border = F )467chart.StackedBar2(PercCVaRsel_minCVaR,col=colorset,space=0, main = namelabels[2], ylab="CVaR allocation", las=1, l=3.9, r=0, cex.axis=1, cex.lab=1, cex.main=1, axisnames=T,legend.loc = NULL,ylim=c(0,1),border = F )468chart.StackedBar2(PercCVaRsel_MCC,col=colorset,space=0, main = namelabels[3], ylab="CVaR allocation", las=1, l=3.9, r=0, cex.axis=1, cex.lab=1, cex.main=1, axisnames=T,legend.loc = NULL,ylim=c(0,1),border = F )469470dev.off()471472473postscript('stackedweightsriskcont_efficientfrontier.eps')474layout( matrix( c(1,2,3,4,5,6,7,4), ncol = 2 ) , height= c(1.5,1.5,1.5,0.7), width=1)475476par(mar=mar3 , cex.main=1)477chart.StackedBar2(interpNA(Wsel_minVar) ,col=colorset,space=0, main = namelabels[1], ylab="Weight allocation", las=1, l=3.9, r=0, cex.axis=1, cex.lab=1, cex.main=1, axisnames=T,legend.loc = NULL,ylim=c(0,1),border = F )478chart.StackedBar2(interpNA(Wsel_minCVaR),col=colorset,space=0, main = namelabels[2], ylab="Weight allocation", las=1, l=3.9, r=0, cex.axis=1, cex.lab=1, cex.main=1, axisnames=T,legend.loc = NULL,ylim=c(0,1),border = F )479chart.StackedBar2(interpNA(Wsel_MCC) ,col=colorset,space=0, main = namelabels[3], ylab="Weight allocation", las=1, l=3.9, r=0, cex.axis=1, cex.lab=1, cex.main=1, axisnames=T, legend.loc = NULL,ylim=c(0,1),border = F )480481par(mar=mar1 , cex.main=1)482plot.new()483legend("center",legend=w.names,fill=colorset,ncol=4)484485par(mar=mar3 , cex.main=1)486chart.StackedBar2(interpNA(PercCVaRsel_minVar),col=colorset,space=0, main = namelabels[1], ylab="CVaR allocation", las=1, l=3.9, r=0, cex.axis=1, cex.lab=1, cex.main=1, axisnames=T,legend.loc = NULL,ylim=c(0,1),border = F )487chart.StackedBar2(interpNA(PercCVaRsel_minCVaR),col=colorset,space=0, main = namelabels[2], ylab="CVaR allocation", las=1, l=3.9, r=0, cex.axis=1, cex.lab=1, cex.main=1, axisnames=T,legend.loc = NULL,ylim=c(0,1),border = F )488chart.StackedBar2(interpNA(PercCVaRsel_MCC),col=colorset,space=0, main = namelabels[3], ylab="CVaR allocation", las=1, l=3.9, r=0, cex.axis=1, cex.lab=1, cex.main=1, axisnames=T,legend.loc = NULL,ylim=c(0,1),border = F )489490dev.off()491492493494495#----------------------------------------------------------------------------------------------------496# DISCUSSION RESULTS497# On Raw Data: Discontinuity in the Mean-CVaR frontier of Mean CVaR concentration efficient portfolios:498# Two types of portfolios:499# Lower return targets: portfolio where the component risk of the bond dominates500# Higher return targets: portfolio where the component risk of the US equity dominates501# Shift when:502# > vmu[13:14]503# [1] 0.006796657 0.006806883504# > vriskconc[13:14]505# [1] 0.0082 0.0254506# > vrisk[13:14]507# [1] 0.01544720 0.06036618508509# On Cleaned Data: Three segments510511# > assetmu512# Bond SP500 EAFE SPGSCI513# 0.07545960 0.10249338 0.08677129 0.05413622514# > assetCVaR515# Bond SP500 EAFE SPGSCI516# 0.02456233 0.09974267 0.10868066 0.12775266517518519# Unconstrained: Equal Risk Contribution Portfolio:520# > W[1,]521# 0.6431897 0.1337981 0.1044994 0.1185127522#> mPercrisk[1,]523# 0.2516 0.2517 0.2504 0.2463524# > vmu[1]*12525# [1] 0.07773165526#> vrisk[1]527#[1] 0.03467514528#> vriskconc[1]529#[1] 0.0087530# Segment 1: increasing allocation to bonds and decreasing allocation to commodities531# Portfolio risk concentration increases, portfolio risk decreases532# > W[25:27,]533# 0.7052788 0.1584357 0.1321813 0.0041042550534# 0.7085301 0.1597522 0.1313759 0.0003417814535# 0.7025028 0.1628656 0.1344935 0.0001380022536#> vmu[26]*12537#[1] 0.0812571538#> vrisk[26]539#[1] 0.03352778540#> vriskconc[26]541#[1] 0.0112542# Segment 2: increasing allocation to both US equity and EAFE543# Portfolio risk concentration and risk increase together544# > W[138:140,]545# 0.0078323664 0.5106416 0.4814090 1.169711e-04546# 0.0005986683 0.5136429 0.4856355 1.228907e-04547# 0.0002258733 0.5201106 0.4796231 4.051641e-05548# > mPercrisk[138:140,]549# 0e+00 0.4999 0.5000 0550#> vmu[139]*12551#[1] 0.09483605552# > vrisk[139]553# [1] 0.09808784554# > vriskconc[139]555# [1] 0.049556# Segment 3: increasing alllocation to US equity and decreasing to EAFE557# Portfolio risk concentration and risk increase together558# > tail(W,1)559# 5.45402e-05 0.9998762 4.340072e-05 2.585630e-05560561562563564