Saturday, October 12, 2019

returns - kalman filter for a multifactor model in R


I am trying to set up a time varying factor model for the purpose of return decomposition via kalman filter.


Following this example and slightly modifying it so as to accommodate for more than one input parameters (i.e S&P 500, Equity L/S index etc) I am getting the betas for the two benchmarks but, as expected, they don't necessarily sum up to 1.



Is there any way to add a constraint during the MLE that the output parameters have to sum up to one?


EDIT...adding the code below, it's basically the same code as in the example with just adding another index and removing the intercept(alpha)


library(PerformanceAnalytics, quietly = TRUE,  warn.conflicts = FALSE)

data(managers)
# extract HAM1 and SP500 excess returns
HAM1 = 100*(managers[,"HAM1", drop=FALSE] - managers[,"US 3m TR", drop=FALSE])
factor_indices = cbind(100*(managers[,"SP500 TR", drop=FALSE] - managers[,"US 3m TR", drop=FALSE]),100*(managers[,"EDHEC LS EQ", drop=FALSE]))
factor_indices= factor_indices['1997-01-31/']
HAM1 = HAM1['1997-01-31/']

colnames(factor_indices) = c("SP500","EQLS")

# Specifying a set model parameters
s2_v = 1 # Variance of observations
s2_sp = 0.01
s2_eqls = 0.01
# Construct a regression model
tvp.dlm = dlmModReg(X=factor_indices, addInt=FALSE, dV=s2_v, dW=c(s2_sp, s2_eqls))

# looking at the various component

tvp.dlm[c("FF","V","GG","W","m0","C0")]
tvp.dlm[c("JFF","JV","JGG","JW")]

ols.fit = lm(HAM1 ~ factor_indices)
summary(ols.fit)

start.vals = c(1,0.01,0.01)

names(start.vals) = c("lns2_v", "lns2_sp", "lns2_eqls")


# function to build Time Varying Parameter state space model
buildTVP <- function(parm, x.mat){
parm <- exp(parm)
return( dlmModReg(X=x.mat, dV=parm[1],addInt=FALSE, dW=c(parm[2], parm[3])) )
}

# Estimate the model
TVP.mle = dlmMLE(y=HAM1, parm=start.vals, x.mat=factor_indices, build=buildTVP, hessian=T)

# get sd estimates

#se2 <- sqrt(exp(TVP.mle$par))
#names(se2) = c("s_obs", "s_alpha", "s_beta")
#sqrt(se2)

TVP.dlm <- buildTVP(TVP.mle$par, factor_indices)
TVP.f <- dlmFilter(y = HAM1, mod = TVP.dlm)
# Optimal estimates of θ_t given information available at time T.
TVP.s <- dlmSmooth(TVP.f)

# extract smoothed states

sp.s = xts(TVP.s$s[-1,1,drop=FALSE], as.Date(rownames(TVP.s$s[-1,])))
eqls.s = xts(TVP.s$s[-1,2,drop=FALSE], as.Date(rownames(TVP.s$s[-1,])))
colnames(sp.s) = "sp"
colnames(eqls.s) = "eqls"


No comments:

Post a Comment

technique - How credible is wikipedia?

I understand that this question relates more to wikipedia than it does writing but... If I was going to use wikipedia for a source for a res...