Mikkel
Mikkel

Reputation: 23

Defining arguments for Kalman filter in R

I have been trying to figure out how to define the equations and arguments to run a Kalman filter (fkf package) with 4 variables. The model I am working with is an extended capital asset pricing model, and the variables are the dependent variable: Rpt (excess portfolio return) and three independent variables: Rmt (excelss monthly return), SMB (size factor), and ILLIQ (illiquidity factor). The data consists of monthly data for 22 stocks for 5 years running. The link gives an idea of how the data set looks, for ease of reference. Portfolio returns. Here is the dataset with the first three stocks: 3 first stocks

Loading the above dataset (in full), I have been able to run the Kalman filter with only one variable, Rpt above. However, how do I add more variables to the model? I am struggling with defining the correct arguments and equations. Can anyone help with this? Below is the code I have so far.

namibia1 <- read.delim(file.choose(), header=T)
attach(namibia1)
namibia1_ts <- ts(as.numeric(namibia1[,1]), frequency=12, start=c(2011,1), end=c(2015,12))
namibia1_ts <- ts(as.numeric(namibia1[,1]), frequency=12, start=c(2011,1), end=c(2015,12))
y <- namibia1_ts
dt <- ct <- matrix(0)
Tt <- matrix(1)
a0 <- y[1]
P0 <- matrix(1)
Zt <- matrix(c(1), ncol=60)
fit.fkf <- optim(c(HHt = var(y, na.rm=TRUE)*.5, 
                   GGt = var(y, na.rm=TRUE)*.5), 
                   fn  = function(par, ...){ -fkf(HHt = matrix(par[1]) }, 
                   GGt = matrix(par[2]), ...)$logLik, 
                   yt  = rbind(y), 
                   a0 = a0, P0 = P0, dt = dt, ct = ct, Zt = Zt, Tt = Tt, 
                  check.input = FALSE)

What I am struggle with more precisely is how to define the transition and measurement equation as matrixes, and if so, how? This may seem like a very easy thing to do, but so far it hasn't worked for me.

Upvotes: 2

Views: 736

Answers (1)

cuttlefish44
cuttlefish44

Reputation: 6786

When number of explanatory variable is one, the measurement and transition equation are: enter image description here In this image, [ 1 Xt ] is Zt, νt's error is GGt. diag(2) is Tt. Above image and I assume no intercept, so ct = matrix(0) and dt <- matrix(0, nrow=2, ncol=1). Estimated c(μ0, β0) is a0 and it's variance is P0.

# using data
namibia1 <- data.frame(Rpt = c(-7.9466, 7.0845, -6.4460, 5.0913, -0.1614, 10.4113, 11.5786, 
                              -6.6402, -6.9760, -0.7926, 7.2900, 16.1156, -12.1467),
                      Rmt = c(-2.9151, -2.6468, -3.5493, -2.9928, -1.8305, -1.8491, -3.2975,
                              -0.9582, -4.1794, -5.0553, 1.8858, -1.4464, -2.9151),
                      SMB = c(-2.5471, -4.3690, 4.2772, 12.1632, 5.1860, -5.3839, -1.4868, 
                              12.1463, 10.8383, 8.4175, -11.1109, -32.2698, -0.5691),
                      ILLIQ = c(-1.7851, 18.3652, -3.2890, 4.9808, -13.8678, -2.9312, 18.5644,
                                -2.6254, -23.1361, 3.2620, -8.3979, 37.6330, 14.7067),
                      Year = c(rep(2011, 12), 2012),
                      Month = c("January", "February", "March", "April", "May", "June", "Juli", "August",
                                "September", "October", "November", "December", "Janualy"))

# In your equations, m = 4, d = 1, n = nrow(namibia1)
y <- namibia1$Rpt
dt <- matrix(0, nrow=4, ncol=1)
ct <- matrix(0)
Tt <- diag(4)
Zt <- array(t(cbind(rep(1,nrow(namibia1)), namibia1[,2:4])), dim=c(1, 4, nrow(namibia1)))
a0 <- c(1, 1, 1, 1)
P0 <- matrix(100, nrow=4, ncol=4)

fit.fkf <- optim(c(1, 1, 1, 1, 1),
                 fn = function(par, ...) -fkf(HHt = diag(4) * par[1:4], GGt = matrix(par[5]), ...)$logLik,
                 yt = rbind(y), a0 = a0, P0 = P0, dt = dt, ct = ct,
                 Zt = Zt, Tt = Tt, check.input = T)
sqrt(fit.fkf$par) # estimated sd
fkf.obj <- fkf(a0, P0, dt, ct, Tt, Zt, HHt = diag(4) * fit.fkf$par[1:4],
               GGt = matrix(fit.fkf$par[5]), yt = rbind(y))
# the value of a0, P0 and optim's par mean nothing special.


Edited (Sorry, I forgot slope.)

estimatedLevel <- fkf.obj$att[1,] + namibia1[,2] * fkf.obj$att[2,] + namibia1[,3] * fkf.obj$att[3,] + namibia1[,4] * fkf.obj$att[4,]

plot(y)
lines(estimatedLevel, col = "blue")

enter image description here

Upvotes: 3

Related Questions