Thursday 9 July 2015

Expected Shortfall for a Canadian ETF Portfolio

In the past few weeks we have seen a lot of volatility in the financial markets. Greece is on the verge of a bailout, leaving the Euro currency, or something in between. China's stock markets, after an impressive run up over the past year have come crashing down. At times like these it is always a good idea to quantify portfolio risk. I take the position of  a Canadian investor who invests in a portfolio of broad based ETFs who wants to know their risk exposure as measured by expected shortfall (ES). ES is related to value at risk (VaR) but whereas VaR provides a measure of the minimum loss for a particular time period and coverage, ES calculates the average expected loss and is therefore closer to what an investor might expect to loose on average.
 
I use a portfolio of five broad asset classes: Canadian equities, Canadian REITs, US equities, Europe and Far East (EAFE) equities, and Canadian bonds. I use daily data sourced from Yahoo Finance. The ticker symbols and asset classes are as follows.

  "XIU.TO", # Canadian equities,
  "XRE.TO", # Canadian REITS,
  "XSP.TO", # US equities (SP500),
  "XIN.TO", # EAFE equities,
  "XBB.TO"  # Canada bonds,

Here is how each of the ETFs have performed.



Except for XBB, the other ETFs experienced large drops during the 2008 - 2009 financial crisis. The Canadian bond market, however, just kept on chugging along.

Here are what the QQ plots look like for the daily continuously compounded returns.


The plots indicate heavy tails for each of the asset returns. This would indicate that assuming normally distributed returns is probably not the best assumption to make when measuring risk.

Now on to calculating expected shortfall (ES). For comparison purposes, ES is calculated three ways (Historical, Gaussian, Modified). ES is calculated using a fixed width moving window of 1000 days. At the end of the day, the current ES is shifted forward by one day to provide a forecast for the next day's shortfall. Coverage is set at 99% which means that ES is calculated as the average loss over the first percentile of the return distribution. As we have seen from the QQ plots, the Gaussian approach is likely to lead to underestimating the expected shortfall because it does not account for heavy tails. In these situations, Modified often works well because it takes into account skewness and excess kurtosis.

The first portfolio I consider is a diversified portfolio with the following portfolio weights.

XIU 30%
XRE 10%
XSP 20%
XIN 10%
XBB 30%




Expected shortfall calculated from the Historical or Modified versions is very similar. In comparison, ES calculated from the Gaussian approach results in more violations.

Here are what the recent daily ES values look like.


           Historical Gaussian Modified
2015-06-30   -0.02057 -0.01398 -0.02016
2015-07-02   -0.02057 -0.01398 -0.02016
2015-07-03   -0.02057 -0.01398 -0.02016
2015-07-06   -0.02057 -0.01397 -0.02016
2015-07-07   -0.02057 -0.01395 -0.02018
2015-07-08   -0.02057 -0.01395 -0.02017



The ES modified value for July 8, 2015 indicates that on that day there was a 1% chance of loosing an average of 2.017% of the portfolio. In other words, the average daily loss on a $100,000 portfolio is $2017.

For comparison purposes, I also estimate expected shortfall for a traditional 60/40 portfolio (60% XIU and 40% XBB).


As in the previous case, the Historical and Modified ES values are similar while the Gaussian ES values lead to more rejections. The most recent value for the Modified ES indicates an average portfolio loss of 1.676% at 99% coverage. The average loss on a $100,000 portfolio is $1676. Notice that the ES values from the 60/40 portfolio are smaller in absolute value than those from the 5 asset portfolio. Interestingly, the Canadian 60/40 portfolio provides less risk than the diversified five asset portfolio.



           Historical Gaussian Modified
2015-06-30    -0.0164 -0.01278 -0.01682
2015-07-02    -0.0164 -0.01278 -0.01681
2015-07-03    -0.0164 -0.01278 -0.01680
2015-07-06    -0.0164 -0.01278 -0.01680
2015-07-07    -0.0164 -0.01277 -0.01676
2015-07-08    -0.0164 -0.01277 -0.01676



While the most recent volatility in the financial markets has been a concern, there has been no breaching of the Historical or Modified expected shortfall values in either the five asset portfolio or the 60/40 portfolio.


The R code is provided below. It takes about 12 minutes to complete one rolling ES calculation.

#########################################################
#  Economic forecasting and analysis
#  Perry Sadorsky
#  ES for a Canadian portfolio
#  July 2015
##########################################################

rm(list=ls())
library(fpp)
library(quantmod)




symbols = c(
  "XIU.TO", # Canadian equities,
  "XRE.TO", # Canadian REITS,
  "XSP.TO", # US equities (SP500),
  "XIN.TO", # EAFE equities,
  "XBB.TO"  # Canada bonds,
)



getSymbols(symbols, from="1970-01-01")
m = length(symbols)
Y = Ad(XIU.TO)
for (i in 2:m) Y = cbind(Y, Ad(get(symbols[i])))
head(Y)
tail(Y)



par(mfrow = c(3, 2))
for (i in 1:m) plot(Y[, i],  main = symbols[i])
par(mfrow = c(1, 1))



## returns
y.ret <-  (na.omit(1 * diff(log(Y)) ))


par(mfrow = c(3, 2))
for (i in 1:m) {qqnorm(y.ret[, i],  main = c("QQ Normal Plot",symbols[i]))
                qqline(y.ret[, i])}
par(mfrow = c(1, 1))


head(y.ret)
tail(y.ret)
weights <- c(0.3, 0.1, 0.2, 0.1, 0.3)
##########################################################


w.e = 1000
p.v = 0.99
port.ret = weights[1]*y.ret[,1] + weights[2]*y.ret[,2] + weights[3]*y.ret[,3]+ weights[4]*y.ret[,4] + weights[5]*y.ret[,5]
names(port.ret) = c("Portfolio")



## create custom function
bt_p_ES <- function(x, p, w) {
  modified.ES = as.numeric  ( ES(x, p=p, method="modified", portfolio_method = "component", weights = w)$MES)
  historical.ES = as.numeric  (ES(x, p=p, method="historical", portfolio_method="component", weights = w)$`-r_exceed/c_exceed`)
  gaussian.ES = as.numeric  ( ES(x, p=p, method="gaussian",  portfolio_method = "component", weights = w)$ES)
  ans = c(historical.ES, gaussian.ES, modified.ES)
  names(ans) = c("Historical", "Gaussian", "Modified")
  return(ans)
}


## rolling analysis
tic <- Sys.time()
ret.es_1 <- rollapply(y.ret, width = w.e, FUN = bt_p_ES, p=p.v, w=weights, by.column = FALSE,
                      align = "right"  )
toc <- Sys.time()
toc - tic

View(ret.es_1)
tail(ret.es_1)


## all three together with actual portfolio returns
ES.results = lag(ret.es_1, k=1)
chart.TimeSeries(merge(port.ret, -ES.results), legend.loc="topright")
tail(-ES.results)


##########################################################
##### comparison with 60/40 portfolio
##########################################################
port.ret.b = 0.6*y.ret[,1]  + 0.4*y.ret[,5]
names(port.ret.b) = c("Portfolio 60/40")
y.ret.b = y.ret[,c(1,5)]
tail(y.ret.b)



## rolling analysis
tic <- Sys.time()
ret.es_1.b <- rollapply(y.ret.b, width = w.e, FUN = bt_p_ES, p=p.v, w=c(.6,.4), by.column = FALSE,
                      align = "right"  )
toc <- Sys.time()
toc - tic

View(ret.es_1.b)
tail(ret.es_1.b)


## all three together with actual portfolio returns
ES.results.b = lag(ret.es_1.b, k=1)
chart.TimeSeries(merge(port.ret.b, -ES.results.b), legend.loc="topright")
tail(-ES.results.b)




Thursday 2 July 2015

Correlations Between Canadian ETFs

June was a difficult month for world equity markets. China was down double digits and most European markets fell between 3% and 5%. Canadian equity markets got caught up in the downdraft.

We know that equity correlation increased during the 2008-2009 financial crisis, but how does current equity correlation compare with the past. In order to investigate further, I took the position of a Canadian investor with a diversified portfolio of ETFs. For the analysis, I used daily data pulled from Yahoo Finance.

  "XIU.TO", # Canadian equities,
  "XRE.TO", # Canadian REITS,
  "XSP.TO", # US equities, SP500
  "XIN.TO", # EAFE equities,
  "XBB.TO"  # Canada bonds,


Here is how the ETFs have performed. Except for bonds, the other assets took a big hit during the financial crisis.




Here are what the correlations look like from 2002 until the end of June 2015. Bonds are negatively correlated with each of the equities with the largest negative correlation with the US. The largest positive correlation is between the US and other developed markets.



Here are what the correlations look like from 2002 until the end of December 2007. Each equity correlation is smaller (in absolute value) than the corresponding value over the full sample indicating greater diversification benefits over this first sub-sample. Notice that during this time period, bonds correlated positively with REITs.

 

Here are what the correlations look like during the financial crisis. Notice that correlations between equity ETFs were much higher during the financial crisis then during the previous period (2002 - 2007). For example, the correlation between XIU and XIN went from 58.6% to 85.9%!

 

Here are what the correlations look like over the post-crisis period (July 2009 until the end of June 2015). Correlations for the equity ETFs are smaller than they were during the financial crisis, but they have not yet returned to pre-crisis values. In some cases, bonds have actually gotten more negatively correlated with equities. The correlations between Canada and the US or Canada and developed international markets are very high (over 70%)

 

The overall takeaway is that in the post-crisis period, correlations between Canada, the US, and other developed markets remains high. This makes it difficult to diversify risk between these asset classes. The correlation between bonds and equities in the post-crisis period has, in some cases, gotten even more negative (possibly in anticipation of Central Bank interest rate increases).



Here is the R code.

#########################################################
#  Economic forecasting and analysis
#  Perry Sadorsky
#  Heat Map for a Canadian ETF portfolio
#  June 2015
##########################################################


rm(list=ls())
library(fpp)
library(quantmod)
library(gplots)



## define symbols
symbols = c(
  "XIU.TO", # Canadian equities,
  "XRE.TO", # Canadian REITS,
  "XSP.TO", # US equities, SP500
  "XIN.TO", # EAFE equities,
  "XBB.TO"  # Canada bonds,
)


## get data
getSymbols(symbols, from="1970-01-01")
m = length(symbols)
Y = Ad(XIU.TO)
for (i in 2:m) Y = cbind(Y, Ad(get(symbols[i])))
head(Y)
tail(Y)


## plots
par(mfrow = c(3, 2))
for (i in 1:m) plot(Y[, i],  main = symbols[i])
par(mfrow = c(1, 1))


## returns
ret <-  (na.omit(1.0 * diff(log(Y)) *
                    100))
colnames(ret) = c("XIU", "XRE", "XSP", "XIN", "XBB")
head(ret)
tail(ret)


## helper function from
## http://blog.revolutionanalytics.com/2014/08/quantitative-finance-applications-in-r-8.html
generate_heat_map <- function(correlationMatrix, title)
{
 
  heatmap.2(x = correlationMatrix,      # the correlation matrix input
            cellnote = correlationMatrix,    # places correlation value in each cell
            main = title,            # heat map title
            symm = TRUE,            # configure diagram as standard correlation matrix
            dendrogram="none",        # do not draw a row dendrogram
            Rowv = FALSE,            # keep ordering consistent
            trace="none",            # turns off trace lines inside the heat map
            density.info="none",        # turns off density plot inside color legend
            notecol="black")        # set font color of cell labels to black
 
}




# Convert each to percent format
corr1 <- cor(ret) * 100
corr2 <- cor(ret['2002-10/2007-12']) * 100
corr3 <- cor(ret['2008-10/2009-05']) * 100
corr4 <- cor(ret['2009-07/2015-06']) * 100

heatmap.2(corr1)

corr1 = round(corr1, digits = 1)
corr2 = round(corr2, digits = 1)
corr3 = round(corr3, digits = 1)
corr4 = round(corr4, digits = 1)

par(cex.main=.8)

generate_heat_map(corr1, "Correlations of Canadian ETF Returns, Oct 2002 - June 2015")
generate_heat_map(corr2, "Correlations of Canadian ETF Returns, Oct 2002 - Dec 2007")
generate_heat_map(corr3, "Correlations of Canadian ETF Returns, Oct 2008 - May 2009")
generate_heat_map(corr4, "Correlations of Canadian ETF Returns, July 2009 - June 2015")
par(cex.main=1.0)