##1

#Getting the data
library(tidyquant)
SPY <- "SPY" %>% 
  tq_get(get  = "stock.prices",
           from = "2019-10-10",
           to   = "2024-10-10")
#30 days with highest change
library(tidyverse)
rets <- SPY %>% 
  tq_transmute(adjusted, periodReturn, period = "daily",type="log")

# Asegurarnos de que 'daily.returns' es numérico
rets <- rets %>%
  mutate(daily.returns = as.numeric(daily.returns))

# Seleccionar los 30 días con mayores retornos en valor absoluto
top_30_abs_rets <- rets %>%
  mutate(abs_return = abs(daily.returns)) %>%
  arrange(desc(abs_return)) %>%
  slice(1:30) %>%
  select(date)

# Agregar una columna para identificar si es uno de los 30 días con mayores retornos
rets <- rets %>%
  mutate(is_top30 = ifelse(date %in% top_30_abs_rets$date, TRUE, FALSE))

# Graficar la serie de tiempo de los retornos y resaltar los 30 días con mayores retornos absolutos
ggplot(rets, aes(x = date, y = daily.returns)) +
  geom_line(color = "blue", size = 0.7) +
  geom_point(data = filter(rets, is_top30), aes(x = date, y = daily.returns), color = "red", size = 3) +
  labs(title = "Retornos diarios logarítmicos de SPY (2019-2024)",
       x = "Fecha", y = "Retorno logarítmico diario") +
  theme_minimal()

El gráfico muestra los retornos diarios del S&P 500 (SPY) durante 5 años, destacando los 30 días con mayores cambios absolutos. Esto evidencia la presencia de volatility clusters (períodos agrupados de alta y baja volatilidad) y heterocedasticidad (varianza no constante a lo largo del tiempo). Además, la mayoría de los picos resaltados corresponden a caídas, lo que sugiere la presencia del leverage effect, un fenómeno donde la volatilidad tiende a aumentar más durante caídas que en subidas del mercado.

##2 Retornos mensuales y remover 2020

#Por teoría la suma de los logretornos es el retorno del período a evaluar

# Convertir los retornos diarios a retornos mensuales
rets_monthly <- rets %>%
  mutate(month = floor_date(date, "month")) %>%  # Crear una columna para el mes
  group_by(month) %>%                            # Agrupar por mes
  summarise(monthly_return = sum(daily.returns))  # Sumar los retornos logarítmicos diarios

# Ahora me quedo solo con Dic 2023 para atrás en los datos mensuales
rets_upto2023 <- rets_monthly %>%
  filter(month < as.Date("2024-01-01"))

# Crear un conjunto de holdout a partir del 01 de enero de 2024 en los datos mensuales
rets_holdout <- rets_monthly %>%
  filter(month >= as.Date("2024-01-01"))

##3 is data serially correlated

acf(rets_upto2023$monthly_return)

pacf(rets_upto2023$monthly_return)

#no muestran autocorrelación

t.test(rets_upto2023$monthly_return) #media igual a 0 al 5%
## 
##  One Sample t-test
## 
## data:  rets_upto2023$monthly_return
## t = 1.3934, df = 50, p-value = 0.1697
## alternative hypothesis: true mean is not equal to 0
## 95 percent confidence interval:
##  -0.004767944  0.026368024
## sample estimates:
##  mean of x 
## 0.01080004
# Prueba de Ljung-Box (usando rets_upto2023 en lugar de rets_train)
Box.test(rets_upto2023$monthly_return, lag = 20, type = "Ljung-Box")
## 
##  Box-Ljung test
## 
## data:  rets_upto2023$monthly_return
## X-squared = 16.119, df = 20, p-value = 0.7092
#Dado que el p-valor es 0.7092, no podemos rechazar la hipótesis nula de que no hay autocorrelación en los retornos mensuales. Esto significa que no hay suficiente evidencia para concluir que los datos de retornos mensuales hasta diciembre de 2023 estén serialmente correlacionados.

library(forecast)
## Warning: package 'forecast' was built under R version 4.3.3
#vamos a ver qué sugeriría auto.arima para tener más información valiosa
auto.arima(rets_upto2023$monthly_return, seasonal = FALSE)
## Series: rets_upto2023$monthly_return 
## ARIMA(0,0,0) with zero mean 
## 
## sigma^2 = 0.00312:  log likelihood = 74.76
## AIC=-147.53   AICc=-147.45   BIC=-145.6
#El modelo ARIMA(0,0,0) con media cero sugiere que no necesitas un modelo ARMA para capturar la dinámica de los retornos mensuales de SPY hasta diciembre de 2023, ya que estos parecen comportarse como ruido blanco, sin autocorrelación significativa ni estructura temporal relevante.

##4. Does it also need a GARCH model? Run ARCH tests.

#dado que el t test me dio que la media es 0 al 5% no me voy a preocupar el centrar la distribución

acf(rets_upto2023$monthly_return^2)

#por ahí que en el primer lag hay un poquito de corr pero no mucho
pacf(rets_upto2023$monthly_return)

# Pruebas de autocorrelación en los rendimientos al cuadrado
Box.test(coredata(rets_upto2023$monthly_return^2), type="Ljung-Box", lag = 12) 
## 
##  Box-Ljung test
## 
## data:  coredata(rets_upto2023$monthly_return^2)
## X-squared = 11.15, df = 12, p-value = 0.5161
library(FinTS)
## Warning: package 'FinTS' was built under R version 4.3.3
## 
## Attaching package: 'FinTS'
## The following object is masked from 'package:forecast':
## 
##     Acf
# Prueba ARCH de Engle (LM Test)
ArchTest(rets_upto2023$monthly_return)
## 
##  ARCH LM-test; Null hypothesis: no ARCH effects
## 
## data:  rets_upto2023$monthly_return
## Chi-squared = 14.629, df = 12, p-value = 0.2624
library(ggplot2)

# Crear una nueva columna para los retornos al cuadrado
rets_upto2023 <- rets_upto2023 %>%
  mutate(monthly_return_squared = monthly_return^2)

# Graficar los retornos al cuadrado
ggplot(rets_upto2023, aes(x = month, y = monthly_return_squared)) +
  geom_line(color = "blue", size = 0.7) +
  labs(title = "Retornos Mensuales al Cuadrado de SPY (hasta 2023)",
       x = "Mes", y = "Retornos Mensuales al Cuadrado") +
  theme_minimal()

#Ambas pruebas, tanto la de Ljung-Box sobre los retornos al cuadrado como la prueba ARCH de Engle, sugieren que no hay efectos ARCH en los retornos mensuales de SPY hasta 2023. Esto implica que la volatilidad de los retornos no parece estar correlacionada de manera significativa a lo largo del tiempo, y no es necesario un modelo ARCH para capturar posibles cambios en la varianza.

##Separar la data

# Definir el número de filas en el conjunto de datos
n <- nrow(rets_upto2023)

# Calcular el índice para la separación 70/30
split_index <- round(n * 0.7)

# Separar los datos en conjunto de entrenamiento (70%) y prueba (30%)
train_data <- rets_upto2023[1:split_index, ]
test_data <- rets_upto2023[(split_index + 1):n, ]

#run simulations

library(rugarch)
## Warning: package 'rugarch' was built under R version 4.3.3
## Loading required package: parallel
## 
## Attaching package: 'rugarch'
## The following object is masked from 'package:purrr':
## 
##     reduce
## The following object is masked from 'package:stats':
## 
##     sigma
# Especificar el modelo GARCH(1,1)
spec <- ugarchspec(variance.model = list(model = "sGARCH", garchOrder = c(1,1)),
                   mean.model = list(armaOrder = c(0,0), include.mean = TRUE),
                   distribution.model = "norm")

# Ajustar el modelo a los datos de entrenamiento
garch_fit <- ugarchfit(spec, data = train_data$monthly_return)
## Warning in .sgarchfit(spec = spec, data = data, out.sample = out.sample, : 
## ugarchfit-->waring: using less than 100 data
##  points for estimation
# Simular 1000 trayectorias para la longitud del conjunto de prueba
n_sim <- nrow(test_data)  # Número de meses en el conjunto de prueba
n_scenarios <- 1000       # Número de simulaciones

# Usar ugarchsim para realizar las simulaciones
garch_sim <- ugarchsim(garch_fit, n.sim = n_sim, m.sim = n_scenarios)

# Obtener las simulaciones (retornos simulados)
simulated_returns <- fitted(garch_sim)

# Obtener el último valor de las simulaciones (último mes de cada simulación)
final_returns_simulated <- simulated_returns[n_sim, ]

# Obtener el último valor real de los datos de prueba
final_return_test <- test_data$monthly_return[n_sim]

# Ver cuántas simulaciones están dentro del 5% del valor final observado
tolerance <- 0.05 * final_return_test
within_range <- sum(abs(final_returns_simulated - final_return_test) <= tolerance)

# Imprimir el número de simulaciones dentro del rango del 5%
cat("Número de simulaciones dentro del rango del 5%: ", within_range, "de 1000\n")
## Número de simulaciones dentro del rango del 5%:  16 de 1000
#Este resultado indica que, aunque el modelo GARCH(1,1) puede proporcionar simulaciones útiles, solo una pequeña proporción de las simulaciones logra un valor cercano al observado. Esto podría sugerir que:

#Se Necesita ajustar más el modelo o explorar modelos alternativos (como un GARCH de mayor orden o modelos con variaciones adicionales).
#El proceso generador de retornos es más complejo de lo que el modelo GARCH(1,1) está capturando

##Hacer combinaciones de hiperparámetros: rip mi pc

# Cargar las librerías necesarias
library(rugarch)
library(dplyr)
library(purrr)

# Definir las combinaciones de hiperparámetros
garch_order_list <- list(p = seq(1, 2), q = seq(1, 2)) # p y q para el modelo GARCH
arma_order_list <- list(p = seq(0, 1), q = seq(0, 1))  # p y q para el modelo ARMA
distribution_list <- c("norm", "std", "ged")           # Distribuciones de residuos

# Crear todas las combinaciones de los hiperparámetros
hyper_parameters <- cross_df(list(
    garch_p = garch_order_list$p,
    garch_q = garch_order_list$q,
    arma_p = arma_order_list$p,
    arma_q = arma_order_list$q,
    dist = distribution_list
))
## Warning: `cross_df()` was deprecated in purrr 1.0.0.
## ℹ Please use `tidyr::expand_grid()` instead.
## ℹ See <https://github.com/tidyverse/purrr/issues/768>.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
# Función para ajustar el modelo GARCH y simular 1000 trayectorias
fit_and_simulate_garch_model <- function(garch_p, garch_q, arma_p, arma_q, dist, data_train, data_test) {
    print(paste("Ajustando GARCH(", garch_p, ",", garch_q, ") con ARMA(", arma_p, ",", arma_q, ") y dist:", dist))
    
    spec <- ugarchspec(
        variance.model = list(model = "sGARCH", garchOrder = c(garch_p, garch_q)),
        mean.model = list(armaOrder = c(arma_p, arma_q)),
        distribution.model = dist
    )
    
    # Ajustar el modelo y capturar errores
    fit <- tryCatch({
        fit <- ugarchfit(spec = spec, data = data_train, solver = "hybrid", solver.control = list(trace = 1))
        
        # Verificar si el ajuste fue exitoso
        if (!is.null(fit@fit$convergence) && fit@fit$convergence == 0) {
            print("El modelo convergió correctamente.")
            
            # Simulamos 1000 trayectorias para la longitud del conjunto de prueba
            n_sim <- nrow(data_test)
            n_scenarios <- 1000
            sim <- ugarchsim(fit, n.sim = n_sim, m.sim = n_scenarios)
            
            # Obtener el último valor de las simulaciones y compararlo con el último valor real
            final_returns_simulated <- fitted(sim)[n_sim, ]
            final_return_test <- tail(data_test$monthly_return, 1)
            
            # Contar cuántas simulaciones están dentro del 5% del valor final real
            tolerance <- 0.05 * abs(final_return_test)
            within_range <- sum(abs(final_returns_simulated - final_return_test) <= tolerance)
            
            return(list(within_range = within_range))
        } else {
            print("El modelo no convergió correctamente.")
            return(list(within_range = NA_real_))
        }
        
    }, error = function(e) {
        print(paste("Error al ajustar modelo GARCH(", garch_p, ",", garch_q, ") con ARMA(", arma_p, ",", arma_q, "):", e$message))
        return(list(within_range = NA_real_))
    })
    
    return(fit)
}

# Asegúrate de que 'train_data' y 'test_data' están definidos y tienen datos
if (!exists("train_data") || !exists("test_data")) {
    stop("Por favor, define 'train_data' y 'test_data' antes de ejecutar el código.")
}

# Aplicar la función a todas las combinaciones de hiperparámetros
simulation_results <- hyper_parameters %>%
    mutate(
        results = pmap(list(garch_p, garch_q, arma_p, arma_q, dist),
                       ~ fit_and_simulate_garch_model(..1, ..2, ..3, ..4, ..5, train_data, test_data)),
        within_range = map_dbl(results, ~ .x$within_range)
    )
## [1] "Ajustando GARCH( 1 , 1 ) con ARMA( 0 , 0 ) y dist: norm"
## 
## Iter: 1 fn: -185.8851     Pars:  0.00273038 0.00000166 0.44960380 0.54939620
## Iter: 2 fn: -185.8851     Pars:  0.00273038 0.00000166 0.44960380 0.54939620
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 2 , 1 ) con ARMA( 0 , 0 ) y dist: norm"
## 
## Iter: 1 fn: -186.4590     Pars:  0.002774483 0.000001926 0.400551446 0.088073405 0.510375070
## Iter: 2 fn: -186.4590     Pars:  0.002774569 0.000001927 0.400540220 0.088095420 0.510364313
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 1 , 2 ) con ARMA( 0 , 0 ) y dist: norm"
## 
## Iter: 1 fn: -186.3502     Pars:  0.00276811571 0.00000168354 0.45530643409 0.54369352526 0.00000004273
## Iter: 2 fn: -186.3502     Pars:  0.00276811605 0.00000168354 0.45530645346 0.54369351228 0.00000003726
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 2 , 2 ) con ARMA( 0 , 0 ) y dist: norm"
## 
## Iter: 1 fn: -186.4590     Pars:  0.0027744897 0.0000019264 0.4005509489 0.0880749655 0.5103739189 0.0000001541
## Iter: 2 fn: -186.4590     Pars:  0.00277448963 0.00000192637 0.40055070422 0.08807516329 0.51037403171 0.00000009628
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 1 , 1 ) con ARMA( 1 , 0 ) y dist: norm"
## 
## Iter: 1 fn: -186.2701     Pars:   0.002702594 -0.106420504  0.000001633  0.461482214  0.537517738
## Iter: 2 fn: -186.2701     Pars:   0.002702594 -0.106420504  0.000001633  0.461482214  0.537517738
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 2 , 1 ) con ARMA( 1 , 0 ) y dist: norm"
## 
## Iter: 1 fn: -186.8698     Pars:   0.002754382 -0.108465615  0.000001992  0.394745237  0.119256809  0.484997903
## Iter: 2 fn: -186.8698     Pars:   0.002754388 -0.108464086  0.000001992  0.394745886  0.119257249  0.484996859
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 1 , 2 ) con ARMA( 1 , 0 ) y dist: norm"
## 
## Iter: 1 fn: -186.6531     Pars:   0.00273296315 -0.09605489607  0.00000164561  0.46418089906  0.53481905304  0.00000003546
## Iter: 2 fn: -186.6531     Pars:   0.00273296333 -0.09605446153  0.00000164562  0.46418084735  0.53481912747  0.00000001999
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 2 , 2 ) con ARMA( 1 , 0 ) y dist: norm"
## 
## Iter: 1 fn: -186.8698     Pars:   0.0027543817 -0.1084654206  0.0000019925  0.3947451231  0.1192574256  0.4849966784  0.0000006798
## Iter: 2 fn: -186.8698     Pars:   0.0027543824 -0.1084654918  0.0000019925  0.3947454169  0.1192570204  0.4849971080  0.0000004029
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 1 , 1 ) con ARMA( 0 , 1 ) y dist: norm"
## 
## Iter: 1 fn: -186.2845     Pars:   0.002696328 -0.106258137  0.000001642  0.461575443  0.537424303
## Iter: 2 fn: -186.2845     Pars:   0.002696150 -0.106437127  0.000001648  0.461654624  0.537345147
## Iter: 3 fn: -186.2845     Pars:   0.002696152 -0.106435208  0.000001648  0.461653778  0.537345994
## solnp--> Completed in 3 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 2 , 1 ) con ARMA( 0 , 1 ) y dist: norm"
## 
## Iter: 1 fn: -186.8889     Pars:   0.002749535 -0.108864512  0.000002018  0.392733066  0.123140583  0.483126284
## Iter: 2 fn: -186.8889     Pars:   0.002749565 -0.108798820  0.000002019  0.392691454  0.123084171  0.483224309
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 1 , 2 ) con ARMA( 0 , 1 ) y dist: norm"
## 
## Iter: 1 fn: -186.6580     Pars:   0.00272781702 -0.09450363440  0.00000165298  0.46395015072  0.53504982275  0.00000002977
## Iter: 2 fn: -186.6580     Pars:   0.00272781697 -0.09450364454  0.00000165298  0.46395017225  0.53504980617  0.00000002565
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 2 , 2 ) con ARMA( 0 , 1 ) y dist: norm"
## 
## Iter: 1 fn: -186.8889     Pars:   0.0027495396 -0.1088543876  0.0000020182  0.3927268100  0.1231319177  0.4831410767  0.0000001962
## Iter: 2 fn: -186.8889     Pars:   0.0027495396 -0.1088542752  0.0000020182  0.3927267260  0.1231318041  0.4831413540  0.0000001205
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 1 , 1 ) con ARMA( 1 , 1 ) y dist: norm"
## 
## Iter: 1 fn: -186.2854     Pars:   0.002697112 -0.021458426 -0.086455257  0.000001641  0.461760523  0.537239469
## Iter: 2 fn: -186.2854     Pars:   0.002697112 -0.021458525 -0.086455258  0.000001641  0.461760555  0.537239444
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 2 , 1 ) con ARMA( 1 , 1 ) y dist: norm"
## 
## Iter: 1 fn: -186.8893     Pars:   0.002749891 -0.013525249 -0.096369537  0.000002015  0.392989573  0.122849186  0.483161179
## Iter: 2 fn: -186.8893     Pars:   0.002749894 -0.013536395 -0.096358897  0.000002015  0.392988266  0.122849221  0.483162472
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 1 , 2 ) con ARMA( 1 , 1 ) y dist: norm"
## 
## Iter: 1 fn: -186.6600     Pars:   0.00272894745 -0.03431634449 -0.06256540966  0.00000164980  0.46421804249  0.53478188386  0.00000006473
## Iter: 2 fn: -186.6600     Pars:   0.00272894714 -0.03431809545 -0.06256384291  0.00000164980  0.46421804427  0.53478192683  0.00000002552
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 2 , 2 ) con ARMA( 1 , 1 ) y dist: norm"
## 
## Iter: 1 fn: -186.8893     Pars:   0.0027498920 -0.0135292993 -0.0963656416  0.0000020153  0.3929891542  0.1228491572  0.4831615316  0.0000001609
## Iter: 2 fn: -186.8893     Pars:   0.0027498920 -0.0135291332 -0.0963657251  0.0000020153  0.3929890554  0.1228493936  0.4831614124  0.0000001434
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 1 , 1 ) con ARMA( 0 , 0 ) y dist: std"
## 
## Iter: 1 fn: -187.8723     Pars:  0.002360203 0.000002345 0.519391973 0.479607946 6.025666713
## Iter: 2 fn: -187.8723     Pars:  0.002360204 0.000002345 0.519392875 0.479607079 6.025620842
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 2 , 1 ) con ARMA( 0 , 0 ) y dist: std"
## 
## Iter: 1 fn: -188.0845     Pars:  0.002357165 0.000002446 0.467329152 0.074777988 0.456892846 6.163203205
## Iter: 2 fn: -188.0845     Pars:  0.002357160 0.000002445 0.467329228 0.074777655 0.456893111 6.163141384
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 1 , 2 ) con ARMA( 0 , 0 ) y dist: std"
## 
## Iter: 1 fn: -188.0281     Pars:  0.0023732376 0.0000023383 0.5190681001 0.4799317717 0.0000001249 6.1315643457
## Iter: 2 fn: -188.0281     Pars:  0.0023732416 0.0000023383 0.5190682432 0.4799316495 0.0000001051 6.1316336329
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 2 , 2 ) con ARMA( 0 , 0 ) y dist: std"
## 
## Iter: 1 fn: -188.0845     Pars:  0.0023571733 0.0000024455 0.4673264334 0.0747824875 0.4568901149 0.0000009067 6.1632388408
## Iter: 2 fn: -188.0845     Pars:  0.0023571564 0.0000024455 0.4673305920 0.0747759495 0.4568932697 0.0000001842 6.1631353126
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 1 , 1 ) con ARMA( 1 , 0 ) y dist: std"
## 
## Iter: 1 fn: -187.8984     Pars:  0.002350997 0.032935304 0.000002421 0.525503824 0.473496170 5.756630353
## Iter: 2 fn: -187.8984     Pars:  0.002350996 0.032935802 0.000002421 0.525503968 0.473496031 5.756598586
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 2 , 1 ) con ARMA( 1 , 0 ) y dist: std"
## 
## Iter: 1 fn: -188.0920     Pars:  0.002351357 0.018234931 0.000002474 0.475489981 0.067714200 0.455795797 5.988483005
## Iter: 2 fn: -188.0920     Pars:  0.002351347 0.018235533 0.000002474 0.475489722 0.067713973 0.455796296 5.988391130
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 1 , 2 ) con ARMA( 1 , 0 ) y dist: std"
## 
## Iter: 1 fn: -188.0504     Pars:  0.002363744 0.030404830 0.000002407 0.524561171 0.474438359 0.000000389 5.864442896
## Iter: 2 fn: -188.0504     Pars:  0.002363737 0.030406072 0.000002407 0.524561145 0.474438562 0.000000244 5.864350885
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 2 , 2 ) con ARMA( 1 , 0 ) y dist: std"
## 
## Iter: 1 fn: -188.0920     Pars:  0.0023513513 0.0182352478 0.0000024744 0.4754898268 0.0677142123 0.4557956871 0.0000002703 5.9884336936
## Iter: 2 fn: -188.0920     Pars:  0.0023513535 0.0182349762 0.0000024744 0.4754897918 0.0677143322 0.4557956262 0.0000002476 5.9884642156
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 1 , 1 ) con ARMA( 0 , 1 ) y dist: std"
## 
## Iter: 1 fn: -187.9004     Pars:  0.002349296 0.035957119 0.000002427 0.525933695 0.473066293 5.731016850
## Iter: 2 fn: -187.9004     Pars:  0.002349297 0.035956683 0.000002427 0.525933446 0.473066550 5.731025484
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 2 , 1 ) con ARMA( 0 , 1 ) y dist: std"
## 
## Iter: 1 fn: -188.0928     Pars:  0.002350418 0.020276680 0.000002478 0.476223301 0.067120822 0.455655854 5.969010755
## Iter: 2 fn: -188.0928     Pars:  0.002350421 0.020276268 0.000002478 0.476223281 0.067120925 0.455655785 5.969042373
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 1 , 2 ) con ARMA( 0 , 1 ) y dist: std"
## 
## Iter: 1 fn: -188.0520     Pars:  0.0023621634 0.0329743960 0.0000024120 0.5249156948 0.4740841711 0.0000001204 5.8405894371
## Iter: 2 fn: -188.0520     Pars:  0.00236216029 0.03297427975 0.00000241200 0.52491536391 0.47408455926 0.00000007183 5.84051561153
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 2 , 2 ) con ARMA( 0 , 1 ) y dist: std"
## 
## Iter: 1 fn: -188.0928     Pars:  0.0023504254 0.0202748626 0.0000024777 0.4762243619 0.0671206463 0.4556546515 0.0000003424 5.9690853161
## Iter: 2 fn: -188.0928     Pars:  0.0023504200 0.0202766395 0.0000024777 0.4762223859 0.0671220709 0.4556552398 0.0000003067 5.9690398708
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 1 , 1 ) con ARMA( 1 , 1 ) y dist: std"
## 
## Iter: 1 fn: -188.1056     Pars:   0.002364209  0.655293077 -0.591803332  0.000002442  0.532532638  0.466467346  5.558789750
## Iter: 2 fn: -188.1056     Pars:   0.002364210  0.655293320 -0.591803724  0.000002442  0.532532445  0.466467551  5.558790809
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 2 , 1 ) con ARMA( 1 , 1 ) y dist: std"
## 
## Iter: 1 fn: -188.2538     Pars:   0.002377146  0.654844002 -0.593021221  0.000002425  0.531194692  0.000013436  0.467791859  5.651727316
## Iter: 2 fn: -188.2538     Pars:   0.002377139  0.654844900 -0.593020662  0.000002425  0.531197596  0.000009184  0.467793215  5.651653021
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 1 , 2 ) con ARMA( 1 , 1 ) y dist: std"
## 
## Iter: 1 fn: -188.2538     Pars:   0.0023771543  0.6548456425 -0.5930202897  0.0000024254  0.5312048674  0.4677946349  0.0000004804  5.6517625121
## Iter: 2 fn: -188.2538     Pars:   0.0023771525  0.6548465342 -0.5930212152  0.0000024254  0.5312046000  0.4677951173  0.0000002768  5.6517468907
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 2 , 2 ) con ARMA( 1 , 1 ) y dist: std"
## 
## Iter: 1 fn: -188.2538     Pars:   0.0023771562  0.6548425268 -0.5930210114  0.0000024254  0.5311981289  0.0000077655  0.4677938864  0.0000002213  5.6516767166
## Iter: 2 fn: -188.2538     Pars:   0.0023771456  0.6548445046 -0.5930210257  0.0000024254  0.5311991314  0.0000072929  0.4677933730  0.0000002059  5.6516578823
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 1 , 1 ) con ARMA( 0 , 0 ) y dist: ged"
## 
## Iter: 1 fn: -189.1210     Pars:  0.001971265 0.000002335 0.483675798 0.515324118 1.040844667
## Iter: 2 fn: -189.1210     Pars:  0.001971265 0.000002335 0.483675798 0.515324118 1.040844669
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 2 , 1 ) con ARMA( 0 , 0 ) y dist: ged"
## 
## Iter: 1 fn: -189.3734     Pars:  0.001971232 0.000002527 0.417567596 0.098380076 0.483052316 1.049971714
## Iter: 2 fn: -189.3734     Pars:  0.001971180 0.000002528 0.417605098 0.098346974 0.483047919 1.050041789
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 1 , 2 ) con ARMA( 0 , 0 ) y dist: ged"
## 
## Iter: 1 fn: -189.2950     Pars:  0.001971260 0.000002347 0.485622270 0.513376016 0.000001230 1.046648899
## Iter: 2 fn: -189.2950     Pars:  0.001971260 0.000002347 0.485622269 0.513376016 0.000001230 1.046648899
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 2 , 2 ) con ARMA( 0 , 0 ) y dist: ged"
## 
## Iter: 1 fn: -189.3734     Pars:  0.0019712096 0.0000025277 0.4176408932 0.0983181984 0.4830406299 0.0000002649 1.0501081827
## Iter: 2 fn: -189.3734     Pars:  0.0019712095 0.0000025277 0.4176409017 0.0983171148 0.4830417838 0.0000001925 1.0501069142
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 1 , 1 ) con ARMA( 1 , 0 ) y dist: ged"
## 
## Iter: 1 fn: -188.9863     Pars:   0.001589629 -0.007117328  0.000002351  0.473838486  0.524760165  0.968349398
## Iter: 2 fn: -188.9863     Pars:   0.001589629 -0.007117341  0.000002351  0.473838492  0.524760159  0.968349392
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 2 , 1 ) con ARMA( 1 , 0 ) y dist: ged"
## 
## Iter: 1 fn: -189.3788     Pars:   0.001967366 -0.003062961  0.000002523  0.416148388  0.099680370  0.483171182  1.048531610
## Iter: 2 fn: -189.3788     Pars:   0.001967356 -0.003063013  0.000002523  0.416148863  0.099677779  0.483173300  1.048526577
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 1 , 2 ) con ARMA( 1 , 0 ) y dist: ged"
## 
## Iter: 1 fn: -189.2941     Pars:  0.0019722389 0.0008373511 0.0000023491 0.4857252495 0.5132741860 0.0000004501 1.0472792531
## Iter: 2 fn: -189.2941     Pars:  0.001972239 0.000837351 0.000002349 0.485725244 0.513274192 0.000000450 1.047279159
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 2 , 2 ) con ARMA( 1 , 0 ) y dist: ged"
## 
## Iter: 1 fn: -189.3787     Pars:   0.001967397 -0.003062669  0.000002523  0.416165975  0.099630496  0.483195822  0.000007158  1.048556679
## Iter: 2 fn: -189.3787     Pars:   0.001967397 -0.003062575  0.000002523  0.416165990  0.099630468  0.483195852  0.000007143  1.048556516
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 1 , 1 ) con ARMA( 0 , 1 ) y dist: ged"
## 
## Iter: 1 fn: -172.9187     Pars:  0.000827485 0.116472194 0.000001592 0.070742847 0.842103505 0.681581595
## Iter: 2 fn: -172.9187     Pars:  0.000827485 0.116472194 0.000001592 0.070742847 0.842103505 0.681581595
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 2 , 1 ) con ARMA( 0 , 1 ) y dist: ged"
## 
## Iter: 1 fn: -189.3788     Pars:   0.001967384 -0.003066208  0.000002525  0.416036610  0.099747522  0.483213347  1.048572918
## Iter: 2 fn: -189.3788     Pars:   0.001967384 -0.003066214  0.000002525  0.416036566  0.099747570  0.483213343  1.048572928
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 1 , 2 ) con ARMA( 0 , 1 ) y dist: ged"
## 
## Iter: 1 fn: -189.2981     Pars:   0.00196751979 -0.00306477754  0.00000235660  0.48570635326  0.51329358420  0.00000006714  1.04487251755
## Iter: 2 fn: -189.2981     Pars:   0.00196751979 -0.00306478440  0.00000235502  0.48565773372  0.51334220373  0.00000006714  1.04489500417
## Iter: 3 fn: -189.2981     Pars:   0.00196751984 -0.00306476350  0.00000235432  0.48563639614  0.51336354131  0.00000006714  1.04490597334
## solnp--> Completed in 3 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 2 , 2 ) con ARMA( 0 , 1 ) y dist: ged"
## 
## Iter: 1 fn: -189.3788     Pars:   0.0019672157 -0.0030679702  0.0000025231  0.4161503245  0.0996481176  0.4832007153  0.0000007714  1.0485059535
## Iter: 2 fn: -189.3788     Pars:   0.0019672035 -0.0030681418  0.0000025231  0.4161506965  0.0996478633  0.4832006221  0.0000007491  1.0485032840
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 1 , 1 ) con ARMA( 1 , 1 ) y dist: ged"
## 
## Iter: 1 fn: -189.1480     Pars:   0.001972959  0.654754114 -0.646093922  0.000002353  0.484596910  0.514402944  1.038805333
## Iter: 2 fn: -189.1480     Pars:   0.001973154  0.654836712 -0.646197353  0.000002353  0.484553545  0.514446398  1.038723744
## Iter: 3 fn: -189.1480     Pars:   0.001973153  0.654839555 -0.646200216  0.000002353  0.484553574  0.514446369  1.038723731
## solnp--> Completed in 3 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 2 , 1 ) con ARMA( 1 , 1 ) y dist: ged"
## 
## Iter: 1 fn: -189.3794     Pars:   0.001966600  0.106126544 -0.109312385  0.000002523  0.415768873  0.100102319  0.483128812  1.048629999
## Iter: 2 fn: -189.3794     Pars:   0.001966600  0.106109969 -0.109295576  0.000002523  0.415769030  0.100101860  0.483129115  1.048629436
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 1 , 2 ) con ARMA( 1 , 1 ) y dist: ged"
## 
## Iter: 1 fn: -189.3225     Pars:   0.0019817018  0.6223728518 -0.6128319922  0.0000023671  0.4870239238  0.5119758789  0.0000001651  1.0469384594
## Iter: 2 fn: -189.3225     Pars:   0.0019816995  0.6223196236 -0.6127770754  0.0000023671  0.4870233849  0.5119764934  0.0000001028  1.0469328814
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## [1] "Ajustando GARCH( 2 , 2 ) con ARMA( 1 , 1 ) y dist: ged"
## 
## Iter: 1 fn: -189.3893     Pars:   0.001973650  0.639386163 -0.632665015  0.000002529  0.423852110  0.090624740  0.484520088  0.000002777  1.047549148
## Iter: 2 fn: -189.3893     Pars:   0.00197365  0.63942659 -0.63270649  0.00000253  0.42389628  0.09058465  0.48451632  0.00000249  1.04755085
## solnp--> Completed in 2 iterations
## [1] "El modelo convergió correctamente."
## Warning: There were 48 warnings in `mutate()`.
## The first warning was:
## ℹ In argument: `results = pmap(...)`.
## Caused by warning in `.sgarchfit()`:
## ! 
## ugarchfit-->waring: using less than 100 data
##  points for estimation
## ℹ Run `dplyr::last_dplyr_warnings()` to see the 47 remaining warnings.
# Verificar el contenido de simulation_results
print("Contenido de simulation_results:")
## [1] "Contenido de simulation_results:"
print(head(simulation_results))
## # A tibble: 6 × 7
##   garch_p garch_q arma_p arma_q dist  results          within_range
##     <int>   <int>  <int>  <int> <chr> <list>                  <dbl>
## 1       1       1      0      0 norm  <named list [1]>            8
## 2       2       1      0      0 norm  <named list [1]>            7
## 3       1       2      0      0 norm  <named list [1]>            5
## 4       2       2      0      0 norm  <named list [1]>            9
## 5       1       1      1      0 norm  <named list [1]>            6
## 6       2       1      1      0 norm  <named list [1]>            9
# Contar valores no NA en within_range
num_validos <- sum(!is.na(simulation_results$within_range))
print(paste("Número de modelos con within_range válido:", num_validos))
## [1] "Número de modelos con within_range válido: 48"
# Filtrar modelos con resultados válidos
simulation_results_validos <- simulation_results %>% filter(!is.na(within_range))

# Ordenar los resultados de mayor a menor según within_range
simulation_results_ordenados <- simulation_results_validos %>%
    arrange(desc(within_range))

# Seleccionar los 3 modelos con mejor desempeño
top_3_models <- simulation_results_ordenados %>%
    head(3)

# Imprimir los resultados de las simulaciones
if (nrow(simulation_results_validos) > 0) {
    print("Número de simulaciones dentro del rango del 5% para cada combinación probada:")
    print(simulation_results_validos)
    
    # Imprimir los 3 mejores modelos
    print("Los 3 modelos con mejor desempeño son:")
    print(top_3_models)
} else {
    print("No se encontraron modelos con resultados válidos.")
}
## [1] "Número de simulaciones dentro del rango del 5% para cada combinación probada:"
## # A tibble: 48 × 7
##    garch_p garch_q arma_p arma_q dist  results          within_range
##      <int>   <int>  <int>  <int> <chr> <list>                  <dbl>
##  1       1       1      0      0 norm  <named list [1]>            8
##  2       2       1      0      0 norm  <named list [1]>            7
##  3       1       2      0      0 norm  <named list [1]>            5
##  4       2       2      0      0 norm  <named list [1]>            9
##  5       1       1      1      0 norm  <named list [1]>            6
##  6       2       1      1      0 norm  <named list [1]>            9
##  7       1       2      1      0 norm  <named list [1]>            7
##  8       2       2      1      0 norm  <named list [1]>            5
##  9       1       1      0      1 norm  <named list [1]>            6
## 10       2       1      0      1 norm  <named list [1]>           11
## # ℹ 38 more rows
## [1] "Los 3 modelos con mejor desempeño son:"
## # A tibble: 3 × 7
##   garch_p garch_q arma_p arma_q dist  results          within_range
##     <int>   <int>  <int>  <int> <chr> <list>                  <dbl>
## 1       2       1      0      1 norm  <named list [1]>           11
## 2       2       2      0      0 norm  <named list [1]>            9
## 3       2       1      1      0 norm  <named list [1]>            9