问题
I am attempting to estimate multivariate linear state space model across a panel of stocks. I have daily returns over 15 years and have aggerated them to monthly time series. As excepted, the issue that the entire process of MLE estimates takes a huge amount of time to complete. Is there an efficient way of handling this?
The model is the multivariate version of the dynamic Fama-French three factor model for m assets, j=1,…,m. Factors are loaded in x(t). Model is then:
y = α + β1 * x1 + β2 * x2 + β3 * x3 + v
α(t) = α(t-1) + w1
β1(t) = β1(t-1) + w2
β2(t) = β1(t-1) + w3
β3(t) = β1(t-1) + w4
where it is sensible to assume that the intercepts and the slopes are correlated across the m stocks. The above model can be rewritten in a more general form such as
y(t) = (Ft⊗Im)θ + υt, υt∼N(0,V)
θt = (G⊗Im)θ(t−1) + ωt, ωt∼N(0,W)
where
yt=[y1t,…,ymt] are the values of the m different y series
θt=[α1t,…,αmt,β1_1p,…,β1_mt,β2_1p,…,β2_1mt, β3_1p,…,β3_mt ]
υt=[υ1t,…,υmt] and ωt=[ω1t,…,ωmt] are iid
W=blockdiag(Wα;Wβ1;Wβ3;Wβ3)
Ft=[1xt]; and G=I_4
I am using dlm package and here is a snap shot of the code:
I assume for simplicity that the αj,t are time-invariant, which amounts to
assuming that Wα=0
m <- NCOL(ret)
q <- NCOL(factors) + 1 #factors + alpha
d <- sum((as.numeric(upper.tri(diag(m)))))
# Define a “build” function to be given to MLE routine
buildSUR <- function(psi) {
### Set up the model
CAPM <- dlmModReg(factors, addInt = TRUE)
CAPM$FF <- CAPM$FF %x% diag(m)
CAPM$GG <- CAPM$GG %x% diag(m)
CAPM$JFF <- CAPM$JFF %x% diag(m)
# specifying the mean of the distribution of the initial state of theta (alpha; beta1; beta2; beta3; beta4)
CAPM$m0 <- c(rep(0,q*m))
# Specifying the variance of the distribution of the initial state of theta (alpha; beta1; beta2; beta3; beta4)
CAPM$C0 <- CAPM$C0 %x% diag(m)
# ’CLEAN’ the system and observation variance-covariance matrices
CAPM$V <- CAPM$V %x% matrix(0, m, m)
CAPM$W <- CAPM$W %x% matrix(0, m, m)
# parametrization of the covariance matrix W
U <- matrix(0, nrow = m, ncol = m)
U2 <- matrix(0, nrow = m, ncol = m)
U3 <- matrix(0, nrow = m, ncol = m)
U4 <- matrix(0, nrow = m, ncol = m)
# putting random element in the upper triangle and making sure that the diagonal element of U are positive
U[upper.tri(U)] <- psi[1 : d]
diag(U) <- exp(0.5 * psi[(d+1) : (m+d)])
U2[upper.tri(U2)] <- psi[(m+d+1) : (m+2*d)]
diag(U2) <- exp(0.5 * psi[(m+2*d+1) : (2*m+2*d)])
U3[upper.tri(U2)] <- psi[(2*m+2*d+1) : (2*m+3*d)]
diag(U3) <- exp(0.5 * psi[(2*m+3*d+1) : (3*m+3*d)])
U4[upper.tri(U2)] <- psi[(3*m+3*d+1) : (3*m+4*d)]
diag(U4) <- exp(0.5 * psi[(3*m+4*d+1) : (4*m+4*d)])
#Constructing the matrix W_beta as the cross product of the U - equivalent to t(U) %*% U
# Assuming W_alpha is zero, U for beta1, U2 for beta2 etc.
W(CAPM)[(m+1) : (2*m), (m+1) : (2*m)] <- crossprod(U)
W(CAPM)[(2*m+1) : (3*m), (2*m+1) : (3*m)] <- crossprod(U2)
W(CAPM)[(3*m+1) : (4*m), (3*m+1) : (4*m)] <- crossprod(U3)
W(CAPM)[(4*m+1) : (5*m), (4*m+1) : (5*m)] <- crossprod(U4)
# parametrization of the covariance matrix V
U5 <- matrix(0, nrow = m, ncol = m)
# putting random element in the upper triangle
U5[upper.tri(U5)] <- psi[(4*m+4*d+1) : (4*m+5*d)]
# making the diagonal element positive
diag(U5) <- exp(0.5 * psi[(4*m+5*d+1) : (5*m+5*d)])
V(CAPM) <- crossprod(U5)
return(CAPM)
}
#MLE Estimate
CAPM_MLE <- dlmMLE(ret, rep(1, (5*m+5*d)), buildSUR, control = list(maxit = 500)).
回答1:
I answer myself. The stocks require different initial values to get through MLE estimation, so I made loop for running each stock individually with initial values from lm.fit.
来源:https://stackoverflow.com/questions/28961570/efficient-way-of-running-a-multivariate-linear-state-space-model-across-a-large