library("Quandl")
library("zoo")
library("vars")
library("urca")
library("xts")
library("gdata")
library("KFAS")
library("dlmodeler")
library("stargazer")
library("forecast")
Quandl.api_key("sfE3eBMHtyGwpQTDwkWQ")

Import data

SP500 <-Quandl("YAHOO/INDEX_GSPC/CLOSE",collapse="monthly", type="zoo")

IBM <-Quandl("GOOG/NYSE_IBM/CLOSE",collapse="monthly", type="zoo")

TB3 <-Quandl("FRED/TB3MS",collapse="monthly", type="zoo")

a

rSP500 <- 100*diff(log(SP500), differences = 1)
rIBM <- 100*diff(log(IBM), differences = 1)
rTB3 <- TB3 / 12
par(mfrow=c(1,2), cex=0.8)

plot(log(SP500), xlab="", ylab="", main="log SP500")

plot(rSP500, xlab="", ylab="", main="100* diff. of log SP500")

plot(IBM, xlab="", ylab="", main="IBM")

plot(rIBM, xlab="", ylab="", main="100*diff. of log IBM ")

plot(TB3, xlab="", ylab="", main="3-Month Treasury Bill")

plot(rTB3, xlab="", ylab="", main="100*diff. of log 3-Month Treasury Bill")

Restrict all variables over the window from April 1981 to April 2017.

reg.rSP500 <- window(rSP500, start = 1981 + 3/12, end = 2017 + 3/12)
reg.rIBM <- window(rIBM, start = 1981 + 3/12, end = 2017 + 3/12)
reg.rTB3 <- window(rTB3, start = 1981 + 3/12, end = 2017 + 3/12)
par(mfrow=c(1,2), cex=0.8)

plot(reg.rSP500, xlab="", ylab="", main="100* diff. of log SP500")

plot(reg.rIBM, xlab="", ylab="", main="100*diff. of log IBM ")

plot(reg.rTB3, xlab="", ylab="", main="100*diff. of log 3-Month Treasury Bill")

b

excessIBM <- reg.rIBM - reg.rTB3
excessSP500 <- reg.rSP500 - reg.rTB3

simple.OLS <- lm(excessIBM  ~ excessSP500)

For the OLS estimated CAPM the alpha and beta have to be constant across time.

alpha.OLS <- simple.OLS$coefficients[1]
beta.OLS <- simple.OLS$coefficients[2]
summary(simple.OLS)
## 
## Call:
## lm(formula = excessIBM ~ excessSP500)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -31.2343  -3.1235  -0.1644   3.4677  24.5022 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -0.09957    0.29559  -0.337    0.736    
## excessSP500  0.92509    0.06804  13.597   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 6.134 on 431 degrees of freedom
## Multiple R-squared:  0.3002, Adjusted R-squared:  0.2986 
## F-statistic: 184.9 on 1 and 431 DF,  p-value: < 2.2e-16

So, in our example alpha is -0.09957 and beta is 0.92509.

plot(excessIBM, excessSP500, main="A simple OLS")
abline(lm(excessSP500~excessIBM))

c

excesssp500ts <- as.ts(excessSP500)
excessIBMts <- as.ts(excessIBM)

Number of observatons

T <- length(excesssp500ts)

Construct system matrices for state-space model

Zt <- array(rbind(rep(1,T), excesssp500ts), dim=c(1,2,T))
Ht <- matrix(NA)
Tt <- diag(2)
Rt <- diag(2)
Qt <- matrix(c(NA,0,0,NA), 2,2)

Use diffuse prior

a1 <- matrix(c(0, 1), 2, 1)
P1 <- matrix(0, 2, 2)
P1inf <- diag(2)

Define state-space CAPM model

y.SS <- SSModel(excessIBMts ~ -1 + SSMcustom(Z=Zt, T=Tt, R=Rt, Q=Qt, a1=a1, P1=P1, P1inf=P1inf), H=Ht)

Estimate variances of innovations using maximum likelihood

y.SS.ML <- fitSSM(y.SS, inits = c(0.001,0.001,0.001), method="BFGS")

Kalman filtering and smoothing, with parameters in Q and H set to maximum likelihood estimates

y.SS.KFS <- KFS(y.SS.ML$model)

Coefficients

alpha.KFS <- ts( cbind(y.SS.KFS$a[,1], y.SS.KFS$alphahat[,1]), start=c(1981,4), frequency=12)

beta.KFS <- ts( cbind(y.SS.KFS$a[,2], y.SS.KFS$alphahat[,2]), start=c(1981,4), frequency=12)

Plot

par(mfrow=c(1,2), cex=0.8)

plot.ts(alpha.KFS, plot.type="single", xlab="",ylab="Alpha", col=c("blue","red"), lwd=2)
legend("topright", c("filtered","smoothed"), col=c("blue","red"), lwd=2, cex=0.7, bty="n")

plot.ts(beta.KFS, plot.type="single", xlab="",ylab="Beta", col=c("blue","red"), lwd=2)
legend("topright", c("filtered","smoothed"), col=c("blue","red"), lwd=2, cex=0.7, bty="n")

Smoothed states alpha and beta

par(mfrow=c(1,2), cex=0.8)

plot.ts(alpha.KFS[,2], plot.type="single", xlab="",ylab="Alpha", col="red", lwd=2)
legend("topright", "smoothed", col="red", lwd=2, cex=0.7, bty="n")

plot.ts(beta.KFS[,2], plot.type="single", xlab="",ylab="Beta", col="red", lwd=2)
legend("topright", "smoothed", col="red", lwd=2, cex=0.7, bty="n")

d

A simple OLS alpha and beta

mean(simple.OLS$coefficients[1])
## [1] -0.09956639
mean(simple.OLS$coefficients[2])
## [1] 0.9250887

Kalman filtered alpha and beta

mean(y.SS.KFS$a[, 1])
## [1] -0.06942577
mean(y.SS.KFS$a[, 2])
## [1] 0.9198105

Kalman filtered smoothed alpha and beta

mean(y.SS.KFS$alphahat[, 1])
## [1] -0.07471126
mean(y.SS.KFS$alphahat[, 2])
## [1] 0.9228255
OLS KF KFS
alpha -0 .09956639 - 0.06942577 - 0.07471126
beta 0 .9250887 0.9198105 0.9228255

All beta look almost the same. The alpha of OLS is smaller than other two models’ alpha. Therefore, if alpha and beta are not constant, state space model looks better than a simple OLS which assumes that alpha and beta for CAPM are constant.