← Catálogo · Capítulo 15

T15_mST_CP_Financiero.R

Ver crudo
# ══════════════════════════════════════════════════
# T15 · Caso práctico Financiero — Cartera IBEX 35 / S&P 500 / DAX
# Abre primero mSeriesTemporales.Rproj en RStudio
# ══════════════════════════════════════════════════

library(tidyverse)
library(rmgarch)
library(rugarch)

pausa <- function(msg = "\n  [Pulsa ENTER para continuar...]") {
  if (interactive()) { cat(msg); invisible(readline()) }
}

# El solver numerico del DCC falla, ocasionalmente, a converger a un ajuste
# valido; se reintenta unas pocas veces antes de dar el ajuste por bueno.
dcc_fit_robusto <- function(spec, data, intentos = 5) {
  for (i in 1:intentos) {
    fit <- tryCatch(dccfit(spec, data = data, solver = "nlminb"), error = function(e) NULL)
    if (!is.null(fit) && isTRUE(tryCatch({ rcor(fit); TRUE }, error = function(e) FALSE))) return(fit)
  }
  stop("No se pudo ajustar el modelo DCC tras varios intentos.")
}

# ── 1. CARGA Y ALINEACION DE LAS TRES SERIES ──────
source("scripts/deskR.R")
r_ibex <- desk_returns("_IBEX", type = "log")
r_gspc <- desk_returns("_GSPC", type = "log")
r_gdax <- desk_returns("_GDAXI", type = "log")

m <- purrr::reduce(
  list(r_ibex |> dplyr::select(date, ibex = return),
       r_gspc |> dplyr::select(date, sp500 = return),
       r_gdax |> dplyr::select(date, dax = return)),
  inner_join, by = "date"
)
m <- tail(m, 2000)
m$fecha <- as.Date(m$date)
R <- as.matrix(m[, c("ibex", "sp500", "dax")])
cat(sprintf("Usando %d sesiones comunes (%s a %s)\n", nrow(m), min(m$fecha), max(m$fecha)))
pausa()

# ── 2. AJUSTE DCC(1,1)-t ──────────────────────────
uspec <- multispec(replicate(3, ugarchspec(
  variance.model = list(model = "sGARCH", garchOrder = c(1, 1)),
  mean.model = list(armaOrder = c(0, 0)), distribution.model = "std"
)))
dcc_spec <- dccspec(uspec, dccOrder = c(1, 1), distribution = "mvt")
dcc_fit <- dcc_fit_robusto(dcc_spec, R)
cat("Parametros de correlacion dinamica (a, b):\n")
print(coef(dcc_fit)[c("[Joint]dcca1", "[Joint]dccb1")])
pausa()

# ── 3. CORRELACION CONDICIONAL: IBEX-DAX vs. IBEX-SP500 ─
Rt <- rcor(dcc_fit)
cor_ibex_dax <- Rt["ibex", "dax", ]
cor_ibex_sp  <- Rt["ibex", "sp500", ]
cat(sprintf("Correlacion IBEX-DAX:    media=%.3f (min=%.3f max=%.3f)\n",
            mean(cor_ibex_dax), min(cor_ibex_dax), max(cor_ibex_dax)))
cat(sprintf("Correlacion IBEX-SP500:  media=%.3f (min=%.3f max=%.3f)\n",
            mean(cor_ibex_sp), min(cor_ibex_sp), max(cor_ibex_sp)))
cat("Fecha de correlacion IBEX-DAX maxima:", as.character(m$fecha[which.max(cor_ibex_dax)]), "\n")
pausa()

# ── 4. RATIO DE COBERTURA IBEX CON DAX ────────────
Ht <- rcov(dcc_fit)
h_dinamico <- Ht["ibex", "dax", ] / Ht["dax", "dax", ]
h_estatico <- cov(R[, "ibex"], R[, "dax"]) / var(R[, "dax"])

pos_sin <- R[, "ibex"]
pos_din <- R[, "ibex"] - h_dinamico * R[, "dax"]
pos_est <- R[, "ibex"] - h_estatico * R[, "dax"]

cat(sprintf("Ratio cobertura estatico: %.3f | dinamico medio: %.3f\n", h_estatico, mean(h_dinamico)))
cat(sprintf("Reduccion de varianza -> dinamica: %.1f%% | estatica: %.1f%%\n",
            (1 - var(pos_din) / var(pos_sin)) * 100, (1 - var(pos_est) / var(pos_sin)) * 100))

# === FIN Caso Práctico Financiero — Tema 15 (IBEX-S&P500-DAX, DCC-GARCH) ===