Monday, October 6, 2014

Popular Mutual Funds Decomposed With Ekholm (2014)

While we have a foundation and momentum from the last post “SelectionShare & TimingShare | Masterfully Written by Delightfully Responsive Author” , we can run the Ekholm calculations on some popular funds to see how they have evolved since the early 1980s.  Remember these are my opinions and not investment advice.  I chose these four funds for

  1. popularity in terms of Assets Under Management (AUM)
  2. style (active)
  3. tenure (old)
  4. evolution ( 2 evolved in a bad way and 2 have stayed consistent in a good way ).

This will continue what I envision to be a whole series of posts experimenting with the Ekholm (2014) decomposition into SelectionShare and TimingShare and determining how to use it in a mutual fund selection process.  Just as a reminder, below is the link to the very well-done paper by Anders Ekholm.

Ekholm, Anders G.

Components of Portfolio Variance: Systematic, Selection and Timing

August 8, 2014

http://ssrn.com/abstract=2463649

See if you can make any conclusions after reading the paper and looking at the chart below on the 2 year rolling Ekholm decomposition of FPA Crescent ®  Fund (FPACX), Sequoia ® Fund (SEQUX), Fidelity ® Contrafund ® (FCNTX), and The Growth Fund of America ®   (AGTHX).

image

As always, I really would like for you to reproduce and extend.  Please let me know if you do.  Below is the code.

# perform Ekholm (2012,2014) analysis on some popular mutual funds

# Ekholm, A.G., 2012
# Portfolio returns and manager activity:
# How to decompose tracking error into security selection and market timing
# Journal of Empirical Finance, Volume 19, pp 349-€“358

# Ekholm, Anders G., July 21, 2014
# Components of Portfolio Variance:
# R2, SelectionShare and TimingShare
# Available at SSRN: http://ssrn.com/abstract=2463649


library(Quandl) # use to get Fama/French factors
library(pipeR) # pipes are the future or R
library(rlist) # rlist - like underscore/lodash for R lists
library(dplyr) # super fast and really powerful
library(tidyr) # next gen wide/long formatter package
library(latticeExtra) # old but still awesome
library(directlabels) # fantastic and works with ggplot & lattice
library(quantmod) # also will load xts

# use Quandl Kenneth French Fama/French factors
# http://www.quandl.com/KFRENCH/FACTORS_D
f <- Quandl("KFRENCH/FACTORS_D",type = "xts") / 100

# grab our function from post
# http://timelyportfolio.blogspot.com/2014/10/selectionshare-timingshare-masterfully.html
devtools::source_gist("e5728c8c7fb45dbdb6e0")

tickers <- c( "FCNTX", "AGTHX", "SEQUX", "FPACX" )
ekFunds <- lapply(
tickers
,function(ticker) {
ticker %>>%
getSymbols( from = "1896-01-01", auto.assign = F ) %>>%
(fund ~
structure(
fund[,6] / stats::lag( fund[,6], 1 ) - 1
,dimnames = list(NULL,gsub(x = colnames(fund)[6], pattern = "[\\.]Adjusted", replacement = ""))
)
) %>>%
merge( f ) %>>% # Quandl("KFRENCH/FACTORS_D",type = "xts") / 100
na.omit %>>%
rollapply (
FUN= function(x){
x %>>%
jensen_ekholm %>>%
( data.frame( summary(.[["linmod"]])$"r.squared" , .$ekholm ) ) %>>%
xts(order.by=tail(index(x),1)) -> return_df
colnames(return_df)[1] <- "R_sq"
return(return_df)
}
, width = 500
#, by = 100
, by.column=F
, fill = NULL
) %>>%
na.fill(0)
}
)
names(ekFunds) <- tickers

ekFunds %>>%
list.map(
{
structure(
data.frame(
date = index(.)
, fund = names(ekFunds)[.i]
, .
)
) %>>%
gather(measure,value,-date,-fund)
}
) %>>%
(
do.call( rbind , . )
) -> ekT

ekT %>>%
# just plot at R^2, SelectionShare, and TimingShare
filter( measure %in% c("R_sq","SelectionShare","TimingShare") ) %>>%
(
xyplot(
value ~ date | measure
, groups = fund
, data = .
, type = "l"
# using direct.label so not necessary
, auto.key = list( space = "right" )
# title our plot
, main = paste(
"Comparison of Ekholm Decomposition for Various Mutual Funds"
,paste0("2 Year Rolling since ",format(.$date[1],format="%b %d, %Y"))
,sep="\n"
)
# layout one on top of the other
, layout = c(1,length(unique(.$measure)))
)
) %>>%
# I like labels on plot rather than legend
directlabels::direct.label( method = "last.qp" ) %>>%
# pretty it up with the latticeExtra Economist theme
asTheEconomist

Friday, October 3, 2014

SelectionShare & TimingShare | Masterfully Written by Delightfully Responsive Author

Anders Ekholm has written a wonderful paper

Ekholm, Anders G.

Components of Portfolio Variance: Systematic, Selection and Timing

August 8, 2014

http://ssrn.com/abstract=2463649

demonstrating how we might decompose a money manager’s performance with just a return stream.  Since his method relies simply on the return stream, he overcomes one of the biggest challenges of the Petajisto / Cremers’ related concepts of Active Share and Tracking Error which is the lack of data due to lagged infrequent reporting and high cost.  For other potential flaws in Active Share, see this post summarizing some very good PIMCO research.

Also, fortunately for me and maybe my faithful readers, the author has been very kind and responsive helping me translate his example Excel sheet into R.  Click on the screenshot below for the full details with replicable code and example with a real live mutual fund.

Of course, this is simply the beginning of what will be a wonderful journey exploring both the simplicity and complexity of Ekholm’s brilliance.

image

Thursday, September 11, 2014

R User Group in Birmingham, AL

If Birmingham, UK has one, then Birmingham, AL, USA should too.image

There is a big gaping hole in R user groups between Georgia and Texas that I think needs filling.  Way back in 2011, I weakly posted R User Group Birmingham Alabama, but this time I am more determined.  (note: I might even consider some Julia and Python, and sure you all know I love some Javascript)

image

 

Thanks to @matlabulous for his award winning Shiny analysis of R user groups that supplied the screenshots for this post.

Tuesday, September 9, 2014

Frazzini goes French

A kind reader commented “Don’t know if you have seen it, but Frazzini goes French now too” .  I have profusely thanked and praised Kenneth French for his incredible data library.  Now, it appears I’ll have to repeatedly do the same for Andrea Frazzini.

Here is a quick plot of Quality Minus Junk (QMJ) around the world.  The code snippet is below the chart.

image

#ssrn citation to the paper
#Asness, Clifford S. and Frazzini, Andrea and Pedersen, Lasse Heje
#Quality Minus Junk (October 9, 2013)
#Available at SSRN: http://ssrn.com/abstract=231243



require(gdata)
require(quantmod)
require(latticeExtra)

#read spreadsheet
qmjFactors <- read.xls(
"http://www.econ.yale.edu/~af227/data/QMJ%20-%20Factors%20-%20monthly.xlsx"
,pattern = "DATE"
,blank.lines.skip = T
,stringsAsFactors = F
)
#convert spreadsheet data to R xts
#remove % with gsub, make numeric, and divide by 100
qmjFactors.xts <- as.xts(
do.call(cbind,
lapply(
qmjFactors[,-1]
,function(x){
df<-data.frame(as.numeric(
gsub(
x=x
,pattern="%"
,replacement=""
)
)/100)
colnames(df) <- colnames(x)
return(df)
}
)
) #date is first column; will use in order.by
,order.by = as.Date(qmjFactors[,1]) #as.Date(paste0(qmjFactors[,1],"-01"),format="%Y%m%d")
)

#xyplot(qmjFactors.xts)

asTheEconomist(
xyplot(
cumprod(1+na.omit(qmjFactors.xts))
, scales = list( y = list( relation = "same" ) )
, main = "Quality Minus Junk (2013)\nAsness,Frazzini, Pedersen\nhttp://ssrn.com/abstract=231243"
)
)

Monday, August 11, 2014

Fama/French Factors in 1 line of code

In the past, getting Fama/French factors from the Kenneth French dataset involved a convoluted procedure to download the zip file, unzip the file, clean the data, and convert to xts.  Now with Quandl, we can do it simply in one line of code.  Note:  this data is available in multiple formats (JSON, CSV, XML) from the API and for multiple code languages.

# use Quandl Kenneth French Fama/French factors
# http://www.quandl.com/KFRENCH/FACTORS_D

library(Quandl)
library(quantmod)

f <- Quandl(
"KFRENCH/FACTORS_D"
)

f <- as.xts(f[,-1],order.by=f[,1])

plot.zoo( f, main = NA )
mtext(
text = "Fama/French Factors from Quandl"
, adj = 0
, outer = T
, line = -2
, cex = 2
)

image

Wednesday, July 30, 2014

Refresh Old rCharts+flickr post with httr and pipeR

The R world keeps moving, and I noticed this old post didn’t work anymore, so I have rewritten it to use Hadley Wickham's httr instead of Rflickr for two reasons:

  1. Rflickr is not working for me anymore
  2. httr is a very helpful package for navigating the "what was scary to me" world of http and oauth

In addition to the changes above, I will also demonstrate use of the pipeR package from Kun Ren who has been quite prolific lately. I feel pretty strongly I will be rewriting this post one more time in the near future (already done) employing his rlist package.

image

Tuesday, July 22, 2014

Chart from R + Color from Javascript

Another color experiment combining resources from R and Javascript.  I just wish I could do Mean Phylogenetic Distance in Javascript like rPlotter.  I enjoyed using d3.js zoom behavior to pan and zoom the image on canvas.  Also, filedrop.js made the drag and drop image easy.  There are lots of mini lessons in this code for someone who want to pick inside the code.

You might also notice the reference color from my last post Pick a Color Site built in R with Shiny tags %$%.

image

Thursday, July 17, 2014

Alternate Price Plots | ggplot2 + magrittr

Just some quick experiments with ggplot2 + magrittr to plot prices differently than the traditional ways. We wi€™ll get daily data on the S&P 500 from FRED using getSymbols and then push it through a magrittr pipe to various alternative plots.

A couple notes for those who might be interested in magrittr. If you want to -> or <- but do not want the pipe fun to end, then you can use assign like this.

mydata
%T>% assign( x="sp_df", value = ., envir = .GlobalEnv ) %>%

Also for those who want to use the special + inside a pipe or just want your + on a different line for tidy code and easy commenting, then you can do like this.

ggplot( ) %>%
+ geom_point()

Let me know if I have it all wrong, and now some plots as promised.

require(ggplot2)
require(dplyr)
require(magrittr)
require(quantmod)

getSymbols("SP500", src="FRED", from = "1900-01-01", auto.assign=F) %>%
na.omit %>%
data.frame(
date = index(.)
) %T>% assign( x="sp_df", value = ., envir = .GlobalEnv ) %>%
mutate( year = format(date,"%Y") ) %>%
ggplot( aes( x=SP500, group = year ) ) %>%
+ geom_density() %>%
+ facet_wrap(~year,nrow=1) %>%
+ coord_flip() %>%
+ theme_bw() %>%
+ theme(
axis.line=element_blank()
,axis.text.x=element_blank()
,axis.title.x=element_blank()
)

plot of chunk unnamed-chunk-3

sp_df %>%
ggplot( aes( x = format(date,"%Y"), y = SP500 ) ) %T>%
( function(x){ print( x + geom_line() ) } ) %T>%
( function(x){ print( x + geom_point() ) } ) %T>%
( function(x){ print( x + geom_hex( bins = 20 ) ) } ) %>%
+ geom_violin()

plot of chunk unnamed-chunk-3plot of chunk unnamed-chunk-3plot of chunk unnamed-chunk-3plot of chunk unnamed-chunk-3


If you are interested in seeing the source Rmd, then it is here. One more note is this is copied/pasted with only minor changes from Rstudio knitted Rmd.