# multi-factor time-varying CAPM using kalman filter

I am trying to implement a time-varying CAPM model using the kalman filter. I have already found numerous examples in R and python using the DLM and the pykalman packages but the problem is that they include a single independent variable while I am aiming for multiple factors. I gave it a shot modifying these examples so as to include another factor (or independent variable) but the betas of the factors don't necessarily sum up to one (which is a constraint when decomposing returns)

Is there any way to impose this constraint during the kalman filter calculation using DLM or pykalman? Or, in general, is there any way to impose this constraint in the kalman filter algorithm?

EDIT: - response to Mr F. Tusell:

Thanks a lot for sharing your paper and the corresponding code, just a couple of questions:

1. As far as I understand from the code, the application of the paper is still univariable, correct?...meaning, the 'market' variable in the code is one-dimensional.

2. If I would like to analyze one variate (let's say 'Telecom' industry) and use all the three factors from the Fama French would a similar approach work?

3. In case I am OK with negative betas, should I just set the 'lower' in the optimization process to '-100'?

4. Could you please give more regarding the use of the control variable during the optimization? Could you also share the reasoning behind initializing the 'ini' vector with the values '0.05' and '8'?

EDIT2: - response to Mr F. Tusell No2:

Thanks again for the help.

1. Regarding the rationale of having the betas of a univariate analysis with multiple factors:

Imagine a mutual fund for which we have the returns and we are trying to drill into these so as to get a better understanding. So let's say we know that they are investing in three indices and we want to decompose the return in these... in this case, the 'betas' (which are not really betas anymore) will tell us that they are +50% in index1, +80% in index2 and -30% in index3.

2. I tried to incorporate in your code the multifactor approach, but I am getting the following issues:

i. The 'betas' don't sum up to 1. I tried multiple approaches with upper/lower limits, initial values etc and in all of them the average of the sum is close to zero with a volatility of around 5-10.

ii. The betas have unrealistic values... around 1k - pending on the volatility I enter on the 'C0' array.

I am copying the code below (skipped the data reading part which is exactly the same as in your code) - any comment welcome

RWs <- function(par,x) {
mod <- dlm(FF = matrix(1, nrow = 2, ncol=3), V  = diag(nc+1), W  = diag(3), GG = diag(3), m0 = rep(0,ncol(x)), C0 = 10^7*diag(3),
JFF= rbind(matrix(1:ncol(market),nrow=1),matrix(1:ncol(market),nrow=1)), X = x)
diag(mod$W) = par[1:3] diag(mod$V) = c(par,0)
return(mod)
}

nc <- 1
N         <- nrow(series)
market    <- matrix(FFfact[,c(1,2,3)],N,3)
y         <- cbind(coredata(series)[,1:nc],1)
np <- 2*nc
ini <- c(rep(0.005,nc),rep(8,nc))

ObsMatrix <- rbind(diag(nc),1)
TrnMatrix <- diag(nc)
LocMatrix <- rbind(diag(nc),rep(0,nc))

par = c(0.01,0.01,0.01,1)

RWs.fit  <- dlmMLE(y, x=market, parm=par, build=RWs)

mod <- RWs(RWs.fit$par,x=market) betas <- zoo(dlmFilter(y,mod)$a,order.by=index(series))


A long time ago I wrote this paper with a co-worker (which was summarily rejected when we submitted for publication...). It answers precisely the question you ask.

Are you sure betas add up to one? I am no expert in Finance, but I had the impression that perhaps a weighted average of betas (using relative market capitalizacion as weights) might add up to 1, rather than the betas themselves. Even of that I am not sure.

Answer to EDIT: of the original question:

• 1 & 2: Yes, the approach carries forward to any number of factors. However, while I am able to rationalize a restriction such as the average (or weighted average) of the betas being 1 when the single factor is excess market return over the non-risk asset, I think in the three factor model there is no obvious restriction to enforce.

No, the "response" is multivariate. In order to impose a (soft) restriction on the betas, you have to estimate all of them at once. The dimension of the state vector (=number of sectors dealt with at once) in chunck 2, for instance, is nc=10.

• 3: In general, you can set 'lower' and 'upper' in the maximization routines to whatever values you think are reasonable bounds for the parameters. You must be aware, though, that the parameters in this model are the variances of the state and observation noises and cannot therefore be negative. The (time-varying) betas are computed in the state.

• 4: Rational for 0.05 and 8: simply we found (by trial and error) that these are reasonable initial values to achieve convergence of the MLE. In practice youj would try different sets of starting values

• thanks a lot for your quick response and sharing your paper. – sen_saven Jun 19 '17 at 8:23
• ...I think that RBSA expects the betas to sum up to 1, but, obviously, taking into account the market capitalization adds value. Would it be possible to share some technical (code) details regarding your implementation? – sen_saven Jun 19 '17 at 8:29
• No sure I understand your comment regarding market capitalization adds value. Yes, I can send you my code (in R) or try to help you otherwise. – F. Tusell Jun 19 '17 at 8:43
• yes, sorry, I pressed the 'Enter' and posted a comment by mistake - I mean that I agree that it makes sense to add the market capitalization as a weighting in the betas - one possible issue though would arise in case there are 'technical' factors included for which there is no market value. Sure if you can send me your R code it would be really helpful. – sen_saven Jun 19 '17 at 9:00
• ￼There you find it. It will last only a few days. dropbox.com/s/dzgrbqi9dkuxvcm/betas2.R?dl=0 – F. Tusell Jun 19 '17 at 9:11