[R-sig-finance] function to calc Fama-French 3 factor model
Spencer Graves
spencer.graves at pdf.com
Sun Sep 11 02:34:26 CEST 2005
(see comments inline)
Andrew West wrote:
> Thanks to Gabor and Dirk, I think I fixed some of the
> worst problems, but then continued on to add new
> output, perhaps intoroducing new problems.
>
> I added an extra plot showing fits vs. actual returns
> for the 2 models (CAPM & FamaFrench), and added a test
> of AIC scores for the 2 models, resulting in a
> statement of which is the better model for the stock.
>
> For a good example of why using Fama French for COE
> estimation might be a good idea, try:
> getffBeta("DUK")
>
> Notes of minor frustrations:
> 1.Couldn't figure out how to extract a single AIC for
> a WLE model,
In the output from help.search("AIC"), I saw "wle.aic". After your
line 'robustreg=wle.lm(combined[,1]~combined[,2])', I tried the following:
> wle.aic(robustreg)
Call:
wle.aic(formula = robustreg)
Weighted Akaike Information Criterion (WAIC):
(Intercept) combined[, 2] waic
[1,] 1 1 -478.0
[2,] 1 0 -477.0
[3,] 0 1 -476.5
Printed the first 3 best models
or pull an Adj. R2 from a WLE summary.
> (could get AIC in best subsets form, but that's not
> the same thing, so had to do AIC comparisons on LM
> models)
>
I'm not sure what you are asking here. I did the following:
> str(summary(robustreg))
List of 1
$ :List of 10
..$ call : language wle.lm(formula = combined[, 1] ~
<snip>
..$ adj.r.squared: num 0.0119
<snip>
This led me to the following:
> summary(robustreg)[[1]]$adj.r.squared
[1] 0.01192491
>
If this is not what you are asking, please provide a much smaller
"toy" example to try to clarify your question.
> 2. Couldn't figure out how to convince a "pairs" plot
> to share a window with another plot (tried par,
> split.screen).
>
A more specific toy example might produce a quick and effective
solution. Ditto for your other questions.
I know this doesn't answer all your questions, but I hope you some of
it helpful.
spencer graves
> 3. Was hoping that the strucchange package could
> automatically show me time-varying coefficients, but
> somehow the plot outputs of efp(type="ME" or "RE",
> functional=NULL) didn't correspond to what I thought
> it might, (rolling window coefficient estimates, which
> I've done before but which is another lengthy
> procedure).
>
> 4. It would be nice to offer a choice of more verbose
> output, e.g. with model summaries.
>
> 5. It would be nice to only download the Fama-French
> data once per session.
>
> I also haven't acquired/learned a substitute for
> MSWord for code editing, thus the function paste below
> may need reformatting to avoid inappropriate line
> breaks.
>
> Here's the code:
>
> getffBeta=function(tool) {
> require(MASS);
> require(tseries);
> require(wle)
> require(zoo)
> stock= (get.hist.quote(instrument = tool, quote
> =c("Ad"),compression="m",origin=as.Date(0)));
> spx=(get.hist.quote(instrument = "^gspc", quote
> =c("Ad"),compression="m",origin=as.Date(0)));
> today=Sys.Date();
> seqmo=length(seq(as.Date("1926-07-01"),today,by="month"))-2;
> url="http://mba.tuck.dartmouth.edu/pages/faculty/ken.french/ftp/F-F_Research_Data_Factors.zip";
> destfile=tempfile();
> dataff=download.file(url, destfile, mode='wb');
> unzip=unz(destfile,"F-F_Research_Data_Factors.txt");
> ff4 <- read.table(unzip, header=FALSE,
> sep="",na.strings="NA", dec=".", strip.white=TRUE,
> skip=4,nrows=seqmo)
> ffdata <- ff4
> attach(ffdata);
> ffdata=ffdata/100
> #find out starting year month for ffdata;
> ffdatats=ts(ffdata, start=c(1926,7), frequency=12);
> stock=ts(na.omit(coredata(stock)), start=
> as.numeric(as.yearmon(as.Date(start(stock)[1]))),
> frequency=12);
> spx=ts(na.remove(spx), start=
> as.numeric(as.yearmon(as.Date(start(spx)[1]))),
> frequency=12);
> combined= na.remove(ts.union(stock,spx));
> combreturn= na.remove(diff(log(combined)));
> combined=na.remove(ts.intersect(combreturn,ffdatats),
> names=list("stockret", "spxret",
> "dates","ffmktret","smb","hml","rf"));
> combined[,1]=combined[,1]-combined[,7]
> combined[,2]=combined[,2]-combined[,7]
>
> simplereg=lm(combined[,1]~combined[,2]);
> stockbeta=simplereg$coef[2];
> textout=paste("CAPM beta=", stockbeta);
> robustreg=wle.lm(combined[,1]~combined[,2]);
> robstockbeta=robustreg$coef[2];
> textout2=paste("robust stock beta=", robstockbeta);
>
> plot(as.numeric(combined[,1])~as.numeric(combined[,2]),xlab="S&P",
> ylab=tool)
> title(main=textout, sub=list(textout2, col="red"))
> abline(coef(simplereg));
> abline(coef(robustreg),col="red")
>
> print(textout);
> print(textout2);
> ffreg=wle.lm(combined[,1]~combined[,4]+combined[,5]+combined[,6]);
> ffbeta=ffreg$coef[2];
> ffsmb=ffreg$coef[3];
> ffhml=ffreg$coef[4] ;
> textout3=paste('robust ff beta=',ffbeta) ;
> textout4=paste('robust ff smb=',ffsmb) ;
> textout5=paste('robust ff hml=',ffhml) ;
> print(textout3) ;
> print(textout4) ;
> print(textout5) ;
> rf=5
> smb=1
> hml=2
> rm=5
> ffcoe=rf+ffbeta*rm+ffsmb*smb+ffhml*hml
> robcoe=rf+robstockbeta*rm
> regcoe=rf+stockbeta*rm
> textout6=paste('regular coe=',regcoe,' robustcoe=',
> robcoe)
> textout7=paste('Fama-French coe=',ffcoe)
> print(textout6)
> print(textout7) ;
> ffreg2=lm(combined[,1]~combined[,4]+combined[,5]+combined[,6]);
>
> a1=as.vector(combined[,1])
> b1=as.vector(ffreg2$fitted)
> c1=as.vector(simplereg$fitted)
> plot3= (data.frame(a1,b1,c1))
> win.graph()
> panel.cor <- function(x, y, digits=2, prefix="",
> cex.cor)
> {
> usr <- par("usr"); on.exit(par(usr))
> par(usr = c(0, 1, 0, 1))
> r <- abs(cor(x, y))
> txt <- format(c(r, 0.123456789),
> digits=digits)[1]
> txt <- paste(prefix, txt, sep="")
> if(missing(cex.cor)) cex <-
> 0.8/strwidth(txt)
> text(0.5, 0.5, txt, cex = cex * r)
> }
> pairs(plot3, upper.panel=panel.cor,labels=c("stock
> returns","FF fits","CAPM fits"))
>
>
> ffreg2=lm(combined[,1]~combined[,4]+combined[,5]+combined[,6]);
> if((AIC(simplereg))<(AIC(ffreg2))) "CAPM superior to
> FF" else "FF superior to CAPM";
> }
>
> _______________________________________________
> R-sig-finance at stat.math.ethz.ch mailing list
> https://stat.ethz.ch/mailman/listinfo/r-sig-finance
--
Spencer Graves, PhD
Senior Development Engineer
PDF Solutions, Inc.
333 West San Carlos Street Suite 700
San Jose, CA 95110, USA
spencer.graves at pdf.com
www.pdf.com <http://www.pdf.com>
Tel: 408-938-4420
Fax: 408-280-7915
More information about the R-sig-finance
mailing list