← Catálogo
· Capítulo 14
T14_mST_CP_Financiero.R
# ══════════════════════════════════════════════════
# T14 · Caso práctico Financiero — IBEX 35 (Decision Desk)
# Abre primero mSeriesTemporales.Rproj en RStudio
# ══════════════════════════════════════════════════
library(tidyverse)
library(rugarch)
pausa <- function(msg = "\n [Pulsa ENTER para continuar...]") {
if (interactive()) { cat(msg); invisible(readline()) }
}
kupiec_test <- function(viol, alpha) {
x <- sum(viol); Tt <- length(viol); pihat <- x / Tt
LR <- -2 * ((Tt - x) * log(1 - alpha) + x * log(alpha) -
(Tt - x) * log(1 - pihat) - x * log(pihat))
list(x = x, T = Tt, LR = LR, p = 1 - pchisq(LR, df = 1))
}
christoffersen_test <- function(viol) {
n00 <- n01 <- n10 <- n11 <- 0
for (t in 2:length(viol)) {
if (viol[t - 1] == 0 && viol[t] == 0) n00 <- n00 + 1
if (viol[t - 1] == 0 && viol[t] == 1) n01 <- n01 + 1
if (viol[t - 1] == 1 && viol[t] == 0) n10 <- n10 + 1
if (viol[t - 1] == 1 && viol[t] == 1) n11 <- n11 + 1
}
pi01 <- n01 / (n00 + n01); pi11 <- n11 / (n10 + n11); pi <- (n01 + n11) / (n00 + n01 + n10 + n11)
LL0 <- (n00 + n10) * log(1 - pi) + (n01 + n11) * log(pi)
LL1 <- n00 * log(1 - pi01) + n01 * log(pi01) + n10 * log(1 - pi11) + n11 * log(pi11)
LR_ind <- -2 * (LL0 - LL1)
list(LR = LR_ind, p = 1 - pchisq(LR_ind, df = 1))
}
# ── 1. CARGA Y VaR AL 99%: HISTORICO Y NORMAL ─────
source("scripts/deskR.R")
ret_ibex <- desk_returns("_IBEX", type = "log")
r <- ret_ibex$return
alpha <- 0.01
mu_r <- mean(r); sd_r <- sd(r)
VaR_hist <- as.numeric(-quantile(r, alpha))
VaR_norm <- -(mu_r + qnorm(alpha) * sd_r)
cat(sprintf("VaR historico (99%%): %.2f%% | VaR normal (99%%): %.2f%%\n", VaR_hist * 100, VaR_norm * 100))
pausa()
# ── 2. VaR DINAMICO CON EGARCH(1,1)-t (CAP. 9) ────
spec <- ugarchspec(variance.model = list(model = "eGARCH", garchOrder = c(1, 1)),
mean.model = list(armaOrder = c(0, 0), include.mean = TRUE),
distribution.model = "std")
fit <- ugarchfit(spec, r, solver = "hybrid")
nu_hat <- coef(fit)["shape"]
sigma_t <- as.numeric(sigma(fit)); mu_t <- as.numeric(fitted(fit))
q_alpha <- qdist("std", p = alpha, shape = nu_hat)
VaR_garch <- -(mu_t + sigma_t * q_alpha)
cat(sprintf("VaR GARCH ultimo dia: %.2f%% | VaR GARCH medio muestra: %.2f%%\n",
tail(VaR_garch, 1) * 100, mean(VaR_garch) * 100))
pausa()
# ── 3. MONTE CARLO: VALIDACION DEL VaR GARCH ──────
set.seed(2026)
Nsim <- 1e5
mu_T <- tail(mu_t, 1); sigma_T <- tail(sigma_t, 1)
r_sim <- mu_T + sigma_T * rdist("std", n = Nsim, shape = nu_hat)
VaR_mc <- -as.numeric(quantile(r_sim, alpha))
ES_mc <- -mean(r_sim[r_sim <= -VaR_mc])
cat(sprintf("VaR Monte Carlo: %.2f%% (analitico: %.2f%%) | ES Monte Carlo: %.2f%%\n",
VaR_mc * 100, -(mu_T + sigma_T * q_alpha) * 100, ES_mc * 100))
pausa()
# ── 4. BACKTESTING: KUPIEC Y CHRISTOFFERSEN ───────
viol_hist <- as.numeric(r < -VaR_hist)
viol_norm <- as.numeric(r < -VaR_norm)
viol_garch <- as.numeric(r < -VaR_garch)
for (nm in c("hist", "norm", "garch")) {
viol <- get(paste0("viol_", nm))
ku <- kupiec_test(viol, alpha); ch <- christoffersen_test(viol)
cat(sprintf("%-6s violaciones=%.2f%% | Kupiec p=%.4f | Christoffersen p=%.4f\n",
nm, mean(viol) * 100, ku$p, ch$p))
}
cat("\nSolo el VaR GARCH (dinamico) supera con holgura el contraste de independencia de Christoffersen.\n")
# === FIN Caso Práctico Financiero — Tema 14 (IBEX 35, VaR y Expected Shortfall) ===