Esta pregunta es la siguiente a la formulada allí .
Estoy intentando filtrar una serie temporal de un índice de acciones (Stoxx 600) utilizando un filtro de kalman. Estoy usando el paquete R dlm y mi código está inspirado en el viñeta dlm con el filtrado de datos de Nilo.
Primero intentaba entender por qué mis datos filtrados eran similares a mis observaciones y resulta (como se ha dicho en la pregunta mencionada anteriormente) que al estimar los parámetros de mi modelo, la varianza de mi ecuación de medida es extremadamente pequeña (alrededor de 10e-5) comparada con la de la ecuación de estado (por encima de 300). La verdad es que estoy bastante sorprendido por esos resultados, ya que obtengo otros similares para otras series temporales financieras (incluidas las macroeconómicas) y ese tipo de series temporales son bien conocidas por ser ruidosas.
¿Podría explicarme si es el modelo el que no estoy especificando bien o si es el proceso de ajuste MLE el que no está funcionando correctamente?
Como en el ejemplo de Nilo de la viñeta dlm, estoy usando un con ruido, con varianzas desconocidas del sistema y de las observaciones.
Este es el código que estoy usando. El a es un vector con datos históricos mensuales del Stoxx 600 desde 1999:
rm(list = ls())
library(dlm)
a <- c(480.77,457.39,489.58,500.62,499.73,485.4,481.69,489.68,506.28,484.09,497.97,466.47,462.34,465.78,431.22,415.07,442.34,444.06,428.4,412.54,388.32,347.75,362.46,377.86,390,382.75,379.94,398.31,383.08,369.31,336.9,302.21,302.07,259.61,284.17,297.08,271.6,252.77,243.61,237.44,263.62,267.1,276.5,288.04,293.83,283.33,303.66,306.48,314.85,323.99,333.77,326.79,331.47,330.75,336.45,330.52,327.67,333.68,337.44,346.74,353.38,361.71,372.89,371.1,364.27,382.35,395.58,408.92,409.82,428.19,418.18,432.27,447.66,463.83,474.26,485.52,490.11,467.53,471.33,479.63,493.79,503.97,521.84,520.64,540.76,552.11,541.26,556.82,578.23,596.82,593.48,573.34,568.6,571.85,588.38,562.03,553.54,489.4,485.27,467.22,496.36,499.47,449.55,441.22,449.27,399.68,346.95,323.43,311.26,300.43,272.53,278.88,318.69,334.33,331.34,362.45,381.22,392,383.26,387.87,412.09,401.04,399.9,430.01,425.74,404.75,402.79,423.12,417.27,431.61,442.33,436.37,459.95,467.45,479,462.53,478.25,477.73,464.8,452.25,405.81,387.2,417.09,412.45,420.35,437.85,456.02,455.67,448.15,421.12,442.4,460.82,470.61,475.28,479.01,489.52,496.77,510.74,516.59,525.07,533.78,544.67,517.06,543.98,541.18,565.63,587.87,593.91,600.04,590.1,619.58,614.69,624.31,640.55,637.2,626.78,639.53,642.13,630.97,651.57,643.24,689.89,738.07,750.44,751.19,763.73,729.46,758.74,696.3,668.02,722.01,742.33,705,660.1,645.53,654.57,666.03)
data_to_fit <- a
buildFun <- function(x) {
dlmModPoly(1, dV = exp(x[1]), dW = exp(x[2]))
}
fit <- dlmMLE(data_to_fit, parm = c(0,0), build = buildFun)
print(exp(fit$par[1]))
print(exp(fit$par[2]))
dlm_Jump <- buildFun(fit$par)
JumpFilt <- dlmFilter(data_to_fit, dlm_Jump)
plot(data_to_fit, type = 'o')
lines(dropFirst(JumpFilt$m), type = 'o', pch = 20, col = "brown")
Gracias