Nothing
## ----setup, include = FALSE---------------------------------------------------
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
echo = TRUE, include = TRUE, message = FALSE, warning = FALSE, eval = FALSE
)
## -----------------------------------------------------------------------------
# kf = kalman_filter(ssm, yt, Xo, Xs, w, smooth)
## -----------------------------------------------------------------------------
# library(kalmanfilter)
# library(maxLik)
# library(ggplot2)
# library(data.table)
# library(gridExtra)
# data(treasuries)
# tau = unique(treasuries$maturity)
#
# #State space model for the Nelson-Siegel dynamic factor yield curve
# yc_ssm = function(par, tau){
# #Set factor names
# tau = unique(tau)
# factors = c("l", "s", "c")
#
# #Loading on the slope factor
# Ls = function(par, tau){
# return(-(1 - exp(-tau*par["lambda"]))/(tau*par["lambda"]))
# }
#
# #Loading on the curvature factor
# Lc = function(par, tau){
# return(-Ls(par["lambda"], tau) - exp(-tau*par["lambda"]))
# }
#
# ########## Define the state space model
# #Transition matrix
# Fm = matrix(par[grepl("phi_", names(par))], nrow = 3, ncol = 3,
# dimnames = list(paste0(factors, "_t0"),
# paste0(factors, "_t1")))
# Fm[is.na(Fm)] = 0
#
# #Transition intercept matrix
# Dm = matrix(par[grepl("D_", names(par))], ncol = 1,
# dimnames = list(rownames(Fm), NULL))
#
# #Transition error covariance matrix
# Qm = matrix(par[unlist(lapply(factors, function(x){paste0("sig_", x, factors)}))], nrow = 3, ncol = 3)
# Qm[lower.tri(Qm)] = Qm[upper.tri(Qm)]
# dimnames(Qm) = list(rownames(Fm), rownames(Fm))
#
# #Observation equation matrix
# n = length(tau)
# Hm = matrix(NA, nrow = n, ncol = 3,
# dimnames = list(as.character(tau), rownames(Fm)))
# tau = as.numeric(tau)
# if("l" %in% factors){
# Hm[, "l_t0"] = 1
# }
# if("s" %in% factors){
# Hm[, "s_t0"] = Ls(par, tau)
# }
# if("c" %in% factors){
# Hm[, "c_t0"] = Lc(par, tau)
# }
#
# #Observation error variance covariance matrix
# Rm = diag(sum(grepl("sig_\\d+", names(par))))*par[grepl("sig_\\d+", names(par))]^2
# dimnames(Rm) = list(rownames(Hm), rownames(Hm))
#
# #Observation intercept matrix
# Am = matrix(0, nrow = nrow(Hm), ncol = 1,
# dimnames = list(rownames(Hm), NULL))
#
# #Initial guess for the unobserved vector
# B0 = matrix(par[names(par) %in% c("level", "slope", "curvature")], ncol = 1, nrow = nrow(Fm),
# dimnames = list(rownames(Fm), NULL))
#
# #Initial guess for the variance of the unobserved vector
# P0 = diag(par["P0"]^2, nrow = nrow(Qm), ncol = ncol(Qm))
#
# return(list(Fm = Fm, Dm = Dm, Qm = Qm,
# Hm = Hm, Am = Am, Rm = Rm,
# B0 = B0, P0 = P0))
# }
#
# #Set the initial values
# init = c(level = 5.9030, slope = -0.7090, curvature = 0.8690, lambda = 0.0423,
# D_l = 0.1234, D_s = -0.2285, D_c = 0.2020,
# phi_ll = 0.9720, phi_ls = 0.1009, phi_lc = -0.1226,
# phi_sl = -0.0209, phi_ss = 0.8189, phi_sc = 0.0192,
# phi_cl = -0.0061, phi_cs = -0.1446, phi_cc = 0.8808,
# sig_ll = 0.1017,
# sig_sl = 0.0937, sig_ss = 0.2267,
# sig_cl = 0.0303, sig_cs = 0.0351, sig_cc = 0.7964,
# sig_1 = 0.0934, sig_3 = 0.0001, sig_6 = 0.1206, sig_12 = 0.1525,
# sig_24 = 0.1328, sig_36 = 0.0855, sig_60 = 0.0001, sig_84 = 0.0397,
# sig_120 = 0.0595, sig_240 = 0.1438, sig_360 = 0.1450,
# P0 = 0.0001)
#
# #Set up the constraints: lambda and all standard deviation parameters must be positive
# ineqA = matrix(0, nrow = 15, ncol = length(init), dimnames = list(NULL, names(init)))
# diag(ineqA[, c("lambda", "sig_ll", "sig_ss", "sig_cc", paste0("sig_", tau))]) = 1
# ineqB = matrix(0, nrow = nrow(ineqA), ncol = 1)
#
# #Convert to an NxT matrix
# yt = dcast(treasuries, "date ~ maturity", value.var = "value")
# yt = t(yt[, 2:ncol(yt)])
#
# #Set the objective function
# objective = function(par){
# ssm = yc_ssm(par, tau)
# return(kalman_filter(ssm, yt,)$lnl)
# }
#
# #Solve the model
# solve = maxLik(logLik = objective, start = init, method = "BFGS",
# finalHessian = FALSE, hess = NULL,
# control = list(printLevel = 2, iterlim = 10000),
# constraints = list(ineqA = ineqA, ineqB = ineqB))
#
# #Get the estimated state space model
# ssm = yc_ssm(solve$estimate, tau)
#
# #Filter the data with the model
# filter = kalman_filter(ssm, yt, smooth = TRUE)
#
# #Get the estimated unobserved factors
# B_tt = data.table(t(filter[["B_tt"]]))[, "date" := unique(treasuries$date)]
# colnames(B_tt)[1:3] = c("level", "slope", "curvature")
#
# #Get the estimated yields
# y_tt = data.table(t(filter[["y_tt"]]))[, "date" := unique(treasuries$date)]
# colnames(y_tt)[1:(ncol(y_tt) - 1)] = tau
#
# #Plot the data
# g1 = ggplot(treasuries, id.vars = "date") +
# geom_line(aes(x = date, y = value, group = factor(maturity), color = factor(maturity))) +
# theme_minimal() + theme(legend.position = "bottom") +
# labs(title = "Actual Treasury Yields", x = "", y = "Value") +
# guides(color = guide_legend(title = NULL))
# g2 = ggplot(melt(y_tt, id.vars = "date")) +
# geom_line(aes(x = date, y = value, group = variable, color = variable)) +
# theme_minimal() + theme(legend.position = "bottom") +
# labs(title = "Estimated Treasury Yields", x = "", y = "Value") +
# guides(color = guide_legend(title = NULL))
# g3 = ggplot(melt(B_tt, id.vars = "date")) +
# geom_line(aes(x = date, y = value, group = variable, color = variable)) +
# theme_minimal() + theme(legend.position = "bottom") +
# labs(title = "Estimated Factors", x = "", y = "Value") +
# guides(color = guide_legend(title = NULL))
# grid.arrange(g1, g2, g3, layout_matrix = rbind(c(1, 2), c(3, 3)))
## -----------------------------------------------------------------------------
# #Set the objective function
# objective = function(par){
# ssm = yc_ssm(par, tau)
# for(x in names(ssm)){
# if(!x %in% c("B0", "P0")){
# ssm[[x]] = array(ssm[[x]], dim = c(dim(ssm[[x]]), ncol(yt)))
# }
# }
# return(kalman_filter(ssm, yt)$lnl)
# }
#
# #Solve the model
# solve = maxLik(logLik = objective, start = init, method = "BFGS",
# finalHessian = FALSE, hess = NULL,
# control = list(printLevel = 2, iterlim = 10000),
# constraints = list(ineqA = ineqA, ineqB = ineqB))
## -----------------------------------------------------------------------------
# library(kalmanfilter)
# library(data.table)
# library(maxLik)
# library(ggplot2)
# library(gridExtra)
# data(sw_dcf)
# data = sw_dcf[, colnames(sw_dcf) != "dcoinc", with = F]
# vars = colnames(data)[colnames(data) != "date"]
#
# #State space model for the Stock and Watson Dynamic Common Factor model
# dcf_ssm = function(par, yt){
# #Get the parameters
# vars = dimnames(yt)[which(unlist(lapply(dimnames(yt), function(x){!is.null(x)})))][[1]]
# phi = par[grepl("phi", names(par))]
# names(phi) = gsub("phi", "", names(phi))
# gamma = par[grepl("gamma_", names(par))]
# names(gamma) = gsub("gamma_", "", names(gamma))
# psi = par[grepl("psi_", names(par))]
# names(psi) = gsub("psi_", "", names(psi))
# sig = par[grepl("sigma_", names(par))]
# names(sig) = gsub("sigma_", "", names(sig))
#
# #Build the transition matrix
# phi_dim = max(c(length(phi)), length(unique(sapply(strsplit(names(gamma), "\\."), function(x){x[2]}))))
# psi_dim = sapply(unique(sapply(strsplit(names(psi), "\\."), function(x){x[1]})), function(x){
# max(as.numeric(sapply(strsplit(names(psi)[grepl(paste0("^", x), names(psi))], "\\."), function(x){x[2]})))
# })
# Fm = matrix(0, nrow = phi_dim + length(psi), ncol = phi_dim + length(psi),
# dimnames = list(
# c(paste0("ct.", 0:(phi_dim - 1)),
# unlist(lapply(names(psi_dim), function(x){paste0("e_", x, ".", 0:(psi_dim[x] - 1))}))),
# c(paste0("ct.", 1:phi_dim),
# unlist(lapply(names(psi_dim), function(x){paste0("e_", x, ".", 1:psi_dim[x])})))
# ))
# Fm["ct.0", paste0("ct.", names(phi))] = phi
# for(i in 1:length(vars)){
# Fm[paste0("e_", i, ".0"),
# paste0("e_", names(psi)[grepl(paste0("^", i), names(psi))])] = psi[grepl(paste0("^", i), names(psi))]
# }
# diag(Fm[intersect(rownames(Fm), colnames(Fm)), intersect(rownames(Fm), colnames(Fm))]) = 1
#
# #Build the observation matrix
# Hm = matrix(0, nrow = nrow(yt), ncol = nrow(Fm), dimnames = list(rownames(yt), rownames(Fm)))
# for(i in 1:length(vars)){
# Hm[i, paste0("ct.", sapply(strsplit(names(gamma)[grepl(paste0("^", i), names(gamma))], "\\."), function(x){x[2]}))] =
# gamma[grepl(paste0("^", i), names(gamma))]
# }
# diag(Hm[, paste0("e_", 1:length(vars), ".0")]) = 1
#
# #Build the state covariance matrix
# #Set the dynamic common factor standard deviation to 1
# Qm = matrix(0, ncol = ncol(Fm), nrow = nrow(Fm), dimnames = list(rownames(Fm), rownames(Fm)))
# Qm["ct.0", "ct.0"] = 1
# for(i in 1:length(vars)){
# Qm[paste0("e_", i, ".0"), paste0("e_", i, ".0")] = sig[names(sig) == i]^2
# }
#
# #Build the observation equation covariance matrix
# Rm = matrix(0, ncol = nrow(Hm), nrow = nrow(Hm), dimnames = list(vars, vars))
#
# #Transition equation intercept matrix
# Dm = matrix(0, nrow = nrow(Fm), ncol = 1, dimnames = list(rownames(Fm), NULL))
#
# #Observation equation intercept matrix
# Am = matrix(0, nrow = nrow(Hm), ncol = 1)
#
# #Initialize the filter for each state
# B0 = matrix(0, nrow(Fm), 1)
# P0 = diag(nrow(Fm))
# dimnames(B0) = list(rownames(Fm), NULL)
# dimnames(P0) = list(rownames(Fm), rownames(Fm))
#
# B0 = solve(diag(ncol(Fm)) - Fm) %*% Dm
# VecP_ll = solve(diag(prod(dim(Fm))) - kronecker(Fm, Fm)) %*% matrix(as.vector(Qm), ncol = 1)
# P0 = matrix(VecP_ll[, 1], ncol = ncol(Fm))
#
# return(list(B0 = B0, P0 = P0, Am = Am, Dm = Dm, Hm = Hm, Fm = Fm, Qm = Qm, Rm = Rm))
# }
#
# #Log the data
# data.log = copy(data)
# data.log[, c(vars) := lapply(.SD, log), .SDcols = c(vars)]
#
# #Difference the data
# data.logd = copy(data.log)
# data.logd[, c(vars) := lapply(.SD, function(x){
# x - shift(x, type = "lag", n = 1)
# }), .SDcols = c(vars)]
#
# #Standardize the data
# data.logds = copy(data.logd)
# data.logds[, c(vars) := lapply(.SD, scale, scale = FALSE), .SDcols = c(vars)]
#
# #Transpose the data
# yt = t(data.logds[, c(vars), with = FALSE])
#
# #Set the initial values
# init = c(phi1 = 0.8588, phi2 = -0.1526,
# psi_1.1 = -0.1079, psi_1.2 = -0.1415,
# psi_2.1 = -0.3166, psi_2.2 = -0.0756,
# psi_3.1 = -0.3994, psi_3.2 = -0.2028,
# psi_4.1 = -0.0370, psi_4.2 = 0.3646,
# gamma_1.0 = 0.0064, gamma_1.1 = -0.0020,
# gamma_2.0 = 0.0018,
# gamma_3.0 = 0.0059, gamma_3.1 = -0.0027,
# gamma_4.0 = 0.0014, gamma_4.1 = -0.0004, gamma_4.2 = 0.0001, gamma_4.3 = 0.0004,
# sigma_1 = 0.0049, sigma_2 = 0.0056, sigma_3 = 0.0077, sigma_4 = 0.0013)
#
# #Set the constraints
# ineqA = matrix(0, nrow = 14,
# ncol = length(init), dimnames = list(NULL, names(init)))
# #Stationarity constraints
# ineqA[c(1, 2), c("phi1", "phi2")] = rbind(c(1, 1), c(-1, -1))
# ineqA[c(3, 4), grepl("psi_1", colnames(ineqA))] = rbind(c(1, 1), c(-1, -1))
# ineqA[c(5, 6), grepl("psi_2", colnames(ineqA))] = rbind(c(1, 1), c(-1, -1))
# ineqA[c(7, 8), grepl("psi_3", colnames(ineqA))] = rbind(c(1, 1), c(-1, -1))
# ineqA[c(9, 10), grepl("psi_4", colnames(ineqA))] = rbind(c(1, 1), c(-1, -1))
# #Non-negativity constraints
# diag(ineqA[c(11, 12, 13, 14), grepl("sigma_", colnames(ineqA))]) = 1
# ineqB = matrix(c(rep(1, 10),
# rep(0, 4)), nrow = nrow(ineqA), ncol = 1)
#
# #Define the objective function
# objective = function(par, yt){
# ssm = dcf_ssm(par, yt)
# return(kalman_filter(ssm, yt, smooth = FALSE)$lnl)
# }
#
# #Solve the model
# solve = maxLik(logLik = objective, start = init, method = "BFGS",
# finalHessian = FALSE, hess = NULL,
# control = list(printLevel = 2, iterlim = 10000),
# constraints = list(ineqA = ineqA, ineqB = ineqB),
# yt = yt)
#
# #Get the estimated state space model
# ssm = dcf_ssm(solve$estimate, yt)
#
# #Get the column means and standard deviations
# M = matrix(unlist(data.logd[, lapply(.SD, mean, na.rm = TRUE), .SDcols = c(vars)]),
# ncol = 1, dimnames = list(vars, NULL))
#
# #Get the coefficient matrices
# Hm = ssm[["Hm"]]
# Fm = ssm[["Fm"]]
#
# #Final K_t is approximation to steady state K
# filter = kalman_filter(ssm, yt, smooth = T)
# K = filter$K_t[,, dim(filter$K_t)[3]]
# W = solve(diag(nrow(K)) - (diag(nrow(K)) - K %*% Hm) %*% Fm) %*% K
# d = (W %*% M)[1, 1]
#
# #Get the intercept terms
# gamma = Hm[, grepl("ct", colnames(Hm))]
# D = M - gamma %*% matrix(rep(d, ncol(gamma)))
#
# #Initialize first element of the dynamic common factor
# Y1 = t(data.log[, c(vars), with = F][1, ])
# initC = function(par){
# return(sum((Y1 - D - gamma %*% par)^2))
# }
# C10 = optim(par = Y1, fn = initC, method = "BFGS", control = list(trace = FALSE))$par[1]
# Ctt = rep(C10, ncol(yt))
#
# #Build the rest of the level of the dynamic common factor
# ctt = filter$B_tt[which(rownames(Fm) == "ct.0"), ]
# for(j in 2:length(Ctt)){
# Ctt[j] = ctt[j] + Ctt[j - 1] + c(d)
# }
# Ctt = data.table(date = data$date, dcf = Ctt, d.dcf = ctt)
#
# #Plot the outputs
# g1 = ggplot(melt(data.log, id.vars = "date")[, "value" := scale(value), by = "variable"]) +
# ggtitle("Data", subtitle = "Log Levels (Rescaled)") +
# scale_y_continuous(name = "Value") +
# scale_x_date(name = "") +
# geom_line(aes(x = date, y = value, group = variable, color = variable)) +
# theme_minimal() + theme(legend.position = "bottom") + guides(color = guide_legend(title = NULL))
#
# g2 = ggplot( melt(data.logds, id.vars = "date")) +
# ggtitle("Data", subtitle = "Log Differenced & Standardized") +
# scale_y_continuous(name = "Value") +
# scale_x_date(name = "") +
# geom_hline(yintercept = 0, color = "black") +
# geom_line(aes(x = date, y = value, group = variable, color = variable)) +
# theme_minimal() + theme(legend.position = "bottom") + guides(color = guide_legend(title = NULL))
#
# g3 = ggplot(melt(Ctt, id.vars = "date")[variable == "dcf", ]) +
# ggtitle("Dynamic Common Factor", subtitle = "Levels") +
# scale_x_date(name = "") +
# geom_hline(yintercept = 0, color = "grey") +
# geom_line(aes(x = date, y = value, group = variable, color = variable)) +
# theme_minimal() + theme(legend.position = "bottom") + scale_color_manual(values = "black") +
# guides(color = guide_legend(title = NULL), fill = guide_legend(title = NULL)) +
# scale_y_continuous(name = "Value", limits = range(Ctt$dcf, na.rm = TRUE))
#
# g4 = ggplot(melt(Ctt, id.vars = "date")[variable == "d.dcf", ]) +
# ggtitle("Dynamic Common Factor", subtitle = "Differenced") +
# scale_x_date(name = "") +
# geom_hline(yintercept = 0, color = "grey") +
# geom_line(aes(x = date, y = value, group = variable, color = variable)) +
# theme_minimal() + theme(legend.position = "bottom") + scale_color_manual(values = "black") +
# guides(color = guide_legend(title = NULL), fill = guide_legend(title = NULL)) +
# scale_y_continuous(name = "Value", limits = range(Ctt$d.dcf, na.rm = TRUE))
#
# grid.arrange(g1, g2, g3, g4, layout_matrix = matrix(c(1, 3, 2, 4), nrow = 2))
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.