Path: blob/master/sandbox/script.workshop2012.R
1433 views
### For R/Finance workshop on Portfolio Analytics1# Chicago, 10 May 20122# Peter Carl and Brian Peterson34### Load the necessary packages5# Include optimizer and multi-core packages6library(PortfolioAnalytics)7require(quantmod)8require(DEoptim)9require(foreach)10require(doMC)11registerDoMC(3)12require(TTR)13# Available on r-forge14require(FactorAnalytics) # development version > build15require(vcd) # for color palates1617### Set up color palates18pal <- function(col, border = "light gray", ...){19n <- length(col)20plot(0, 0, type="n", xlim = c(0, 1), ylim = c(0, 1),21axes = FALSE, xlab = "", ylab = "", ...)22rect(0:(n-1)/n, 0, 1:n/n, 1, col = col, border = border)23}24# Use dark8equal for now?2526# Qualitative color scheme by Paul Tol27tol1qualitative=c("#4477AA")28tol2qualitative=c("#4477AA", "#CC6677")29tol3qualitative=c("#4477AA", "#DDCC77", "#CC6677")30tol4qualitative=c("#4477AA", "#117733", "#DDCC77", "#CC6677")31tol5qualitative=c("#332288", "#88CCEE", "#117733", "#DDCC77", "#CC6677")32tol6qualitative=c("#332288", "#88CCEE", "#117733", "#DDCC77", "#CC6677","#AA4499")33tol7qualitative=c("#332288", "#88CCEE", "#44AA99", "#117733", "#DDCC77", "#CC6677","#AA4499")34tol8qualitative=c("#332288", "#88CCEE", "#44AA99", "#117733", "#999933", "#DDCC77", "#CC6677","#AA4499")35tol9qualitative=c("#332288", "#88CCEE", "#44AA99", "#117733", "#999933", "#DDCC77", "#CC6677", "#882255", "#AA4499")36tol10qualitative=c("#332288", "#88CCEE", "#44AA99", "#117733", "#999933", "#DDCC77", "#661100", "#CC6677", "#882255", "#AA4499")3738####### Script WBS39# Parse data from EDHEC or HFRI40## Just load the data from packages41### See script.buildEDHEC.R and script.buildFactors.R42data(edhec)43# data(factors)444546## Which styles?47### Relative value48#### FIA49#### Converts50#### EMN51#### Event driven52### Directional53#### US Eq LS54#### Macro55#### CTA56#### Distressed5758# Drop some indexes and reorder59edhec.R = edhec[,c("Convertible Arbitrage", "Equity Market Neutral","Fixed Income Arbitrage", "Event Driven", "CTA Global", "Global Macro", "Long/Short Equity")]6061########################################################################62# Performance analysis of EDHEC hedge fund indexes63########################################################################64# --------------------------------------------------------------------65# EDHEC Indexes Returns through time66# --------------------------------------------------------------------67#postscript(file="EDHEC-Cumulative-Returns.pdf", height=6, width=10, paper="special", horizontal=FALSE, onefile=FALSE)68png(filename="EDHEC-Cumulative-Returns.png", units="in", height=5.5, width=9, res=96)69par(cex.lab=.8) # should set these parameters once at the top70op <- par(no.readonly = TRUE)71layout(matrix(c(1, 2)), height = c(2, 1.3), width = 1)72par(mar = c(1, 4, 1, 2)) #c(bottom, left, top, right)73chart.CumReturns(edhec.R, main = "", xaxis = FALSE, legend.loc = "topleft", ylab = "Cumulative Return", colorset= rainbow8equal, ylog=TRUE, wealth.index=TRUE, cex.legend=.7, cex.axis=.6, cex.lab=.7)74par(mar = c(4, 4, 0, 2))75chart.Drawdown(edhec.R, main = "", ylab = "Drawdown", colorset = rainbow8equal, cex.axis=.6, cex.lab=.7)76par(op)77dev.off()7879# --------------------------------------------------------------------80# EDHEC Indexes Risk81# --------------------------------------------------------------------82# postscript(file="EDHEC-BarVaR.eps", height=6, width=5, paper="special", horizontal=FALSE, onefile=FALSE)83png(filename="EDHEC-BarVaR.png", units="in", height=5.5, width=9, res=96)84# Generate charts of EDHEC index returns with ETL and VaR through time85par(mar=c(3, 4, 0, 2) + 0.1) #c(bottom, left, top, right)86# charts.BarVaR(edhec.R, p=(1-1/12), gap=36, main="", clean='boudt', show.cleaned=TRUE, show.greenredbars=TRUE, methods=c("ModifiedES", "ModifiedVaR"), show.endvalue=TRUE, colorset=rainbow8equal)8788charts.BarVaR(edhec.R, p=(1-1/12), gap=36, main="", show.greenredbars=TRUE,89methods=c("ModifiedES", "ModifiedVaR"), show.endvalue=TRUE,90colorset=rep("Black",7), ylim=c(-.1,.15))9192# charts.BarVaR(edhec.R, p=(1-1/12), gap=36, main="", show.greenredbars=TRUE, methods=c("ModifiedES", "ModifiedVaR"), show.endvalue=TRUE, colorset=rainbow8equal)93par(op)94dev.off()9596# --------------------------------------------------------------------97# EDHEC Indexes Rolling Performance98# --------------------------------------------------------------------99png(filename="EDHEC-RollPerf.png", units="in", height=5.5, width=9, res=96)100# Generate charts of EDHEC index returns with ETL and VaR through time101par(mar=c(5, 4, 0, 2) + 0.1) #c(bottom, left, top, right)102charts.RollingPerformance(edhec.R, width=36, main="", colorset=rainbow8equal, legend.loc="topleft")103par(op)104dev.off()105106# --------------------------------------------------------------------107# EDHEC Indexes Returns and Risk Scatter108# --------------------------------------------------------------------109png(filename="EDHEC-Scatter36m.png", units="in", height=5.5, width=4.5, res=96)110chart.RiskReturnScatter(last(edhec.R,36), main="EDHEC Index Trailing 36-Month Performance", colorset=rainbow8equal, ylim=c(0,.2), xlim=c(0,.12))111dev.off()112png(filename="EDHEC-ScatterSinceIncept.png", units="in", height=5.5, width=4.5, res=96)113chart.RiskReturnScatter(edhec.R, main="EDHEC Index Since Inception Performance", colorset=rainbow8equal, ylim=c(0,.2), xlim=c(0,.12))114dev.off()115116# --------------------------------------------------------------------117## EDHEC Indexes Table of Return and Risk Statistics118# --------------------------------------------------------------------119require(Hmisc)120incept.stats = t(table.RiskStats(R=edhec.R, p=p, Rf=.03/12))121write.csv(incept.stats, file="inception-stats.csv")122png(filename="EDHEC-InceptionStats.png", units="in", height=5.5, width=9, res=96)123textplot(format.df(incept.stats, na.blank=TRUE, numeric.dollar=FALSE, cdec=c(3,3,1,3,1,3,3,1,3,3,1,1,3,3,1,0), rmar = 0.8, cmar = 1, max.cex=.9, halign = "center", valign = "top", row.valign="center", wrap.rownames=20, wrap.colnames=10, mar = c(0,0,4,0)+0.1))124dev.off()125# --------------------------------------------------------------------126## EDHEC Indexes Distributions127# --------------------------------------------------------------------128129png(filename="EDHEC-Distributions.png", units="in", height=5.5, width=9, res=96)130op <- par(no.readonly = TRUE)131# c(bottom, left, top, right)132par(oma = c(5,0,2,1), mar=c(0,0,0,3))133layout(matrix(1:28, ncol=4, byrow=TRUE), widths=rep(c(.6,1,1,1),7))134# layout.show(n=21)135chart.mins=min(edhec.R)136chart.maxs=max(edhec.R)137row.names = sapply(colnames(RND.weights), function(x) paste(strwrap(x,10), collapse = "\n"), USE.NAMES=FALSE)138for(i in 1:7){139if(i==7){140plot.new()141text(x=1, y=0.5, adj=c(1,0.5), labels=row.names[i], cex=1.1)142chart.Histogram(edhec.R[,i], main="", xlim=c(chart.mins, chart.maxs), breaks=seq(-0.15,0.10, by=0.01), show.outliers=TRUE, methods=c("add.normal"))143abline(v=0, col="darkgray", lty=2)144chart.QQPlot(edhec.R[,i], main="", pch="*", envelope=0.95, col=c(1,"#005AFF"), ylim=c(chart.mins, chart.maxs))145abline(v=0, col="darkgray", lty=2)146chart.ECDF(edhec.R[,i], main="", xlim=c(chart.mins, chart.maxs), lwd=2)147abline(v=0, col="darkgray", lty=2)148}149else{150plot.new()151text(x=1, y=0.5, adj=c(1,0.5), labels=row.names[i], cex=1.1)152chart.Histogram(edhec.R[,i], main="", xlim=c(chart.mins, chart.maxs), breaks=seq(-0.15,0.10, by=0.01), xaxis=FALSE, yaxis=FALSE, show.outliers=TRUE, methods=c("add.normal"))153abline(v=0, col="darkgray", lty=2)154chart.QQPlot(edhec.R[,i], main="", xaxis=FALSE, yaxis=FALSE, pch="*", envelope=0.95, col=c(1,"#005AFF"), ylim=c(chart.mins, chart.maxs))155abline(v=0, col="darkgray", lty=2)156chart.ECDF(edhec.R[,i], main="", xlim=c(chart.mins, chart.maxs), xaxis=FALSE, yaxis=FALSE, lwd=2)157abline(v=0, col="darkgray", lty=2)158}159}160par(op)161dev.off()162163# --------------------------------------------------------------------164# Correlation165# --------------------------------------------------------------------166require("corrplot")167col3 <- colorRampPalette(c("darkgreen", "white", "darkred"))168M <- cor(edhec.R)169colnames(M) = rownames(M) = row.names170order.hc2 <- corrMatOrder(M, order="hclust", hclust.method="complete")171M.hc2 <- M[order.hc2,order.hc2]172png(filename="EDHEC-cor-inception.png", units="in", height=5.5, width=4.5, res=96)173corrplot(M.hc2, tl.col="black", tl.cex=0.8, method="square", col=col3(8), cl.offset=.75, cl.cex=.7, cl.align.text="l", cl.ratio=.25)174corrRect.hclust(M.hc2, k=3, method="complete", col="blue")175dev.off()176177M36 <- cor(last(edhec.R,36))178colnames(M36) = rownames(M36) = row.names179order36.hc2 <- corrMatOrder(M36, order="hclust", hclust.method="complete")180M36.hc2 <- M36[order36.hc2,order36.hc2]181png(filename="EDHEC-cor-tr36m.png", units="in", height=5.5, width=4.5, res=96)182corrplot(M36.hc2, tl.col="black", tl.cex=0.8, method="square", col=col3(8), cl.offset=.75, cl.cex=.7, cl.align.text="l", cl.ratio=.25)183corrRect.hclust(M36.hc2, k=3, method="complete", col="blue")184dev.off()185186# --------------------------------------------------------------------187## Autocorrelation188# --------------------------------------------------------------------189# @TODO: This is frosting, do it last190191runname='garch.sigma.and.mu'192193#########################################################################194# Optimization starts here195########################################################################196197# Set up objectives as buoys198## Equal contribution to199### Weight200### Variance201### Risk (mETL)202## Reward to Risk203### Mean-Variance204### Mean-mETL205## Minimum206### Variance207### Risk (mETL)208209# Add constraints210## Box constraints - 5% to 30%?211## Rebalancing period - quarterly? annual?212## Turnover constraints213214# Set up a starting portfolio215## Could use the equal weight216217# Forecast returns218## Start with pamean but don't use it in the presentation219### Create a small weighted annualized trailing-period mean wrapper function220pamean <- function(n=12, R, weights, geometric=TRUE)221{ as.vector(sum(Return.annualized(last(R,n), geometric=geometric)*weights)) }222223pameanLCL <- function(n=36, R, weights, scale=12)224{ as.vector(sum( scale*mean.LCL(last(R,n))*weights)) }225226paEMA <- function(n=10, R, weights, ...)227{# call Exponential Moving Average from TTR, return the last observation228sum((12*last(apply(R,2,FUN=TTR::EMA,n=n)))*weights)229}230231pasd <- function(R, weights){232as.numeric(StdDev(R=R, weights=weights)*sqrt(12)) # hardcoded for monthly data233# as.numeric(StdDev(R=R, weights=weights)*sqrt(4)) # hardcoded for quarterly data234}235236pasd.garch<- function(R,weights,garch.sigma,...) {237#sigmas is an input of predicted sigmas on a date,238# presumably from a GARCH model239as.numeric(sum((garch.sigma[last(index(R)),]*weights)*sqrt(12)))240}241242## Apply multi-factor model243## Show fit244## ADD MORE DETAIL HERE245246# Forecast risk247## Historical realized248## GARCH(1,1) for vol? if daily data available...249250# Run each of the objective portfolios as of a Date - Dec2010?251## Combined scatter with overlaid objectives, starting portfolio252### Mean-variance plot253254# Construct objectives for buoy portfolios255256# Select a rebalance period257rebalance_period = 'quarters' # uses endpoints identifiers from xts258clean = "boudt" #"none"259permutations = 4000260261# A set of box constraints used to initialize ALL the bouy portfolios262init.constr <- constraint(assets = colnames(edhec.R),263min = .05, # minimum position weight264max = .3, #1, # maximum position weight265min_sum=0.99, # minimum sum of weights must be equal to 1-ish266max_sum=1.01, # maximum sum must also be about 1267weight_seq = generatesequence(by=.005)268)269# Add measure 1, annualized return270init.constr <- add.objective(constraints=init.constr,271type="return", # the kind of objective this is272name="pamean",273#name="pameanLCL",274enabled=TRUE, # enable or disable the objective275multiplier=0, # calculate it but don't use it in the objective276arguments = list(n=60) # for monthly277# arguments = list(n=12) # for quarterly278)279# Add measure 2, annualized standard deviation280init.constr <- add.objective(init.constr,281type="risk", # the kind of objective this is282name="pasd", # to minimize from the sample283#name='pasd.garch', # to minimize from the predicted sigmas284enabled=TRUE, # enable or disable the objective285multiplier=0, # calculate it but don't use it in the objective286arguments=list() # from inception for pasd287#arguments=list(sigmas=garch.sigmas) # from inception for pasd.garch288)289# Add measure 3, CVaR with p=(1-1/12)290291# set confidence for VaR/ES292p=1-1/12 # for monthly293#p=.25 # for quarterly294295init.constr <- add.objective(init.constr,296type="risk", # the kind of objective this is297name="CVaR", # the function to minimize298enabled=FALSE, # enable or disable the objective299multiplier=0, # calculate it but don't use it in the objective300arguments=list(p=p),301clean=clean302)303304### Construct BUOY 1: Constrained Mean-StdDev Portfolio305MeanSD.constr <- init.constr306# Turn back on the return and sd objectives307MeanSD.constr$objectives[[1]]$multiplier = -1 # pamean308MeanSD.constr$objectives[[2]]$multiplier = 1 # pasd309310### Construct BUOY 2: Constrained Mean-mETL Portfolio311MeanmETL.constr <- init.constr312# Turn on the return and mETL objectives313MeanmETL.constr$objectives[[1]]$multiplier = -1 # pamean314MeanmETL.constr$objectives[[3]]$multiplier = 1 # mETL315MeanmETL.constr$objectives[[3]]$enabled = TRUE # mETL316317### Construct BUOY 3: Constrained Minimum Variance Portfolio318MinSD.constr <- init.constr319# Turn back on the sd objectives320MinSD.constr$objectives[[2]]$multiplier = 1 # StdDev321322### Construct BUOY 4: Constrained Minimum mETL Portfolio323MinmETL.constr <- init.constr324# Turn back on the mETL objective325MinmETL.constr$objectives[[3]]$multiplier = 1 # mETL326MinmETL.constr$objectives[[3]]$enabled = TRUE # mETL327328### Construct BUOY 5: Constrained Equal Variance Contribution Portfolio329EqSD.constr <- add.objective(init.constr, type="risk_budget", name="StdDev", enabled=TRUE, min_concentration=TRUE, arguments = list(p=(1-1/12)))330# Without a sub-objective, we get a somewhat undefined result, since there are (potentially) many Equal SD contribution portfolios.331EqSD.constr$objectives[[2]]$multiplier = 1 # min paSD332333# EqSD.constr$objectives[[1]]$multiplier = 0 # pamean334335### Construct BUOY 6: Constrained Equal mETL Contribution Portfolio336EqmETL.constr <- add.objective(init.constr, type="risk_budget", name="CVaR", enabled=TRUE, min_concentration=TRUE, arguments = list(p=(1-1/12), clean=clean))337EqmETL.constr$objectives[[3]]$multiplier = 1 # min mETL338EqmETL.constr$objectives[[3]]$enabled = TRUE # min mETL339# EqmETL.constr$objectives[[1]]$multiplier = -1 # max pamean340341### Construct BUOY 7: Equal Weight Portfolio342# There's only one, so construct weights for it. Rebalance the equal-weight portfolio at the same frequency as the others.343dates=index(edhec.R[endpoints(edhec.R, on=rebalance_period)])344weights = xts(matrix(rep(1/NCOL(edhec.R),length(dates)*NCOL(edhec.R)), ncol=NCOL(edhec.R)), order.by=dates)345colnames(weights)= colnames(edhec.R)346347348### Evaluate constraint objects349# Generate a single set of random portfolios to evaluate against all constraint set350print(paste('constructing random portfolios at',Sys.time()))351rp = random_portfolios(rpconstraints=init.constr, permutations=permutations)352print(paste('done constructing random portfolios at',Sys.time()))353354### Choose our 'R' variable355R=edhec.R # for monthlies356#R=edhec.R.quarterly #to use the quarterlies357#R=garch.mu # to use the monthly quarter-ahead predictions from the garch358359start_time<-Sys.time()360print(paste('Starting optimization at',Sys.time()))361### Evaluate BUOY 1: Constrained Mean-StdDev Portfolio362# MeanSD.RND<-optimize.portfolio(R=R,363# constraints=MeanSD.constr,364# optimize_method='random',365# search_size=1000, trace=TRUE, verbose=TRUE,366# rp=rp) # use the same random portfolios generated above367# plot(MeanSD.RND, risk.col="pasd.pasd", return.col="mean")368# Evaluate the objectives through time369### requires PortfolioAnalytics build >= 1864370MeanSD.RND.t = optimize.portfolio.rebalancing(R=R,371constraints=MeanSD.constr,372optimize_method='random',373search_size=permutations, trace=TRUE, verbose=TRUE,374rp=rp, # all the same as prior375rebalance_on=rebalance_period, # uses xts 'endpoints'376trailing_periods=NULL, # calculates from inception377training_period=36) # starts 3 years in to the data history378MeanSD.w = extractWeights.rebal(MeanSD.RND.t)379MeanSD=Return.rebalancing(edhec.R, MeanSD.w)380colnames(MeanSD) = "MeanSD"381save(MeanSD.RND.t,MeanSD.w,MeanSD,file=paste('MeanSD',Sys.Date(),runname,'rda',sep='.'))382383print(paste('Completed meanSD optimization at',Sys.time(),'moving on to meanmETL'))384385### Evaluate BUOY 2: Constrained Mean-mETL Portfolio386# MeanmETL.RND<-optimize.portfolio(R=R,387# constraints=MeanmETL.constr,388# optimize_method='random',389# search_size=1000, trace=TRUE, verbose=TRUE,390# rp=rp) # use the same random portfolios generated above391# plot(MeanmETL.RND, risk.col="pasd.pasd", return.col="mean")392# Evaluate the objectives with RP through time393MeanmETL.RND.t = optimize.portfolio.rebalancing(R=R,394constraints=MeanmETL.constr,395optimize_method='random',396search_size=permutations, trace=TRUE, verbose=TRUE,397rp=rp, # all the same as prior398rebalance_on=rebalance_period, # uses xts 'endpoints'399trailing_periods=NULL, # calculates from inception400training_period=36) # starts 3 years in to the data history401MeanmETL.w = extractWeights.rebal(MeanmETL.RND.t)402MeanmETL=Return.rebalancing(edhec.R, MeanmETL.w)403colnames(MeanmETL) = "MeanmETL"404save(MeanmETL.RND.t,MeanmETL.w,MeanmETL,file=paste('MeanmETL',Sys.Date(),runname,'rda',sep='.'))405print(paste('Completed meanmETL optimization at',Sys.time(),'moving on to MinSD'))406407### Evaluate BUOY 3: Constrained Minimum Variance Portfolio408# MinSD.RND<-optimize.portfolio(R=R,409# constraints=MinSD.constr,410# optimize_method='random',411# search_size=1000, trace=TRUE, verbose=TRUE,412# rp=rp) # use the same random portfolios generated above413# plot(MinSD.RND, risk.col="pasd.pasd", return.col="mean")414# Evaluate the objectives with RP through time415MinSD.RND.t = optimize.portfolio.rebalancing(R=R,416constraints=MinSD.constr,417optimize_method='random',418search_size=permutations, trace=TRUE, verbose=TRUE,419rp=rp, # all the same as prior420rebalance_on=rebalance_period, # uses xts 'endpoints'421trailing_periods=NULL, # calculates from inception422training_period=36) # starts 3 years in to the data history423MinSD.w = extractWeights.rebal(MinSD.RND.t)424MinSD=Return.rebalancing(edhec.R, MinSD.w)425colnames(MinSD) = "MinSD"426save(MinSD.RND.t,MinSD.w,MinSD,file=paste('MinSD',Sys.Date(),runname,'rda',sep='.'))427print(paste('Completed MinSD optimization at',Sys.time(),'moving on to MinmETL'))428429### Evaluate BUOY 4: Constrained Minimum mETL Portfolio430# MinmETL.RND<-optimize.portfolio(R=R,431# constraints=MinmETL.constr,432# optimize_method='random',433# search_size=1000, trace=TRUE, verbose=TRUE,434# rp=rp) # use the same random portfolios generated above435# plot(MinmETL.RND, risk.col="pasd.pasd", return.col="mean")436# Evaluate the objectives with RP through time437MinmETL.RND.t = optimize.portfolio.rebalancing(R=R,438constraints=MinmETL.constr,439optimize_method='random',440search_size=permutations, trace=TRUE, verbose=TRUE,441rp=rp, # all the same as prior442rebalance_on=rebalance_period, # uses xts 'endpoints'443trailing_periods=NULL, # calculates from inception444training_period=36) # starts 3 years in to the data history445MinmETL.w = extractWeights.rebal(MinmETL.RND.t)446MinmETL=Return.rebalancing(edhec.R, MinmETL.w)447colnames(MinmETL) = "MinmETL"448save(MinmETL.RND.t,MinmETL.w,MinmETL,file=paste('MinmETL',Sys.Date(),runname,'rda',sep='.'))449print(paste('Completed MinmETL optimization at',Sys.time(),'moving on to EqSD'))450451### Evaluate BUOY 5: Constrained Equal Variance Contribution Portfolio452# EqSD.RND<-optimize.portfolio(R=R,453# constraints=EqSD.constr,454# optimize_method='random',455# search_size=1000, trace=TRUE, verbose=TRUE,456# rp=rp) # use the same random portfolios generated above457# plot(EqSD.RND, risk.col="pasd.pasd", return.col="mean")458EqSD.RND.t = optimize.portfolio.rebalancing(R=R,459constraints=EqSD.constr,460optimize_method='random',461search_size=permutations, trace=TRUE, verbose=TRUE,462rp=rp, # all the same as prior463rebalance_on=rebalance_period, # uses xts 'endpoints'464trailing_periods=NULL, # calculates from inception465training_period=36) # starts 3 years in to the data history466EqSD.w = extractWeights.rebal(EqSD.RND.t)467EqSD=Return.rebalancing(edhec.R, EqSD.w)468colnames(EqSD) = "EqSD"469save(EqSD.RND.t,EqSD.w,EqSD,file=paste('EqSD',Sys.Date(),runname,'rda',sep='.'))470print(paste('Completed EqSD optimization at',Sys.time(),'moving on to EqmETL'))471472### Evaluate BUOY 6: Constrained Equal mETL Contribution Portfolio473# EqmETL.RND<-optimize.portfolio(R=R,474# constraints=EqmETL.constr,475# optimize_method='random',476# search_size=1000, trace=TRUE, verbose=TRUE,477# rp=rp) # use the same random portfolios generated above478EqmETL.RND.t = optimize.portfolio.rebalancing(R=R,479constraints=EqmETL.constr,480optimize_method='random',481search_size=permutations, trace=TRUE, verbose=TRUE,482rp=rp, # all the same as prior483rebalance_on=rebalance_period, # uses xts 'endpoints'484trailing_periods=NULL, # calculates from inception485training_period=36) # starts 3 years in to the data history486EqmETL.w = extractWeights.rebal(EqmETL.RND.t)487EqmETL=Return.rebalancing(edhec.R, EqmETL.w)488colnames(EqmETL) = "EqmETL"489save(EqmETL.RND.t,EqmETL.w,EqmETL,file=paste('EqmETL',Sys.Date(),runname,'rda',sep='.'))490print(paste('Completed EqmETL optimization at',Sys.time(),'moving on to EqWgt'))491492### Evaluate BUOY 7: Equal Weight Portfolio493# There's only one, so calculate it. Rebalance the equal-weight portfolio regularly, matching the periods above494EqWgt = Return.rebalancing(edhec.R,weights) # requires development build of PerfA >= 1863 or CRAN version 1.0.4 or higher495colnames(EqWgt)="EqWgt"496### Performance of Buy & Hold Random Portfolios497#BHportfs = EqWgt498#for(i in 2:NROW(rp)){ #@TODO: Use foreach in this loop instead499# weights_i = xts(matrix(rep(rp[i,],length(dates)), ncol=NCOL(rp)), order.by=dates)500# tmp = Return.rebalancing(edhec.R,weights_i)501# BHportfs = cbind(BHportfs,tmp)502#}503BHportfs <- foreach(i=1:NROW(rp),.combine=cbind, .inorder=TRUE) %dopar% {504weights_i = xts(matrix(rep(rp[i,],length(dates)), ncol=NCOL(rp)), order.by=dates)505tmp = Return.rebalancing(edhec.R,weights_i)506}507# BHportfs <- cbind(EqWgt,BHportfs)508save(rp,BHportfs,EqWgt,file=paste('BHportfs',Sys.Date(),runname,'rda',sep='.'))509510end_time<-Sys.time()511end_time-start_time512513# Assemble the ex ante result data514515results.obj = c("MeanSD.RND.t", "MeanmETL.RND.t", "MinSD.RND.t", "MinmETL.RND.t", "EqSD.RND.t", "EqmETL.RND.t")516results.names= c("Eq Wgt", "Mean SD", "Mean mETL", "Min SD", "Min mETL", "Eq SD", "Eq mETL")517518results = list(EqWgt=EqWgt,519BHportfs=BHportfs,520MeanSD.RND.t=MeanSD.RND.t,521MeanmETL.RND.t=MeanmETL.RND.t,522MinSD.RND.t=MinSD.RND.t,523MinmETL.RND.t=MinmETL.RND.t,524EqSD.RND.t=EqSD.RND.t,525EqmETL.RND.t=EqmETL.RND.t)526527528# evalDate="2010-12-31"529## Extract Weights530evalDate="2008-06-30"531RND.weights = MeanSD.RND.t[[evalDate]]$random_portfolio_objective_results[[1]]$weights #EqWgt532for(result in results.obj){533x=get(result)534RND.weights = rbind(RND.weights,x[[evalDate]]$weights)535}536rownames(RND.weights)=results.names # @TODO: add prettier labels537538#RND.weights = MeanSD.RND.t[["2010-12-31"]]$random_portfolio_objective_results[[1]]$weights #EqWgt539#for(result in results){540# RND.weights = rbind(RND.weights,result[["2010-12-31"]]$weights)541#}542#results.names= c("Eq Wgt", "Mean SD", "Mean mETL", "Min SD", "Min mETL", "Eq SD", "Eq mETL")543#rownames(RND.weights)=c(results.names) # @TODO: add prettier labels544#545### Extract Objective measures546#RND.objectives=rbind(MeanSD.RND.t[["2010-12-31"]]$random_portfolio_objective_results[[1]]$objective_measures[1:3]) #EqWgt547#for(result in results){548# RND.objectives = rbind(RND.objectives,rbind(result[["2010-12-31"]]$objective_measures[1:3]))549#}550#rownames(RND.objectives)=c("EqWgt",results) # @TODO: add prettier labels551save(results,file=paste(Sys.Date(),runname,'full-results','rda',sep='.'))552553## Extract Objective measures554RND.objectives=rbind(MeanSD.RND.t[[evalDate]]$random_portfolio_objective_results[[1]]$objective_measures[1:2]) #EqWgt555for(result in results.obj){556print(result)557x=get(result)558x.obj=rbind(x[[evalDate]]$objective_measures[1:2])559print(x.obj)560RND.objectives = rbind(RND.objectives,x.obj)561}562rownames(RND.objectives)=results.names # @TODO: add prettier labels563564565#****************************************************************************566# END main optimization section567#****************************************************************************568op <- par(no.readonly=TRUE)569570# --------------------------------------------------------------------571# NOT USED: Chart EqWgt Results against BH RP portfolios572# --------------------------------------------------------------------573postscript(file="EqWgtBHPerfSumm.eps", height=6, width=5, paper="special", horizontal=FALSE, onefile=FALSE)574charts.PerformanceSummary(BHportfs, main="Equal Weight and Buy & Hold Random Portfolios", methods=c("ModifiedVaR", "ModifiedES"), p=(1-1/12), gap=36, colorset=c("orange",rep("darkgray",NCOL(BHportfs))), lwd=3, legend.loc=NA)575# use clean='boudt', show.cleaned=TRUE, in final version?576dev.off()577# --------------------------------------------------------------------578579580### Plot comparison of objectives and weights581# > names(EqmETL.RND)582# [1] "random_portfolios" "random_portfolio_objective_results"583# [3] "weights" "objective_measures"584# [5] "call" "constraints"585# [7] "data_summary" "elapsed_time"586# [9] "end_t"587588# --------------------------------------------------------------------589# Plot Ex Ante scatter of RP and ONLY Equal Weight portfolio590# --------------------------------------------------------------------591xtract = extractStats(MeanSD.RND.t[[evalDate]])592593png(filename="RP-EqW-ExAnte-2008-06-30.png", units="in", height=5.5, width=9, res=96)594par(mar=c(5, 4, 1, 2) + 0.1) #c(bottom, left, top, right)595plot(xtract[,"pasd.pasd"],xtract[,"pamean.pamean"], xlab="Predicted StdDev", ylab="Predicted Mean", col="darkgray", axes=FALSE, main="", cex=.7)596grid(col = "darkgray")597abline(h = 0, col = "darkgray")598points(RND.objectives[1,2],RND.objectives[1,1], col=tol7qualitative, pch=16, cex=1.5)599axis(1, cex.axis = 0.8, col = "darkgray")600axis(2, cex.axis = 0.8, col = "darkgray")601box(col = "darkgray")602legend("bottomright",legend=results.names[1], col=tol7qualitative, pch=16, ncol=1, border.col="darkgray", y.intersp=1.2, cex=0.8, inset=.02)603par(op)604dev.off()605606# --------------------------------------------------------------------607# Plot Ex Ante scatter of RP and ALL BUOY portfolios608# --------------------------------------------------------------------609png(filename="Buoy-ExAnte-2008-06-30.png", units="in", height=5.5, width=9, res=96)610par(mar=c(5, 4, 1, 2) + 0.1) #c(bottom, left, top, right)611plot(xtract[,"pasd.pasd"],xtract[,"pamean.pamean"], xlab="Sample StdDev", ylab="Sample Mean", col="darkgray", axes=FALSE, main="", cex=.7)612grid(col = "darkgray")613abline(h = 0, col = "darkgray")614points(RND.objectives[,2],RND.objectives[,1], col=tol7qualitative, pch=16, cex=1.5)615axis(1, cex.axis = 0.8, col = "darkgray")616axis(2, cex.axis = 0.8, col = "darkgray")617box(col = "darkgray")618legend("bottomright", legend=results.names, col=tol7qualitative, pch=16, ncol=1, border.col="darkgray", y.intersp=1.2, inset=.02)619par(op)620dev.off()621622# --------------------------------------------------------------------623# Plot weights of Buoy portfolios as of 2008-06-30624# --------------------------------------------------------------------625png(filename="Weights-ExAnte-2008-06-30.png", units="in", height=5.5, width=9, res=96)626par(oma = c(4,8,2,1), mar=c(0,0,0,1)) # c(bottom, left, top, right)627layout(matrix(c(1:7), nr = 1, byrow = TRUE))628row.names = sapply(colnames(RND.weights), function(x) paste(strwrap(x,10), collapse = "\n"), USE.NAMES=FALSE)629for(i in 1:7){630if(i==1){631barplot(RND.weights[i,], col=rainbow8equal, horiz=TRUE, xlim=c(0,max(RND.weights)), axes=FALSE, names.arg=row.names, las=2, cex.names=1.1)632abline(v=0, col="darkgray")633abline(v=1/7, col="darkgray", lty=2)634axis(1, cex.axis = 1, col = "darkgray", las=1)635mtext(rownames(RND.weights)[i], side= 3, cex=0.7, adj=0)636}637else{638barplot(RND.weights[i,], col=rainbow8equal, horiz=TRUE, xlim=c(0,max(RND.weights)), axes=FALSE, names.arg="", ylab=rownames(RND.weights)[i])639abline(v=0, col="darkgray")640abline(v=1/7, col="darkgray", lty=2)641mtext(rownames(RND.weights)[i], side= 3, cex=0.7, adj=0)642}643}644par(op)645dev.off()646647# --------------------------------------------------------------------648# NOT USED: Plot Ex Ante scatter of buoy portfolios and weights649# --------------------------------------------------------------------650postscript(file="ExAnteScatterWeights20101231.eps", height=6, width=5, paper="special", horizontal=FALSE, onefile=FALSE)651op <- par(no.readonly=TRUE)652layout(matrix(c(1,2,3)),height=c(2,0.25,1.5),width=1)653par(mar=c(4,4,4,2)+.1, cex=1)654## Draw the Scatter chart of combined results655### Get the random portfolios from one of the result sets656# xtract = extractStats(MeanSD.RND.t[["2010-12-31"]]) # did this above657plot(xtract[,"pasd.pasd"],xtract[,"mean"], xlab="StdDev", ylab="Mean", col="darkgray", axes=FALSE, main="Objectives in Mean-Variance Space", cex=.7)658points(RND.objectives[,2],RND.objectives[,1], col=tol7qualitative, pch=16)659# This could easily be done in mean CVaR space as well660# plot(xtract[,"pasd.pasd"],xtract[,"mean"], xlab="CVaR", ylab="Mean", col="darkgray", axes=FALSE, main="Objectives in Mean-mETL Space")661# points(RND.objectives[,3],RND.objectives[,1], col=rainbow8equal, pch=16)662axis(1, cex.axis = 0.8, col = "darkgray")663axis(2, cex.axis = 0.8, col = "darkgray")664box(col = "darkgray")665666# Add legend to middle panel667par(mar=c(0,4,0,2)+.1, cex=0.7)668plot.new()669legend("bottom",legend=rownames(RND.weights), col=tol7qualitative, pch=16, lwd=2, ncol=4, border.col="darkgray", y.intersp=1.2)670671# Draw the Weights chart of the combined results672columnnames = colnames(RND.weights)673numassets = length(columnnames)674minmargin = 3675topmargin=1676# set the bottom border to accommodate labels677bottommargin = max(c(minmargin, (strwidth(columnnames,units="in"))/par("cin")[1])) * 1 #cex.lab678if(bottommargin > 10 ) {679bottommargin<-10680columnnames<-substr(columnnames,1,19)681# par(srt=45) #TODO figure out how to use text() and srt to rotate long labels682}683par(mar = c(bottommargin, 4, topmargin, 2) +.1, cex=1)684plot(RND.weights[1,], type="b", col=rainbow8equal[1], ylim=c(0,max(EqSD.RND.t$constraints$max)), ylab="Weights", xlab="",axes=FALSE)685points(EqSD.RND.t$constraints$min, type="b", col="darkgray", lty="solid", lwd=2, pch=24)686points(EqSD.RND.t$constraints$max, type="b", col="darkgray", lty="solid", lwd=2, pch=25)687for(i in 1:NROW(RND.weights)) points(RND.weights[i,], type="b", col=tol7qualitative[i], lwd=2)688axis(2, cex.axis = .8, col = "darkgray")689axis(1, labels=columnnames, at=1:numassets, las=3, cex.axis = .8, col = "darkgray")690box(col = "darkgray")691par(op)692dev.off()693# Use colors to group measures weight=orange, ETL=blue, sd=green694# Use pch to group types min=triangle, equal=circle, returnrisk=square695696# --------------------------------------------------------------------697# Plot Ex Post scatter of buoy portfolios698# --------------------------------------------------------------------699# Calculate ex post results700xpost.ret=Return.cumulative(BHportfs["2008-07::2008-09"])701xpost.sd=StdDev(BHportfs["2008-07::2008-09"])*sqrt(3)702xante.ret=xtract[,"pamean.pamean"]/3703xante.sd=xtract[,"pasd.pasd"]/sqrt(3)704705xpost.obj=NA706for(i in 1:NROW(RND.weights)){707x = Return.portfolio(R=edhec.R["2008-07::2008-09"], weights=RND.weights[i,])708y=c(Return.cumulative(x), StdDev(x)*sqrt(3))709if(is.na(xpost.obj))710xpost.obj=y711else712xpost.obj=rbind(xpost.obj,y)713}714rownames(xpost.obj)=rownames(RND.weights)715colnames(xpost.obj)=c("Realized Returns","Realized SD")716xmin=min(c(xpost.sd,xante.sd))717xmax=max(c(xpost.sd,xante.sd))718ymin=min(c(xpost.ret,xante.ret))719ymax=max(c(xpost.ret,xante.ret))720721png(filename="Scatter-ExPost-2008-06-30.png", units="in", height=5.5, width=9, res=96)722par(mar=c(5, 4, 1, 2) + 0.1) #c(bottom, left, top, right)723plot(xpost.sd,xpost.ret, xlab="StdDev", ylab="Mean", col="darkgray", axes=FALSE, main="", cex=.7, xlim=c(xmin,xmax), ylim=c(ymin,ymax))724grid(col = "darkgray")725points(xpost.obj[,2],xpost.obj[,1], col=tol7qualitative, pch=16, cex=1.5)726points(xante.sd,xante.ret, col="lightgray", cex=.7)727points(unlist(RND.objectives[,2])/sqrt(3),unlist(RND.objectives[,1])/3, col=tol7qualitative, pch=16, cex=1.5)728abline(h = 0, col = "darkgray")729axis(1, cex.axis = 0.8, col = "darkgray")730axis(2, cex.axis = 0.8, col = "darkgray")731box(col = "darkgray")732legend("topright",legend=rownames(RND.weights), col=tol7qualitative, pch=16, ncol=1, border.col="darkgray", y.intersp=1.2, inset=.02)733dev.off()734735# --------------------------------------------------------------------736# NOT USED: Show Ex Ante AND Ex Post results for 2010-12-31737# --------------------------------------------------------------------738# One more time, chart the ex ante results in mean-sd space739# postscript(file="ExAnteExPost20070630.eps", height=6, width=5, paper="special", horizontal=FALSE, onefile=FALSE)740op <- par(no.readonly=TRUE)741layout(matrix(c(1,2,3)),height=c(2,0.25,2),width=1)742par(mar=c(4,4,4,2)+.1, cex=1)743## Draw the Scatter chart of combined results744### Get the random portfolios from one of the result sets745xtract = extractStats(MeanSD.RND.t[["2010-12-31"]])746plot(xtract[,"pasd.pasd"],xtract[,"mean"], xlab="StdDev", ylab="Mean", col="darkgray", axes=FALSE, main="Ex Ante Results for 2010-12-31", cex=.5, xlim=c(xmin,xmax), ylim=c(ymin,ymax))747grid(col = "darkgray")748points(RND.objectives[,2],RND.objectives[,1], col=tol7qualitative, pch=16)749abline(h = 0, col = "darkgray")750# This could easily be done in mean CVaR space as well751# plot(xtract[,"pasd.pasd"],xtract[,"mean"], xlab="CVaR", ylab="Mean", col="darkgray", axes=FALSE, main="Objectives in Mean-mETL Space")752# points(RND.objectives[,3],RND.objectives[,1], col=rainbow8equal, pch=16)753axis(1, cex.axis = 0.8, col = "darkgray")754axis(2, cex.axis = 0.8, col = "darkgray")755box(col = "darkgray")756757# Add legend to middle panel758par(mar=c(0,4,0,2)+.1, cex=0.7)759plot.new()760legend("bottom",legend=rownames(RND.weights), col=tol7qualitative, pch=16, ncol=4, border.col="darkgray", y.intersp=1.2)761762# Plot the ex post results in mean-sd space763# Realized return versus predicted volatility?764par(mar=c(4,4,4,2)+.1, cex=1)765plot(x.sd2011,x.ret2011, xlab="StdDev", ylab="Mean", col="darkgray", axes=FALSE, main="Ex Post Results for 2010-12-31", cex=.5, xlim=c(xmin,xmax), ylim=c(ymin,ymax))766grid(col = "darkgray")767points(obj.real2011[,2],obj.real2011[,1], col=tol7qualitative, pch=16)768abline(h = 0, col = "darkgray")769axis(1, cex.axis = 0.8, col = "darkgray")770axis(2, cex.axis = 0.8, col = "darkgray")771box(col = "darkgray")772legend("bottomright",legend=rownames(RND.weights), col=tol7qualitative, pch=16, ncol=4, border.col="darkgray", y.intersp=1.2)773par(op)774dev.off()775776# --------------------------------------------------------------------777# Ex Post Results Through Time778# --------------------------------------------------------------------779# charts.PerformanceSummary(cbind(EqWgt,MeanSD, MeanmETL,MinSD,MinmETL,EqSD,EqmETL)["2009::2011"], colorset=tol7qualitative)780# charts.PerformanceSummary(cbind(EqWgt,MeanSD, MeanmETL,MinSD,MinmETL,EqSD,EqmETL)["2000::2011"], colorset=tol7qualitative)781buoys.R=cbind(EqWgt,MeanSD, MeanmETL,MinSD,MinmETL,EqSD,EqmETL)782png(filename="Buoy-Cumulative-Returns.png", units="in", height=5.5, width=9, res=96)783op <- par(no.readonly = TRUE)784layout(matrix(c(1, 2)), height = c(2, 1.3), width = 1)785par(mar = c(1, 4, 1, 2)) # c(bottom, left, top, right)786chart.CumReturns(buoys.R["2000::",], main = "", xaxis = FALSE, legend.loc = "topleft", ylab = "Cumulative Return", colorset= tol7qualitative, ylog=TRUE, wealth.index=TRUE, cex.legend=.7, cex.axis=.6, cex.lab=.7)787par(mar = c(4, 4, 0, 2))788chart.Drawdown(buoys.R["2000::",], main = "", ylab = "Drawdown", colorset = tol7qualitative, cex.axis=.6, cex.lab=.7)789par(op)790dev.off()791792# --------------------------------------------------------------------793# Predicted correlation chart794# --------------------------------------------------------------------795796predM <- dcccorl$"2008-06-30"797colnames(predM) = rownames(predM) = row.names798order.predM.hc2 <- corrMatOrder(predM, order="hclust", hclust.method="complete")799predM.hc2 <- predM[order.predM.hc2,order.predM.hc2]800png(filename="EDHEC-cor-pred-20080630.png", units="in", height=5.5, width=4.5, res=96)801corrplot(predM.hc2, tl.col="black", tl.cex=0.8, method="square", col=col3(8), cl.offset=.75, cl.cex=.7, cl.align.text="l", cl.ratio=.25)802corrRect.hclust(predM.hc2, k=3, method="complete", col="blue")803dev.off()804805# --------------------------------------------------------------------806# Show turnover of the RP portfolios relative to the EqWgt portfolio807# --------------------------------------------------------------------808turnover = function(w1,w2) {sum(abs(w1-w2))/length(w1)}809# Calculate the turnover matrix for the random portfolio set:810to.matrix<-matrix(nrow=NROW(rp),ncol=NROW(rp))811for(x in 1:NROW(rp)){812for(y in 1:NROW(rp)) {813to.matrix[x,y]<-turnover(rp[x,],rp[y,])814}815}816817png(filename="Turnover-2008-06-30.png", units="in", height=5.5, width=9, res=96)818# postscript(file="TurnoverOf20101231.eps", height=6, width=5, paper="special", horizontal=FALSE, onefile=FALSE)819op <- par(no.readonly=TRUE)820layout(matrix(c(1,2)),height=c(4,1.25),width=1)821par(mar=c(4,4,1,2)+.1, cex=1) # c(bottom, left, top, right)822seq.col = heat.colors(11)823## Draw the Scatter chart of combined results824### Get the random portfolios from one of the result sets825x=apply(rp, MARGIN=1,FUN=turnover,w2=rp[1,])826plot(xtract[,"pasd.pasd"],xtract[,"pamean.pamean"], xlab="Predicted StdDev", ylab="Predicted Mean", col=seq.col[ceiling(x*100)], axes=FALSE, main="", cex=.7, pch=16)827grid(col = "darkgray")828points(RND.objectives[1,2],RND.objectives[1,1], col="blue", pch=19, cex=1.5)829axis(1, cex.axis = 0.8, col = "darkgray")830axis(2, cex.axis = 0.8, col = "darkgray")831box(col = "darkgray")832833# Add legend to bottom panel834par(mar=c(5,5.5,1,3)+.1, cex=0.7)835## Create a histogramed legend for sequential colorsets836## this next bit of code is based on heatmap.2 in gplots package837x=ceiling(x*100)838scale01 <- function(x, low = min(x), high = max(x)) {839return((x - low)/(high - low))840}841breaks <- seq(min(x, na.rm = TRUE), max(x, na.rm = TRUE), length = length(seq.col)+1)842min.raw <- min(x, na.rm = TRUE)843max.raw <- max(x, na.rm = TRUE)844z <- seq(min.raw, max.raw, length = length(seq.col))845image(z = matrix(z, ncol = 1), col = seq.col, breaks = breaks, xaxt = "n", yaxt = "n")846par(usr = c(0, 1, 0, 1)) # needed to draw the histogram correctly847lv <- pretty(breaks)848xv <- scale01(as.numeric(lv), min.raw, max.raw)849axis(1, at = xv, labels=sprintf("%s%%", pretty(lv)))850h <- hist(x, plot = FALSE, breaks=breaks)851hx <- scale01(breaks, min(x), max(x))852hy <- c(h$counts, h$counts[length(h$counts)])853lines(hx, hy/max(hy)*.95, lwd = 2, type = "s", col = "blue")854axis(2, at = pretty(hy)/max(hy)*.95, pretty(hy))855title(ylab="Count")856title(xlab="Degree of Turnover from Equal Weight Portfolio")857par(op)858dev.off()859860# --------------------------------------------------------------------861# RSGarch results against EqWgt returns862# --------------------------------------------------------------------863864print(load("~/devel/R/RSGarch.rda"))865866png(filename="RSGarch.png", units="in", height=5.5, width=9, res=96)867layout(matrix(c(1,2)),height=c(2,1.5),width=1)868par(mar=c(1, 4, 4, 2) + 0.1, cex=0.8) #c(bottom, left, top, right)869chart.TimeSeries(zoo(f.MC.q,index(EqWgt)[-1]), main='Regime Switching Garch model for the Equal Weight Portfolio', ylab='Volatility Regime from 0(low) to 1(high)', xaxis=FALSE, colorset=rep("blue",2), lty=2, lwd=1)870par(mar=c(4,4,0,2)+.1, cex=0.8) #c(bottom, left, top, right)871chart.BarVaR(EqWgt, methods="StdDev", show.symmetric=TRUE, main="", ylab="EqWgt Return", width=12)872par(op)873dev.off()874875876# --------------------------------------------------------------------877# Other things we might do:878879###############880#ARMA-GARCH(1,1,1) for mu, sigma, and skew estimates 3 months out881require(rugarch)882883884ctrl = list(rho = 1, delta = 1e-6, outer.iter = 100, tol = 1e-6,outer.iter=700,inner.iter=2000)885spec = ugarchspec(variance.model = list(model = "gjrGARCH", garchOrder = c(1,1)),886mean.model = list(armaOrder = c(1,0), include.mean = TRUE),887distribution.model = "ghyp")888889dates<-seq.Date(from=as.Date('1975-03-01'), to=as.Date('1996-12-31'),by=1)890dates<-dates[endpoints(dates,on='months')]891taildates<-seq.Date(from=as.Date(as.Date(last(index(edhec.R)))+1), to=as.Date(as.Date(last(index(edhec.R)))+160),by=1)892taildates<-taildates[endpoints(taildates,on='months')]893tailxts<-xts(rep(0,length(taildates)),order.by=taildates)894895garch.out <- foreach(i=1:ncol(edhec.R),.inorder=TRUE) %dopar% {896897oridata <- edhec.R[,i]898start <- first(index(oridata))899end <- last(index(oridata))900901#bootsstrap902#we're going to do a simple sample with replacement here903# if doing this 'for real', a more sophisticated factor model monte carlo904# or AR tsboot() approach would likely be preferred905data<-rbind(xts(sample(oridata,length(dates),replace=TRUE),order.by=dates),oridata,tailxts)906colnames(data)<-colnames(oridata)907#add some NA's on the end, hack for now908909#run the garch910rm(bktest)911#NOTE forecast.length needs to be evenly divisible by n.ahead and refit.every912bktest = ugarchroll(spec, data = data, n.ahead = 3,913forecast.length = 186, refit.every = 3, refit.window = "moving",914solver = "solnp", fit.control = list(), solver.control = ctrl,915calculate.VaR = FALSE, VaR.alpha = c(0.01, 0.025, 0.05))916917# the standardized density parameters (rho, zeta)918f01density = bktest@roll$f01density[[3]]919skew = apply(f01density[,5:6],1, FUN = function(x) dskewness("nig", skew=x[1], shape=x[2]))920kurt = apply(f01density[,5:6],1, FUN = function(x) dkurtosis("nig", skew=x[1], shape=x[2])) #excess kurtosis921922# just sum the n.ahead predictions for now, could compound them, not sure923# what trouble that would cause924mu3 = rowSums(cbind(as.data.frame(bktest, n.ahead=1, refit = "all", which = "series"),925as.data.frame(bktest, n.ahead=2, refit = "all", which = "series"),926as.data.frame(bktest, n.ahead=3, refit = "all", which = "series")))927928sigma3 = rowMeans(cbind(as.data.frame(bktest, n.ahead=1, refit = "all", which = "sigma"),929as.data.frame(bktest, n.ahead=2, refit = "all", which = "sigma"),930as.data.frame(bktest, n.ahead=3, refit = "all", which = "sigma")))931932garchmom<-cbind(933as.data.frame(bktest, n.ahead=3, refit = "all", which = "series"),934as.data.frame(bktest, n.ahead=3, refit = "all", which = "sigma"),935skew, kurt,mu3,sigma3)936937garchmom.xts<-xts(garchmom,order.by=as.Date(rownames(garchmom)))938garchdata<-garchmom.xts[index(oridata)]939colnames(garchdata)[1]<-'mu'940colnames(garchdata)[6]<-'sigma3'941942out<-list(bktest=bktest,spec=spec,oridata=oridata,data=data,garchmom=garchmom.xts,garchdata=garchdata,start=start, end=end)943}944names(garch.out)<-colnames(edhec.R)945# OK, so now we've got a big unweildy GARCH list. let's create garchmu and garchsigma946garch.mu<-foreach(x=iter(garch.out),.combine=cbind)%do% { x$garchdata$mu }947names(garch.mu)<-colnames(edhec.R)948garch.sigma<-foreach(x=iter(garch.out),.combine=cbind)%do% { x$garchdata$sigma }949names(garch.sigma)<-colnames(edhec.R)950garch.skew<-foreach(x=iter(garch.out),.combine=cbind)%do% { x$garchdata$skew }951names(garch.skew)<-colnames(edhec.R)952garch.kurtosis <-foreach(x=iter(garch.out),.combine=cbind)%do% { x$garchdata$kurt }953names(garch.kurtosis)<-colnames(edhec.R)954garch.mu3 <- foreach(x=iter(garch.out),.combine=cbind)%do% { x$garchdata$mu3 }955names(garch.mu3)<-colnames(edhec.R)956garch.sigma3 <- foreach(x=iter(garch.out),.combine=cbind)%do% { x$garchdata$sigma3 }957names(garch.sigma3)<-colnames(edhec.R)958959960#diagnose skew and kurtosis961last(garch.skew)962skewness(tail(edhec.R,36))963last(garch.kurtosis)964kurtosis(tail(edhec.R,36))965966foreach(i=1:ncol(edhec.R)) %do% {967dev.new()968par(mfrow=c(3,1))969plot(garch.out[[i]]$bktest, n.ahead=1, which = 3,main=paste(names(garch.out)[i],'n-ahead 1'))970plot(garch.out[[i]]$bktest, n.ahead=2, which = 3,main=paste(names(garch.out)[i],'n-ahead 2'))971plot(garch.out[[i]]$bktest, n.ahead=3, which = 3,main=paste(names(garch.out)[i],'n-ahead 3'))972}973974save(garch.out,garch.mu,garch.mu3,garch.sigma,garch.sigma3,garch.skew,garch.kurtosis,file=paste(Sys.Date(),runname,'garch-results','rda',sep='.'))975976#####977# you can examine the bktest slots using commands like:978#report(bktest, type="VaR", n.ahead = 1, VaR.alpha = 0.01, conf.level = 0.95)979#report(convert.arb.bktest, type="fpm")980#plot(bktest)981982# fit=ugarchfit(garch.out$"Global Macro"$spec, garch.out$"Global Macro"$data)983# show(fit)984985986###########987# Multivariate Garch from rmgarch package988989# set up the data990bs.data <- foreach(i=1:ncol(edhec.R),.inorder=TRUE, .combine=cbind) %dopar% {991992oridata <- edhec.R[,i]993start <- first(index(oridata))994end <- last(index(oridata))995996#bootsstrap997#we're going to do a simple sample with replacement here998# if doing this 'for real', a more sophisticated factor model monte carlo999# or AR tsboot() approach would likely be preferred1000data<-rbind(xts(sample(oridata,length(dates),replace=TRUE),order.by=dates),oridata,tailxts)1001colnames(data)<-colnames(oridata)1002#add some NA's on the end, hack for now10031004data1005}10061007#try GO-GARCH1008ggspec = gogarchspec(1009mean.model = list(model = c("constant", "AR", "VAR")[3], lag = 2), #external.regressors = ex),1010variance.model = list(model = "gjrGARCH", garchOrder = c(1,1), submodel = NULL, variance.targeting = FALSE),1011distribution.model = c("mvnorm", "manig", "magh")[3], ica = c("fastica", "pearson", "jade", "radical")[1])1012ggfit = gogarchfit(ggspec, data = bs.data, out.sample = 0,1013parallel = FALSE, parallel.control = parallel.control)10141015gportmoments(ggfit,weights=rep(1/ncol(bs.data),ncol(bs.data)))10161017rcov(ggfit)10181019ggroll = gogarchroll(ggspec, data = bs.data, n.ahead = 1,1020forecast.length = 186, refit.every = 3, refit.window = "moving",1021solver = "solnp", fit.control = list(), solver.control = ctrl)10221023# try DCC-GARCH1024spec = spec # use the same spec we used for the univariate GARCH1025spec1 = dccspec(uspec = multispec( replicate(7, spec) ), dccOrder = c(1,1), asymmetric = TRUE, distribution = "mvnorm")1026dccfit1 = dccfit(spec1, data = bs.data, fit.control = list(eval.se=FALSE))102710281029#dccroll1 = dccroll(spec1, data = bs.data, n.ahead = 1,1030# forecast.length = 186, refit.every = 3, refit.window = "moving",1031# solver = "solnp", fit.control = list(), solver.control = ctrl)10321033###1034# garch moments1035# mu1036dccmu<-fitted(dccfit1)1037colnames(dccmu)<-colnames(edhec.R)1038rownames(dccmu)<-as.character(index(bs.data)[-1])1039dccmu<-xts(dccmu,order.by=as.Date(rownames((dccmu))))1040dccmu<-dccmu[index(edhec.R)]10411042# sigma1043dccsigma<-sigma(dccfit1)1044colnames(dccsigma)<-colnames(edhec.R)1045rownames(dccsigma)<-as.character(index(bs.data)[-1])1046dccsigma<-xts(dccsigma,order.by=as.Date(rownames((dccsigma))))1047dccsigma<-dccsigma[index(edhec.R)]10481049# conditional covariance1050dcccova<-rcov(dccfit1)1051dcccovl<-list()1052for(i in 1:dim(dcccova)[3]) { dcccovl[[i]]<- dcccova[,,i]; colnames(dcccovl[[i]])<-colnames(edhec.R); rownames(dcccovl[[i]])<-colnames(edhec.R)}1053names(dcccovl)<-index(bs.data)[-length(index(bs.data))]1054dcccovls<-dcccovl[1:444] #subset out only the real data1055dcccovls<-dcccovls[263:444] # dump the zero junk from the end1056all.equal(names(dcccovls),as.character(index(edhec.R)))10571058# conditional correlation1059dcccora<-rcor(dccfit1)1060dcccorl<-list()1061for(i in 1:dim(dcccora)[3]) { dcccorl[[i]]<- dcccora[,,i]; colnames(dcccorl[[i]])<-colnames(edhec.R); rownames(dcccorl[[i]])<-colnames(edhec.R)}1062names(dcccorl)<-index(bs.data)[-length(index(bs.data))]1063dcccorls<-dcccorl[1:444] #subset out only the real data1064dcccorls<-dcccorls[263:444] # dump the zero junk from the end1065dcccorl<-dcccorls1066rm(dcccorls,dcccora)1067save(spec,dccfit1,dccmu,dccsigma,dcccovl,dcccorl,file=paste('MVDCCGarch',Sys.Date(),'rda',sep='.'))10681069# Historical performance of each buoy portfolio1070## Same statistics as above1071## Compare relative performance10721073# Condition factor model forecasts?1074## On volatility1075## On correlation107610771078