時間序列

帶有卡爾曼濾波器的違反直覺的時變 Beta

  • June 30, 2017

如果您習慣使用R,您會喜歡以下可重現的程式碼:

# =================================================== #
# An example of state-space monitor via Kalman filter #
# =================================================== #

op <- par(no.readonly = TRUE)
Sys.setenv(TZ = 'UTC')

# Contents:

# 1. Installing packages
# 2. Loading packages
# 3. Custom functions
# 4. Downloading and preparing data
# 5. Cross-Betas Kalman filtering

# *********************************
# 1. Installing packages
# *********************************

install.packages('KFAS')
install.packages('latticeExtra')
install.packages('quantmod')

# *********************************
# 2. Loading packages
# *********************************

require(compiler)
require(latticeExtra)
require(KFAS)
require(quantmod)

# *********************************
# 3. Custom functions
# *********************************

# This function returns the time varying state-space representation 
# parameters of a linear model which represents y ~ X

Kalman.beta <- cmpfun(function(y, X)
{
 model <- regSSM(y = y, X = cbind(1, X), H = NA, Q = diag(NA, 2))
 object <- fitSSM(inits = rep(0, 3), model = model)$model
     KFAS <- KFS(object = object)
     alpha.beta <- xts(t(KFAS$alphahat), index(y))
 colnames(alpha.beta) <- rep(paste(colnames(y), 'vs' , colnames(X)), 2)
 return(alpha.beta)
})  

# *********************************
# 4. Downloading and preparing data
# *********************************

env <- new.env()
Symbols <- c('SPY', 'QQQ', 'XLF', 'TLT')
getSymbols(Symbols = Symbols, env = env, from = '1950-01-01')
args <- eapply(env = env, FUN = function(x){ClCl(x)})
X <- na.omit(do.call(what = merge, args = args))
colnames(X) <- Symbols
xyplot(X)

# *********************************
# 5. Cross-Betas Kalman filtering
# *********************************

Betas <- NULL
k <- 0

for(i in 1:ncol(X))
{
 for(j in (1:ncol(X))[-i])
 {
   k <- k + 1
   Betas[[k]] <- Kalman.beta(y = X[,i], X = X[,j])[,2]
 }
}

Beta.matrix <- do.call(what = merge, args = Betas)
colnames(Beta.matrix) <- gsub(pattern = '.', fixed = TRUE, 
                             x = colnames(Beta.matrix), replacement = ' ')
xyplot(Beta.matrix, superpose = FALSE, auto.key = FALSE,
      main = '')

這段程式碼有什麼作用?它基本上使用卡爾曼濾波器來估計時變 $ \beta_{t} $ 每個資產相互對抗並繪製它們。

那是怎麼回事?

如果使用簡單的線性回歸模型來估計 $ \beta $ 隨著時間的推移,你會看到它經常發生,例如, $ \beta_{t}<1<\beta $ 要麼 $ \beta_{t}>0>\beta $ 在大部分時間序列中……這真的違反直覺!

SPY如何與QQQ負相關,而很明顯它們是強相關的,並且 $ \beta \approx 1 $ ? 等等…

你會怎麼解釋這個?

我的程式碼有什麼問題嗎?

這絕對不是卡爾曼濾波器的問題:如果你替換這行程式碼

args &lt;- eapply(env = env, FUN = function(x){ClCl(x)})

有了這個

args &lt;- eapply(env = env, FUN = function(x){ClCl(x)})[Symbols]

eapply()將保留原始 Yahoo 查詢的順序quantmod。你可以檢查,你會看到每個 $ \beta_{t} $ 匹配關於 $ \beta $ 從簡單的 OLS 線性回歸 CAPM 樣。

引用自:https://quant.stackexchange.com/questions/8438