Correlations among US Stocks: Is it really time to fire your adviser?
[This article was first published on Modern Toolmaking, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
Note: This post is NOT financial advice! This is just a fun way to explore some of the capabilities R has for importing and manipulating data.Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
The Financial Times says it’s time to “Fire your Adviser” because correlations among US stocks are at their highest levels since the financial crisis. Unfortunately, they only provide data going back 3 months and it’s in a boring table, rather than an awesome chart. After reading this article, I immediately pulled out quantmod and PerfomanceAnalytics in R. I used quantmod to download the daily data (from yahoo finance) for each index listed in the article, and then used PerformanceAnalytics to analyze and graph it. After and hour or so of fiddling around, I ended up with this chart:
Each line on this chart represents the rolling correlation between a major asset class and the S&P 500 (represented by SPY). I used a 90-day window to calculate the correlations, so each point on each line is looking backwards at a 90-day timeframe. As you can see, correlations have indeed gone up in the last few months, but there have been other periods in 2010 and 2011 with similarly high correlations.
This next chart looks at just the major US sectors, and takes the average of each of their correlations with SPY. This shows the overall correlation of the US stock market since 2007. Again, things are highly correlated right now, but we’ve been here before.
Here is the code I used to generate these charts. Feel free to comment on my implementation, and I’ll be happy to make any improvements and update the charts.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Load Data | |
rm(list = ls(all = TRUE)) | |
library(quantmod) | |
library(PerformanceAnalytics) | |
symbols <- c('XLE','XLV','XLI','XLU','XLP','IYZ','XLK','XLY','XLF','XLB','GLD','SLV','EFA','EEM','FXA','FXE','FXY','HYG','LQD') | |
getSymbols(symbols,from='2007-01-01') | |
getSymbols('SPY',from='2007-01-01') | |
SP500 <- Cl(SPY) | |
colnames(SP500)[1] <- 'SPY' | |
#Function to build a dataframe form a list of symbols | |
symbolFrame <- function(symbolList) { | |
Data <- data.frame(NULL) | |
for (S in symbolList) { | |
Data <- cbind(Data,Cl(get(S))) | |
} | |
colnames(Data) <- symbolList | |
return(Data) | |
} | |
#Make a color palette for the graphj | |
library(fBasics) | |
colorset <- qualiPalette(length(symbols), name="Set1") | |
#Chart Correlations | |
Data <- symbolFrame(symbols) | |
Data <- Data['2010-01-01::'] | |
chart.RollingCorrelation(Data, SP500, legend.loc="bottomleft",colorset=colorset, main = "Rolling 3-month Correlation",width=90) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Modified version of chart.RollingCorrelation that returns the data rather than plotting it | |
table.RollingCorrelation <- function (Ra, Rb, width = 12, na.pad = FALSE, ...) | |
{ | |
Ra = checkData(Ra) | |
Rb = checkData(Rb) | |
columns.a = ncol(Ra) | |
columns.b = ncol(Rb) | |
columnnames.a = colnames(Ra) | |
columnnames.b = colnames(Rb) | |
for (column.a in 1:columns.a) { | |
for (column.b in 1:columns.b) { | |
merged.assets = merge(Ra[, column.a, drop = FALSE], | |
Rb[, column.b, drop = FALSE]) | |
column.calc = rollapply(na.omit(merged.assets[, , | |
drop = FALSE]), width = width, FUN = function(x) cor(x[, | |
1, drop = FALSE], x[, 2, drop = FALSE]), by = 1, | |
by.column = FALSE, na.pad = na.pad, align = "right") | |
column.calc.tmp = xts(column.calc) | |
colnames(column.calc.tmp) = paste(columnnames.a[column.a], | |
columnnames.b[column.b], sep = " to ") | |
column.calc = xts(column.calc.tmp, order.by = time(column.calc)) | |
if (column.a == 1 & column.b == 1) | |
Result.calc = column.calc | |
else Result.calc = merge(Result.calc, column.calc) | |
} | |
} | |
return(Result.calc) | |
} | |
#Calculate mean correlation among US Sectors & plot | |
sectors <- c('XLE','XLV','XLI','XLU','XLP','IYZ','XLK','XLY','XLF','XLB') | |
corrs <- table.RollingCorrelation(symbolFrame(sectors), SP500, width=90) | |
meancorr <- apply(corrs,1,mean) | |
meancorr <- xts(meancorr,order.by=index(corrs)) | |
plot(meancorr, main = "Mean Rolling 3-month Correlation Among Major US Sectors") |
To leave a comment for the author, please follow the link and comment on their blog: Modern Toolmaking.
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.