#Cargar librerías necesarias
library(readxl)  # Para leer archivos Excel
library(tseries)  # Para pruebas de estacionariedad
## Warning: package 'tseries' was built under R version 4.4.3
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
library(forecast)  # Para modelado ARIMA y pronósticos
## Warning: package 'forecast' was built under R version 4.4.3
library(ggplot2)  # Para visualización de datos
library(plotly)  # Para gráficos interactivos
## Warning: package 'plotly' was built under R version 4.4.3
## 
## Adjuntando el paquete: 'plotly'
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## The following object is masked from 'package:stats':
## 
##     filter
## The following object is masked from 'package:graphics':
## 
##     layout
library(timetk) 
## Warning: package 'timetk' was built under R version 4.4.3
library(readxl) 
data_col <- read_excel("C:/Users/usuario/Downloads/data_col.xlsx",  col_types = c("date", "numeric", "numeric"))
## Warning: Expecting numeric in B2 / R2C2: got '1.396,35'
## Warning: Coercing text to numeric in C2 / R2C3: '1396.35'
## Warning: Expecting numeric in B3 / R3C2: got '1.306,62'
## Warning: Coercing text to numeric in C3 / R3C3: '1306.62'
## Warning: Expecting numeric in B4 / R4C2: got '1.331,35'
## Warning: Coercing text to numeric in C4 / R4C3: '1331.35'
## Warning: Expecting numeric in B5 / R5C2: got '1.317,24'
## Warning: Coercing text to numeric in C5 / R5C3: '1317.24'
## Warning: Expecting numeric in B6 / R6C2: got '1.246,59'
## Warning: Coercing text to numeric in C6 / R6C3: '1246.59'
## Warning: Expecting numeric in B7 / R7C2: got '1.218,82'
## Warning: Coercing text to numeric in C7 / R7C3: '1218.82'
## Warning: Expecting numeric in B8 / R8C2: got '1.218,13'
## Warning: Coercing text to numeric in C8 / R8C3: '1218.13'
## Warning: Expecting numeric in B9 / R9C2: got '1.114,36'
## Warning: Coercing text to numeric in C9 / R9C3: '1114.36'
## Warning: Expecting numeric in B10 / R10C2: got '1.153,71'
## Warning: Coercing text to numeric in C10 / R10C3: '1153.71'
## Warning: Expecting numeric in B11 / R11C2: got '1.175,09'
## Warning: Coercing text to numeric in C11 / R11C3: '1175.09'
## Warning: Expecting numeric in B12 / R12C2: got '1.244,17'
## Warning: Coercing text to numeric in C12 / R12C3: '1244.17'
## Warning: Expecting numeric in B13 / R13C2: got '1.336,27'
## Warning: Coercing text to numeric in C13 / R13C3: '1336.27'
## Warning: Expecting numeric in B14 / R14C2: got '1.342,42'
## Warning: Coercing text to numeric in C14 / R14C3: '1342.42'
## Warning: Expecting numeric in B15 / R15C2: got '1.292,51'
## Warning: Coercing text to numeric in C15 / R15C3: '1292.51'
## Warning: Expecting numeric in B16 / R16C2: got '1.313,18'
## Warning: Coercing text to numeric in C16 / R16C3: '1313.18'
## Warning: Expecting numeric in B17 / R17C2: got '1.308,22'
## Warning: Coercing text to numeric in C17 / R17C3: '1308.22'
## Warning: Expecting numeric in B18 / R18C2: got '1.380,18'
## Warning: Coercing text to numeric in C18 / R18C3: '1380.18'
## Warning: Expecting numeric in B19 / R19C2: got '1.338,83'
## Warning: Coercing text to numeric in C19 / R19C3: '1338.83'
## Warning: Expecting numeric in B20 / R20C2: got '1.365,53'
## Warning: Coercing text to numeric in C20 / R20C3: '1365.53'
## Warning: Expecting numeric in B21 / R21C2: got '1.286,07'
## Warning: Coercing text to numeric in C21 / R21C3: '1286.07'
## Warning: Expecting numeric in B22 / R22C2: got '1.351,68'
## Warning: Coercing text to numeric in C22 / R22C3: '1351.68'
## Warning: Expecting numeric in B23 / R23C2: got '1.357,47'
## Warning: Coercing text to numeric in C23 / R23C3: '1357.47'
## Warning: Expecting numeric in B24 / R24C2: got '1.326,31'
## Warning: Coercing text to numeric in C24 / R24C3: '1326.31'
## Warning: Expecting numeric in B25 / R25C2: got '1.365,61'
## Warning: Coercing text to numeric in C25 / R25C3: '1365.61'
## Warning: Expecting numeric in B26 / R26C2: got '1.371,54'
## Warning: Coercing text to numeric in C26 / R26C3: '1371.54'
## Warning: Expecting numeric in B27 / R27C2: got '1.439,48'
## Warning: Coercing text to numeric in C27 / R27C3: '1439.48'
## Warning: Expecting numeric in B28 / R28C2: got '1.462,90'
## Warning: Coercing text to numeric in C28 / R28C3: '1462.90'
## Warning: Expecting numeric in B29 / R29C2: got '1.481,37'
## Warning: Coercing text to numeric in C29 / R29C3: '1481.37'
## Warning: Expecting numeric in B30 / R30C2: got '1.482,27'
## Warning: Coercing text to numeric in C30 / R30C3: '1482.27'
## Warning: Expecting numeric in B31 / R31C2: got '1.487,52'
## Warning: Coercing text to numeric in C31 / R31C3: '1487.52'
## Warning: Expecting numeric in B32 / R32C2: got '1.424,58'
## Warning: Coercing text to numeric in C32 / R32C3: '1424.58'
## Warning: Expecting numeric in B33 / R33C2: got '1.445,23'
## Warning: Coercing text to numeric in C33 / R33C3: '1445.23'
## Warning: Expecting numeric in B34 / R34C2: got '1.513,65'
## Warning: Coercing text to numeric in C34 / R34C3: '1513.65'
## Warning: Expecting numeric in B35 / R35C2: got '1.558,18'
## Warning: Coercing text to numeric in C35 / R35C3: '1558.18'
## Warning: Expecting numeric in B36 / R36C2: got '1.478,33'
## Warning: Coercing text to numeric in C36 / R36C3: '1478.33'
## Warning: Expecting numeric in B37 / R37C2: got '1.455,52'
## Warning: Coercing text to numeric in C37 / R37C3: '1455.52'
## Warning: Expecting numeric in B38 / R38C2: got '1.565,56'
## Warning: Coercing text to numeric in C38 / R38C3: '1565.56'
## Warning: Expecting numeric in B39 / R39C2: got '1.546,71'
## Warning: Coercing text to numeric in C39 / R39C3: '1546.71'
## Warning: Expecting numeric in B40 / R40C2: got '1.577,01'
## Warning: Coercing text to numeric in C40 / R40C3: '1577.01'
## Warning: Expecting numeric in B41 / R41C2: got '1.526,60'
## Warning: Coercing text to numeric in C41 / R41C3: '1526.60'
## Warning: Expecting numeric in B42 / R42C2: got '1.542,77'
## Warning: Coercing text to numeric in C42 / R42C3: '1542.77'
## Warning: Expecting numeric in B43 / R43C2: got '1.506,07'
## Warning: Coercing text to numeric in C43 / R43C3: '1506.07'
## Warning: Expecting numeric in B44 / R44C2: got '1.392,18'
## Warning: Coercing text to numeric in C44 / R44C3: '1392.18'
## Warning: Expecting numeric in B45 / R45C2: got '1.379,24'
## Warning: Coercing text to numeric in C45 / R45C3: '1379.24'
## Warning: Expecting numeric in B46 / R46C2: got '1.325,93'
## Warning: Coercing text to numeric in C46 / R46C3: '1325.93'
## Warning: Expecting numeric in B47 / R47C2: got '1.447,01'
## Warning: Coercing text to numeric in C47 / R47C3: '1447.01'
## Warning: Expecting numeric in B48 / R48C2: got '1.508,27'
## Warning: Coercing text to numeric in C48 / R48C3: '1508.27'
## Warning: Expecting numeric in B49 / R49C2: got '1.587,74'
## Warning: Coercing text to numeric in C49 / R49C3: '1587.74'
## Warning: Expecting numeric in B50 / R50C2: got '1.573,64'
## Warning: Coercing text to numeric in C50 / R50C3: '1573.64'
## Warning: Expecting numeric in B51 / R51C2: got '1.487,00'
## Warning: Coercing text to numeric in C51 / R51C3: '1487.00'
## Warning: Expecting numeric in B52 / R52C2: got '1.548,98'
## Warning: Coercing text to numeric in C52 / R52C3: '1548.98'
## Warning: Expecting numeric in B53 / R53C2: got '1.562,13'
## Warning: Coercing text to numeric in C53 / R53C3: '1562.13'
## Warning: Expecting numeric in B54 / R54C2: got '1.559,52'
## Warning: Coercing text to numeric in C54 / R54C3: '1559.52'
## Warning: Expecting numeric in B55 / R55C2: got '1.577,96'
## Warning: Coercing text to numeric in C55 / R55C3: '1577.96'
## Warning: Expecting numeric in B56 / R56C2: got '1.633,15'
## Warning: Coercing text to numeric in C56 / R56C3: '1633.15'
## Warning: Expecting numeric in B57 / R57C2: got '1.611,92'
## Warning: Coercing text to numeric in C57 / R57C3: '1611.92'
## Warning: Expecting numeric in B58 / R58C2: got '1.662,42'
## Warning: Coercing text to numeric in C58 / R58C3: '1662.42'
## Warning: Expecting numeric in B59 / R59C2: got '1.623,83'
## Warning: Coercing text to numeric in C59 / R59C3: '1623.83'
## Warning: Expecting numeric in B60 / R60C2: got '1.549,61'
## Warning: Coercing text to numeric in C60 / R60C3: '1549.61'
## Warning: Expecting numeric in B61 / R61C2: got '1.123,85'
## Warning: Coercing text to numeric in C61 / R61C3: '1123.85'
## Warning: Expecting numeric in B62 / R62C2: got '1.142,04'
## Warning: Coercing text to numeric in C62 / R62C3: '1142.04'
## Warning: Expecting numeric in B63 / R63C2: got '1.095,84'
## Warning: Coercing text to numeric in C63 / R63C3: '1095.84'
## Warning: Expecting numeric in B64 / R64C2: got '1.111,80'
## Warning: Coercing text to numeric in C64 / R64C3: '1111.80'
## Warning: Expecting numeric in B65 / R65C2: got '1.134,34'
## Warning: Coercing text to numeric in C65 / R65C3: '1134.34'
## Warning: Expecting numeric in B66 / R66C2: got '1.216,03'
## Warning: Coercing text to numeric in C66 / R66C3: '1216.03'
## Warning: Expecting numeric in B67 / R67C2: got '1.171,92'
## Warning: Coercing text to numeric in C67 / R67C3: '1171.92'
## Warning: Expecting numeric in B68 / R68C2: got '1.136,75'
## Warning: Coercing text to numeric in C68 / R68C3: '1136.75'
## Warning: Expecting numeric in B69 / R69C2: got '1.258,00'
## Warning: Coercing text to numeric in C69 / R69C3: '1258.00'
## Warning: Expecting numeric in B70 / R70C2: got '1.437,89'
## Warning: Coercing text to numeric in C70 / R70C3: '1437.89'
## Warning: Expecting numeric in B71 / R71C2: got '1.348,12'
## Warning: Coercing text to numeric in C71 / R71C3: '1348.12'
## Warning: Expecting numeric in B72 / R72C2: got '1.359,48'
## Warning: Coercing text to numeric in C72 / R72C3: '1359.48'
## Warning: Expecting numeric in B73 / R73C2: got '1.316,81'
## Warning: Coercing text to numeric in C73 / R73C3: '1316.81'
## Warning: Expecting numeric in B74 / R74C2: got '1.250,65'
## Warning: Coercing text to numeric in C74 / R74C3: '1250.65'
## Warning: Expecting numeric in B75 / R75C2: got '1.200,90'
## Warning: Coercing text to numeric in C75 / R75C3: '1200.90'
## Warning: Expecting numeric in B76 / R76C2: got '1.248,83'
## Warning: Coercing text to numeric in C76 / R76C3: '1248.83'
## Warning: Expecting numeric in B77 / R77C2: got '1.236,73'
## Warning: Coercing text to numeric in C77 / R77C3: '1236.73'
## Warning: Expecting numeric in B78 / R78C2: got '1.319,96'
## Warning: Coercing text to numeric in C78 / R78C3: '1319.96'
## Warning: Expecting numeric in B79 / R79C2: got '1.361,95'
## Warning: Coercing text to numeric in C79 / R79C3: '1361.95'
## Warning: Expecting numeric in B80 / R80C2: got '1.394,04'
## Warning: Coercing text to numeric in C80 / R80C3: '1394.04'
## Warning: Expecting numeric in B81 / R81C2: got '1.373,84'
## Warning: Coercing text to numeric in C81 / R81C3: '1373.84'
## Warning: Expecting numeric in B82 / R82C2: got '1.410,97'
## Warning: Coercing text to numeric in C82 / R82C3: '1410.97'
## Warning: Expecting numeric in B83 / R83C2: got '1.536,92'
## Warning: Coercing text to numeric in C83 / R83C3: '1536.92'
## Warning: Expecting numeric in B84 / R84C2: got '1.527,75'
## Warning: Coercing text to numeric in C84 / R84C3: '1527.75'
## Warning: Expecting numeric in B85 / R85C2: got '1.616,08'
## Warning: Coercing text to numeric in C85 / R85C3: '1616.08'
## Warning: Expecting numeric in B86 / R86C2: got '1.562,46'
## Warning: Coercing text to numeric in C86 / R86C3: '1562.46'
## Warning: Expecting numeric in B87 / R87C2: got '1.603,23'
## Warning: Coercing text to numeric in C87 / R87C3: '1603.23'
## Warning: Expecting numeric in B88 / R88C2: got '1.322,88'
## Warning: Coercing text to numeric in C88 / R88C3: '1322.88'
## Warning: Expecting numeric in B89 / R89C2: got '1.295,96'
## Warning: Coercing text to numeric in C89 / R89C3: '1295.96'
## Warning: Expecting numeric in B90 / R90C2: got '1.228,33'
## Warning: Coercing text to numeric in C90 / R90C3: '1228.33'
## Warning: Expecting numeric in B91 / R91C2: got '1.128,24'
## Warning: Coercing text to numeric in C91 / R91C3: '1128.24'
## Warning: Expecting numeric in B92 / R92C2: got '1.231,52'
## Warning: Coercing text to numeric in C92 / R92C3: '1231.52'
## Warning: Expecting numeric in B93 / R93C2: got '1.242,63'
## Warning: Coercing text to numeric in C93 / R93C3: '1242.63'
## Warning: Expecting numeric in B94 / R94C2: got '1.286,07'
## Warning: Coercing text to numeric in C94 / R94C3: '1286.07'
## Warning: Expecting numeric in B95 / R95C2: got '1.290,11'
## Warning: Coercing text to numeric in C95 / R95C3: '1290.11'
## Warning: Expecting numeric in B96 / R96C2: got '1.187,56'
## Warning: Coercing text to numeric in C96 / R96C3: '1187.56'
## Warning: Expecting numeric in B97 / R97C2: got '1.157,59'
## Warning: Coercing text to numeric in C97 / R97C3: '1157.59'
## Warning: Expecting numeric in B98 / R98C2: got '1.198,81'
## Warning: Coercing text to numeric in C98 / R98C3: '1198.81'
## Warning: Expecting numeric in B99 / R99C2: got '1.099,03'
## Warning: Coercing text to numeric in C99 / R99C3: '1099.03'
## Warning: Expecting numeric in B100 / R100C2: got '1.133,60'
## Warning: Coercing text to numeric in C100 / R100C3: '1133.60'
## Warning: Expecting numeric in B101 / R101C2: got '1.174,70'
## Warning: Coercing text to numeric in C101 / R101C3: '1174.70'
## Warning: Expecting numeric in B102 / R102C2: got '1.076,12'
## Warning: Coercing text to numeric in C102 / R102C3: '1076.12'
## Warning: Expecting numeric in B103 / R103C2: got '1.121,64'
## Warning: Coercing text to numeric in C103 / R103C3: '1121.64'
## Warning: Expecting numeric in B104 / R104C2: got '1.088,15'
## Warning: Coercing text to numeric in C104 / R104C3: '1088.15'
## Warning: Expecting numeric in B105 / R105C2: got '1.146,87'
## Warning: Coercing text to numeric in C105 / R105C3: '1146.87'
## Warning: Expecting numeric in B106 / R106C2: got '1.195,20'
## Warning: Coercing text to numeric in C106 / R106C3: '1195.20'
## Warning: Expecting numeric in B107 / R107C2: got '1.276,55'
## Warning: Coercing text to numeric in C107 / R107C3: '1276.55'
## Warning: Expecting numeric in B108 / R108C2: got '1.274,08'
## Warning: Coercing text to numeric in C108 / R108C3: '1274.08'
## Warning: Expecting numeric in B109 / R109C2: got '1.332,76'
## Warning: Coercing text to numeric in C109 / R109C3: '1332.76'
## Warning: Expecting numeric in B110 / R110C2: got '1.368,46'
## Warning: Coercing text to numeric in C110 / R110C3: '1368.46'
## Warning: Expecting numeric in B111 / R111C2: got '1.399,72'
## Warning: Coercing text to numeric in C111 / R111C3: '1399.72'
## Warning: Expecting numeric in B112 / R112C2: got '1.382,29'
## Warning: Coercing text to numeric in C112 / R112C3: '1382.29'
## Warning: Expecting numeric in B113 / R113C2: got '1.348,69'
## Warning: Coercing text to numeric in C113 / R113C3: '1348.69'
## Warning: Expecting numeric in B114 / R114C2: got '1.339,79'
## Warning: Coercing text to numeric in C114 / R114C3: '1339.79'
## Warning: Expecting numeric in B115 / R115C2: got '1.307,59'
## Warning: Coercing text to numeric in C115 / R115C3: '1307.59'
## Warning: Expecting numeric in B116 / R116C2: got '1.358,46'
## Warning: Coercing text to numeric in C116 / R116C3: '1358.46'
## Warning: Expecting numeric in B117 / R117C2: got '1.392,13'
## Warning: Coercing text to numeric in C117 / R117C3: '1392.13'
## Warning: Expecting numeric in B118 / R118C2: got '1.379,58'
## Warning: Coercing text to numeric in C118 / R118C3: '1379.58'
## Warning: Expecting numeric in B119 / R119C2: got '1.521,74'
## Warning: Coercing text to numeric in C119 / R119C3: '1521.74'
## Warning: Expecting numeric in B120 / R120C2: got '1.607,57'
## Warning: Coercing text to numeric in C120 / R120C3: '1607.57'
## Warning: Expecting numeric in B121 / R121C2: got '1.619,38'
## Warning: Coercing text to numeric in C121 / R121C3: '1619.38'
View(data_col)
variable1_ts <- ts(data_col$COLCAP, start = c(2015, 1), frequency = 12)
variable1_ts
##          Jan     Feb     Mar     Apr     May     Jun     Jul     Aug     Sep
## 2015 1396.35 1306.62 1331.35 1317.24 1246.59 1218.82 1218.13 1114.36 1153.71
## 2016 1342.42 1292.51 1313.18 1308.22 1380.18 1338.83 1365.53 1286.07 1351.68
## 2017 1371.54 1439.48 1462.90 1481.37 1482.27 1487.52 1424.58 1445.23 1513.65
## 2018 1565.56 1546.71 1577.01 1526.60 1542.77 1506.07 1392.18 1379.24 1325.93
## 2019 1573.64 1487.00 1548.98 1562.13 1559.52 1577.96 1633.15 1611.92 1662.42
## 2020 1142.04 1095.84 1111.80 1134.34 1216.03 1171.92 1136.75 1258.00 1437.89
## 2021 1250.65 1200.90 1248.83 1236.73 1319.96 1361.95 1394.04 1373.84 1410.97
## 2022 1562.46 1603.23 1322.88 1295.96 1228.33 1128.24 1231.52 1242.63 1286.07
## 2023 1198.81 1099.03 1133.60 1174.70 1076.12 1121.64 1088.15 1146.87 1195.20
## 2024 1368.46 1399.72 1382.29 1348.69 1339.79 1307.59 1358.46 1392.13 1379.58
##          Oct     Nov     Dec
## 2015 1175.09 1244.17 1336.27
## 2016 1357.47 1326.31 1365.61
## 2017 1558.18 1478.33 1455.52
## 2018 1447.01 1508.27 1587.74
## 2019 1623.83 1549.61 1123.85
## 2020 1348.12 1359.48 1316.81
## 2021 1536.92 1527.75 1616.08
## 2022 1290.11 1187.56 1157.59
## 2023 1276.55 1274.08 1332.76
## 2024 1521.74 1607.57 1619.38
library(ggplot2)
library(plotly)

# Convertir la serie temporal a un vector numérico para lograr graficar con ggplot2
data_col$variable1 <- as.numeric(variable1_ts)

# Crear el gráfico
grafico_serie <- ggplot(data_col, aes(x = seq.Date(from = as.Date("2015-01-01"), by = "month", length.out = nrow(data_col)), 
                                      y = variable1)) +
  geom_line(color = "grey", linewidth = 0.4) +  # Cambiado 'size' por 'linewidth'
  geom_point(color = "black", size = 0.1) +
  ggtitle("Variable 1: Serie original") +
  xlab("Tiempo") +
  ylab("Unidad Variable 1") +
  theme_minimal()

ggplotly(grafico_serie)

La serie original del índice COLCAP en frecuencia mensual desde 2015 hasta 2025 muestra una tendencia creciente a largo plazo, aunque con caídas significativas, especialmente en 2020 debido al impacto de la pandemia de COVID-19. A pesar de estos descensos, la serie ha mostrado una recuperación progresiva en los últimos años. No se evidencia una estacionalidad marcada, aunque podrían existir patrones cíclicos que requieren un análisis más profundo. La alta volatilidad del índice refleja su sensibilidad a eventos macroeconómicos y políticos, con fluctuaciones abruptas típicas de los mercados bursátiles.

# Cargar librerías necesarias
library(ggplot2)
library(plotly)

# Descomposición de la serie temporal
stl_decomp_var1 <- stl(variable1_ts, s.window = "periodic")

# Convertir la descomposición a un data frame para graficar con ggplot2
stl_df_var1 <- data.frame(
  Time = rep(time(variable1_ts), 4),  # Tiempo repetido para cada componente (son 4 componentes)
  Value = c(stl_decomp_var1$time.series[, "seasonal"], 
            stl_decomp_var1$time.series[, "trend"], 
            stl_decomp_var1$time.series[, "remainder"], 
            variable1_ts),
  Component = rep(c("Estacional", "Tendencia", "Residuo", "Serie Original"), each = length(variable1_ts))
)

# Crear gráfico con ggplot2
p <- ggplot(stl_df_var1, aes(x = Time, y = Value, color = Component)) +
  geom_line() +
  facet_wrap(~Component, scales = "free_y", ncol = 1) + 
  theme_minimal() +
  labs(title = "Descomposición temporal de la variable 1",
       x = "Tiempo",
       y = "Valor")

# Convertir a gráfico interactivo con plotly
ggplotly(p)

La descomposición del índice COLCAP revela tres componentes principales: tendencia, estacionalidad y residuo. La tendencia muestra un crecimiento hasta 2020, seguido de una fuerte caída y una recuperación posterior con variaciones ondulantes. El componente estacional presenta patrones anuales de baja amplitud, posiblemente ligados a ciclos económicos y reportes corporativos. Por otro lado, el residuo exhibe una alta volatilidad con picos abruptos, reflejando choques externos y eventos impredecibles que afectan el índice. En conjunto, la serie temporal muestra una estructura dominada por su tendencia y la presencia de eventos exógenos más que por una estacionalidad fuerte.

# Extraer los componentes de la descomposición
variable1_sa <- variable1_ts - stl_decomp_var1$time.series[, "seasonal"]
# Crear vector de fechas correctamente alineado con la serie
fechas_var1 <- seq.Date(from = as.Date("2015-01-01"), by = "month", length.out = length(variable1_ts))

# Gráfico mejorado con fechas en el eje X
grafico_ajustada_var1 <- ggplot() +
  geom_line(aes(x = fechas_var1, y = variable1_ts), color = "grey", size = 0.5, linetype = "solid", name = "Serie Original") +
  geom_line(aes(x = fechas_var1, y = variable1_sa), color = "black", size = 0.6, linetype = "solid", name = "Serie Ajustada") +
  ggtitle("Variable 1:Serie Original vs Serie Ajustada por Estacionalidad") +
  xlab("Tiempo") +
  ylab("Unidad de medida variable 1") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) # Rotar etiquetas para mejor visualización
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## Warning in geom_line(aes(x = fechas_var1, y = variable1_ts), color = "grey", :
## Ignoring unknown parameters: `name`
## Warning in geom_line(aes(x = fechas_var1, y = variable1_sa), color = "black", :
## Ignoring unknown parameters: `name`
# Convertir a gráfico interactivo
ggplotly(grafico_ajustada_var1)
## Don't know how to automatically pick scale for object of type <ts>. Defaulting
## to continuous.

Al comparar la serie original del COLCAP con su versión ajustada por estacionalidad, se observa que las diferencias entre ambas son mínimas, lo que indica que la estacionalidad no es un factor predominante en su comportamiento. La serie ajustada conserva la misma tendencia y las principales fluctuaciones, sugiriendo que los movimientos del índice están más influenciados por choques externos que por patrones cíclicos recurrentes. Para la predicción del índice, trabajar con la serie ajustada podría mejorar la precisión de los modelos econométricos, dado que elimina variaciones periódicas que no afectan significativamente su trayectoria.

library(ggplot2)
library(plotly)

# Convertir la serie a un vector numérico
variable1_vec <- as.numeric(variable1_ts)
tendencia_var1 <- as.numeric(stl_decomp_var1$time.series[, "trend"])

# Asegurar que 'fechas' tenga la misma longitud
fechas <- seq.Date(from = as.Date("2015-01-01"), by = "month", length.out = length(variable1_ts))

# Gráfico interactivo de la serie original vs tendencia
grafico_tendencia_var1 <- ggplot() +
  geom_line(aes(x = fechas, y = variable1_vec, color = "Serie Original"), size = 0.7, linetype = "solid") +
  geom_line(aes(x = fechas, y = tendencia_var1, color = "Tendencia"), size = 0.8, linetype = "solid") +
  scale_color_manual(values = c("Serie Original" = "grey", "Tendencia" = "black")) +
  ggtitle("Variable 1: Serie Original vs Tendencia") +
  xlab("Tiempo") +
  ylab("Unidad de medida Variable 1") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) # Rotar etiquetas del eje X

# Convertir a gráfico interactivo con plotly
ggplotly(grafico_tendencia_var1)

El análisis de la serie original en relación con su tendencia permite identificar el comportamiento estructural del COLCAP sin la interferencia de fluctuaciones de corto plazo. Se observan ciclos de mediano plazo, con fases alternas de crecimiento y corrección, y una caída pronunciada en 2020 debido a la crisis del COVID-19. Posteriormente, el índice se recupera con un crecimiento sostenido, aunque con cierta volatilidad. La ausencia de una brecha significativa entre la serie original y la tendencia refuerza la idea de que la estacionalidad no es determinante en el comportamiento del COLCAP, siendo más relevante el impacto de factores macroeconómicos y coyunturales

#Cálculo de la tasa de crecimiento anual correctamente alineada
tasa_crecimiento_var1 <- (variable1_ts[(13:length(variable1_ts))] / variable1_ts[1:(length(variable1_ts) - 12)] - 1) * 100
tasa_tendencia_var1 <- (tendencia_var1[(13:length(tendencia_var1))] / tendencia_var1[1:(length(tendencia_var1) - 12)] - 1) * 100

# Crear vector de fechas corregido, es decir que inicie desde enero 2013
fechas_corregidas_var1 <- seq(from = as.Date("2016-01-01"), by = "month", length.out = length(tasa_crecimiento_var1))

# Verificar longitudes
print(length(fechas_corregidas_var1))
## [1] 108
print(length(tasa_crecimiento_var1))
## [1] 108
print(length(tasa_tendencia_var1))
## [1] 108
library(ggplot2)
library(plotly)

# Gráfico de la tasa de crecimiento anual variable 1
grafico_crecimiento_var1 <- ggplot() +
  geom_line(aes(x = fechas_corregidas_var1, y = tasa_crecimiento_var1), color = "grey", size = 0.7) +
  geom_line(aes(x = fechas_corregidas_var1, y = tasa_tendencia_var1), color = "black", size = 0.8, linetype = "dashed") +
  ggtitle("Variable1: Tasa de crecimiento anual % de la serie Original y la tendencia") +
  xlab("Tiempo") +
  ylab("% de Crecimiento Anual") +
  theme_minimal()

# Convertir a gráfico interactivo
ggplotly(grafico_crecimiento_var1)

La tasa de crecimiento anual del índice COLCAP muestra una alta volatilidad, con períodos de expansión seguidos de caídas abruptas, reflejando su sensibilidad a factores externos como decisiones de política económica y crisis globales. La comparación con la tasa de crecimiento de su tendencia evidencia que, aunque la tendencia es más estable, sigue presentando un comportamiento cíclico. No se detecta una estacionalidad clara en la tasa de crecimiento, lo que sugiere que el índice responde principalmente a eventos macroeconómicos. Para modelar su comportamiento, enfoques como ARIMA, GARCH o modelos de cambio de régimen podrían capturar mejor su volatilidad y patrones de crecimiento

# Esta división idealmente podria se 80%-70% de los datos para entrenamiento y 20%-30% para prueba o test

# En este ejemplo el conjunto de entrenamiento es: Enero 2012-Septiembre 2024 y  el conjunto de prueba o test: noviembre 2024-diciembre 2024 

train_size <- length(variable1_ts) - 3 # Se deja fuera los últimos 3 valores para usarlos como set de prueba.
train_ts <- window(variable1_ts, end = c(2024, 9))  # Entrenamiento hasta septiembre 2024
test_ts <- window(variable1_ts, start = c(2024, 10))  # Prueba inicia desde oct2024
library(tseries)
# Prueba de estacionariedad con Augmented Dickey-Fuller (ADF)
adf_test <- adf.test(train_ts) #Se aplica el test ADF a la variable 1 (conjunto de entrenamiento)
print(adf_test) # se muestra el resultado del test
## 
##  Augmented Dickey-Fuller Test
## 
## data:  train_ts
## Dickey-Fuller = -3.1141, Lag order = 4, p-value = 0.114
## alternative hypothesis: stationary
#Se crea un nuevo objeto o variable que se llama train_diff, en donde se diferencia la variable 1 , una sola vez:
train_diff <- diff(train_ts, differences = 1) 
# Graficar la serie original en un gráfico separado
  p2 <- ggplot(data.frame(Tiempo = time(train_ts), variable1 = as.numeric(train_ts)), aes(x = Tiempo, y = variable1)) +
    geom_line(color = "black") +
    ggtitle("Variable 1:Serie Original") +
    xlab("Tiempo") + ylab("Gwh")
  
  ggplotly(p2)  # Convertir en gráfico interactivo
## Don't know how to automatically pick scale for object of type <ts>. Defaulting
## to continuous.
 # Graficar la serie diferenciada en un gráfico separado
  p3 <- ggplot(data.frame(Tiempo = time(train_ts)[-1], variable1_Diff = as.numeric(train_diff)), aes(x = Tiempo, y = variable1_Diff)) +
    geom_line(color = "orange") +
    ggtitle("variable 1:Serie Estacionaria (Una diferenciacion)") +
    xlab("Tiempo") + ylab("variable 1 diferenciada")
  
  ggplotly(p3)  # Convertir en gráfico interacti
# Si la serie no es estacionaria (p-valor > 0.05), aplicar diferenciación

train_diff_log <- diff(log(train_ts), differences = 1)
# Graficar la serie original en un gráfico separado
  p2 <- ggplot(data.frame(Tiempo = time(train_ts), variable1 = as.numeric(train_ts)), aes(x = Tiempo, y = variable1)) +
    geom_line(color = "black") +
    ggtitle("Variable1:Serie Original") +
    xlab("Tiempo") + ylab("Variable1")
  
  ggplotly(p2)  # Convertir en gráfico interactivo
## Don't know how to automatically pick scale for object of type <ts>. Defaulting
## to continuous.
 # Graficar la serie diferenciada en un gráfico separado
  
  p3 <- ggplot(data.frame(Tiempo = time(train_ts)[-1], micro_Diff = as.numeric(train_diff_log)), aes(x = Tiempo, y = micro_Diff)) +
    geom_line(color = "orange") +
    ggtitle("Variable1:Serie Estacionaria (Una diferenciacion en logaritmo)") +
    xlab("Tiempo") + ylab("Variable 1 diferenciada")
  
  ggplotly(p3)  # Convertir en gráfico interactivo
# Segunda prueba de estacionariedad sobre la serie diferenciada en niveles
  adf_test_diff <- adf.test(train_diff)
## Warning in adf.test(train_diff): p-value smaller than printed p-value
 print(adf_test_diff)
## 
##  Augmented Dickey-Fuller Test
## 
## data:  train_diff
## Dickey-Fuller = -5.8224, Lag order = 4, p-value = 0.01
## alternative hypothesis: stationary
# Segunda prueba de estacionariedad sobre la serie diferenciada en logaritmo
  adf_test_diff_log <- adf.test(train_diff_log)
## Warning in adf.test(train_diff_log): p-value smaller than printed p-value
  print(adf_test_diff_log)
## 
##  Augmented Dickey-Fuller Test
## 
## data:  train_diff_log
## Dickey-Fuller = -5.8578, Lag order = 4, p-value = 0.01
## alternative hypothesis: stationary
library(forecast)
# Graficar ACF y PACF
acf_plot <- ggAcf(train_diff_log, lag.max = 6) + ggtitle("Autocorrelation Function (ACF)-Determinar q")
pacf_plot <- ggPacf(train_diff_log, lag.max = 6) + ggtitle("Partial Autocorrelation Function (PACF)-Determinar p")

ggplotly(acf_plot)
ggplotly(pacf_plot)
# Cálculo manual de modelo ARIMA
manual_arima_model <- Arima(train_diff, order = c(4,1,4)) #Se va a estimar un modelo Arima de orden (4,1,4)
summary(manual_arima_model)
## Series: train_diff 
## ARIMA(4,1,4) 
## 
## Coefficients:
##           ar1      ar2      ar3     ar4      ma1     ma2     ma3      ma4
##       -0.2962  -0.4449  -0.6248  0.0069  -0.7057  0.3869  0.0496  -0.7306
## s.e.   0.5843   0.2385   0.4458  0.1093   0.5769  0.8278  0.8273   0.5766
## 
## sigma^2 = 5279:  log likelihood = -656.22
## AIC=1330.45   AICc=1332.16   BIC=1355.15
## 
## Training set error measures:
##                   ME     RMSE      MAE      MPE     MAPE      MASE
## Training set 2.89108 69.78019 50.95583 62.68932 182.1789 0.6232286
##                       ACF1
## Training set -0.0002250505
library(lmtest)
## Warning: package 'lmtest' was built under R version 4.4.3
## Cargando paquete requerido: zoo
## 
## Adjuntando el paquete: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
# Evaluar la significancia estadística de los coeficientes del modelo ARIMA
coeftest(manual_arima_model)
## 
## z test of coefficients:
## 
##       Estimate Std. Error z value Pr(>|z|)  
## ar1 -0.2962426  0.5842539 -0.5070  0.61212  
## ar2 -0.4449076  0.2385485 -1.8651  0.06217 .
## ar3 -0.6248301  0.4458247 -1.4015  0.16106  
## ar4  0.0069457  0.1092806  0.0636  0.94932  
## ma1 -0.7057431  0.5768531 -1.2234  0.22116  
## ma2  0.3868523  0.8278319  0.4673  0.64028  
## ma3  0.0495566  0.8272840  0.0599  0.95223  
## ma4 -0.7306388  0.5765587 -1.2672  0.20507  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
checkresiduals(manual_arima_model)

## 
##  Ljung-Box test
## 
## data:  Residuals from ARIMA(4,1,4)
## Q* = 15.521, df = 15, p-value = 0.4146
## 
## Model df: 8.   Total lags used: 23
#Aquí se crea el pronóstico con el modelo ARIMA manual y se guarda en una nueva riable u objeto "manual_forecast"
manual_forecast <- forecast(manual_arima_model, h = length(test_ts)) #Se generan tantos pronósticos como valores tenga el conjunto de prueba (test_ts).

# Crear dataframe para gráfico interactivo del pronóstico manual
manual_forecast_data <- data.frame(Tiempo = time(manual_forecast$mean), ## Extrae las fechas del pronóstico
                                   Pronostico = as.numeric(manual_forecast$mean), ## Valores pronosticados
                                   Observado = as.numeric(test_ts)) ## Valores reales de la serie

# Graficar pronóstico manual junto con los valores observados reales
p_manual <- ggplot(manual_forecast_data, aes(x = Tiempo)) +
  geom_line(aes(y = Pronostico, color = "Pronóstico Manual")) +
  geom_line(aes(y = Observado, color = "Observado")) +
  ggtitle("Variable1:Pronóstico Manual vs Observado") +
  xlab("Tiempo") + ylab("Variable1")

ggplotly(p_manual)
## Don't know how to automatically pick scale for object of type <ts>. Defaulting
## to continuous.
# Calcular métricas de evaluación del modelo manual
mae_manual <- mean(abs(manual_forecast$mean - test_ts), na.rm = TRUE)
rmse_manual <- sqrt(mean((manual_forecast$mean - test_ts)^2, na.rm = TRUE))

# Mostrar métricas de evaluación del modelo manual
cat("MAE Manual: ", mae_manual, "\n")
## MAE Manual:  1595.796
cat("RMSE Manual: ", rmse_manual, "\n")
## RMSE Manual:  1596.482
# Cargar librerías necesarias
library(forecast)
library(dplyr)
## 
## Adjuntando el paquete: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
# Generar pronóstico con el modelo ARIMA identificado
arima_forecast_manual <- forecast(manual_arima_model, h = length(test_ts))

# Crear un dataframe con los valores observados y pronosticados
forecast_table_manual <- data.frame(
  Tiempo = time(arima_forecast_manual$mean),  # Extraer las fechas del pronóstico
  Observado = as.numeric(test_ts),  # Valores reales
  Pronosticado = as.numeric(arima_forecast_manual$mean)  # Valores pronosticados
)

# Mostrar la tabla
print(forecast_table_manual)
##     Tiempo Observado Pronosticado
## 1 2024.750   1521.74    -8.053398
## 2 2024.833   1607.57   -25.480205
## 3 2024.917   1619.38    -5.163330
# Cargar librerías necesarias
library(forecast)

# Hacer un pronóstico para el siguiente mes (1 período adicional)
next_forecast_manual <- forecast(manual_arima_model, h = length(test_ts) + 1)

# Extraer el pronóstico del próximo mes
next_month_forecast_manual <- data.frame(
  Tiempo = time(next_forecast_manual$mean),  # Extraer la fecha del pronóstico
  Pronostico = as.numeric(next_forecast_manual$mean)  # Valor pronosticado
)

# Mostrar el pronóstico completo
print(next_month_forecast_manual)
##     Tiempo Pronostico
## 1 2024.750  -8.053398
## 2 2024.833 -25.480205
## 3 2024.917  -5.163330
## 4 2025.000  17.145594
# Extraer solo el valor del trimestre adicional (último de la tabla)
next_month <- tail(next_month_forecast_manual, 1)
print(paste("Pronóstico para enero 2025:", next_month$Tiempo, "=", next_month$Pronostico))
## [1] "Pronóstico para enero 2025: 2025 = 17.1455942729766"
# Pronosticar octubre de 2024
future_forecast_manual <- forecast(manual_arima_model, h = 1)

# Extraer el valor específico de marzo 2025
forecast_oct2024 <- future_forecast_manual$mean[1]
print(paste("Pronóstico para enero 2025:", forecast_oct2024))
## [1] "Pronóstico para enero 2025: -8.05339789615117"
library(forecast)

# Ajustar un modelo ARIMA automático sin estacionalidad, por eso se pone seasonal=FALSE
auto_arima_model_no_seasonal <- auto.arima(train_ts, seasonal = FALSE)

# Mostrar el modelo seleccionado
summary(auto_arima_model_no_seasonal)
## Series: train_ts 
## ARIMA(0,1,0) 
## 
## sigma^2 = 5533:  log likelihood = -664.47
## AIC=1330.93   AICc=1330.97   BIC=1333.68
## 
## Training set error measures:
##                      ME    RMSE      MAE        MPE    MAPE      MASE
## Training set -0.1313987 74.0635 51.90005 -0.1691659 3.94893 0.3004161
##                    ACF1
## Training set 0.01142284
# Ajuste del modelo ARIMA(0,1,0) automático sin parte estacional y crearlo como variable darima_auto para luego poder graficarlo y crear la tabla
darima_auto <- Arima(train_ts, 
                order = c(0, 1, 0))  # Especificamos directamente (p=0, d=1, q=0)  

# Mostrar resumen del modelo ajustado
summary(darima_auto)
## Series: train_ts 
## ARIMA(0,1,0) 
## 
## sigma^2 = 5533:  log likelihood = -664.47
## AIC=1330.93   AICc=1330.97   BIC=1333.68
## 
## Training set error measures:
##                      ME    RMSE      MAE        MPE    MAPE      MASE
## Training set -0.1313987 74.0635 51.90005 -0.1691659 3.94893 0.3004161
##                    ACF1
## Training set 0.01142284
# Diagnóstico del modelo (los residuos deben ser ruido blanco)
checkresiduals(darima_auto)  # Verificar si los residuos son aleatorios y no presentan patrones

## 
##  Ljung-Box test
## 
## data:  Residuals from ARIMA(0,1,0)
## Q* = 22.133, df = 23, p-value = 0.5123
## 
## Model df: 0.   Total lags used: 23
# Generar pronóstico para el conjunto de prueba
forecast_arima_auto <- forecast(darima_auto, h = length(test_ts))  # Predecir los valores futuros

# Crear dataframe para gráfico interactivo del pronóstico
forecast_data_auto <- data.frame(Tiempo = time(forecast_arima_auto$mean), 
                            Pronostico = as.numeric(forecast_arima_auto$mean),
                            Observado = as.numeric(test_ts))

# Graficar pronóstico junto con los valores observados reales
p4auto <- ggplot(forecast_data_auto, aes(x = Tiempo)) +
  geom_line(aes(y = Pronostico, color = "Pronóstico")) +
  geom_line(aes(y = Observado, color = "Observado")) +
  ggtitle("Pronóstico vs Observado") +
  xlab("Tiempo") + ylab("variable1")

ggplotly(p4auto)  # Convertir el gráfico en interactivo
## Don't know how to automatically pick scale for object of type <ts>. Defaulting
## to continuous.
# Cargar librerías necesarias
library(forecast)
library(dplyr)

# Generar pronóstico con el modelo ARIMA identificado
arima_forecast_auto <- forecast(auto_arima_model_no_seasonal, h = length(test_ts))

# Crear un dataframe con los valores observados y pronosticados
forecast_table_auto <- data.frame(
  Tiempo = time(arima_forecast_auto$mean),  # Extraer las fechas del pronóstico
  Observado = as.numeric(test_ts),  # Valores reales
  Pronosticado = as.numeric(arima_forecast_auto$mean)  # Valores pronosticados
)

# Mostrar la tabla
print(forecast_table_auto)
##     Tiempo Observado Pronosticado
## 1 2024.750   1521.74      1379.58
## 2 2024.833   1607.57      1379.58
## 3 2024.917   1619.38      1379.58
# Cargar librerías necesarias
library(forecast)

# Hacer un pronóstico para el siguiente trimestre (1 período adicional)
next_forecast_auto <- forecast(auto_arima_model_no_seasonal, h = length(test_ts) + 1)

# Extraer el pronóstico del próximo trimestre
next_month_forecast_auto <- data.frame(
  Tiempo = time(next_forecast_auto$mean),  # Extraer la fecha del pronóstico
  Pronostico = as.numeric(next_forecast_auto$mean)  # Valor pronosticado
)

# Mostrar el pronóstico completo
print(next_month_forecast_auto)
##     Tiempo Pronostico
## 1 2024.750    1379.58
## 2 2024.833    1379.58
## 3 2024.917    1379.58
## 4 2025.000    1379.58
# Extraer solo el valor del trimestre adicional (último de la tabla)
next_month <- tail(next_month_forecast_auto, 1)
print(paste("Pronóstico para enero 2025:", next_month$Tiempo, "=", next_month$Pronostico))
## [1] "Pronóstico para enero 2025: 2025 = 1379.58"
# Pronosticar  el mes octubre 2024
future_forecast_auto <- forecast(auto_arima_model_no_seasonal, h = 1)

# Extraer el valor específico de octubre 2024
forecast_oct2024_auto <- future_forecast_auto$mean[1]
print(paste("Pronóstico para octubre 2024:", forecast_oct2024_auto))
## [1] "Pronóstico para octubre 2024: 1379.58"
# Identificación automática del mejor modelo ARIMA
auto_arima_model <- auto.arima(train_ts)  # Busca automáticamente los mejores parámetros del modelo ARIMA
print(auto_arima_model)
## Series: train_ts 
## ARIMA(0,1,0) 
## 
## sigma^2 = 5533:  log likelihood = -664.47
## AIC=1330.93   AICc=1330.97   BIC=1333.68
# Cargar el paquete necesario
library(forecast)

# Ajustar el modelo SARIMA(0,1,0)
darima <- Arima(train_ts, 
                order = c(0, 1, 0),  # (p,d,q) -> (0,1,1)
                seasonal = list(order = c(0, 1, 0),  # (P,D,Q) -> (1,0,0)
                                period = 12))  # Periodicidad estacional de 12 meses

# Mostrar resumen del modelo ajustado
summary(darima)
## Series: train_ts 
## ARIMA(0,1,0)(0,1,0)[12] 
## 
## sigma^2 = 12777:  log likelihood = -639.25
## AIC=1280.5   AICc=1280.54   BIC=1283.15
## 
## Training set error measures:
##                    ME     RMSE      MAE         MPE    MAPE      MASE
## Training set 2.004887 106.5724 72.73564 0.009012282 5.48116 0.4210199
##                     ACF1
## Training set -0.03532551
# Diagnóstico del modelo (los residuos deben ser ruido blanco)
checkresiduals(darima)  # Verificar si los residuos son aleatorios y no presentan patrones

## 
##  Ljung-Box test
## 
## data:  Residuals from ARIMA(0,1,0)(0,1,0)[12]
## Q* = 61.112, df = 23, p-value = 2.635e-05
## 
## Model df: 0.   Total lags used: 23
# Generar pronóstico para el conjunto de prueba
forecast_arima <- forecast(darima, h = length(test_ts))  # Predecir los valores futuros

# Crear dataframe para gráfico interactivo del pronóstico
forecast_data <- data.frame(Tiempo = time(forecast_arima$mean), 
                            Pronostico = as.numeric(forecast_arima$mean),
                            Observado = as.numeric(test_ts))

# Graficar pronóstico junto con los valores observados reales
p4 <- ggplot(forecast_data, aes(x = Tiempo)) +
  geom_line(aes(y = Pronostico, color = "Pronóstico")) +
  geom_line(aes(y = Observado, color = "Observado")) +
  ggtitle("Pronóstico vs Observado") +
  xlab("Tiempo") + ylab("Unidad Variable 1")

ggplotly(p4)  # Convertir el gráfico en interactivo
## Don't know how to automatically pick scale for object of type <ts>. Defaulting
## to continuous.
# Cargar librerías necesarias
library(forecast)
library(dplyr)

# Generar pronóstico con el modelo ARIMA identificado
arima_forecast <- forecast(forecast_arima, h = length(test_ts))

# Crear un dataframe con los valores observados y pronosticados
forecast_table <- data.frame(
  Tiempo = time(arima_forecast$mean),  # Extraer las fechas del pronóstico
  Observado = as.numeric(test_ts),  # Valores reales
  Pronosticado = as.numeric(arima_forecast$mean)  # Valores pronosticados
)

# Mostrar la tabla
print(forecast_table)
##     Tiempo Observado Pronosticado
## 1 2024.750   1521.74      1460.93
## 2 2024.833   1607.57      1458.46
## 3 2024.917   1619.38      1517.14
# Cargar librerías necesarias
library(forecast)

# Hacer un pronóstico para el siguiente mes (1 período adicional)
next_forecast <- forecast(auto_arima_model, h = length(test_ts) + 1)

# Extraer el pronóstico del próximo mes
next_month_forecast <- data.frame(
  Tiempo = time(next_forecast$mean),  # Extraer la fecha del pronóstico
  Pronostico = as.numeric(next_forecast$mean)  # Valor pronosticado
)

# Mostrar el pronóstico completo
print(next_month_forecast)
##     Tiempo Pronostico
## 1 2024.750    1379.58
## 2 2024.833    1379.58
## 3 2024.917    1379.58
## 4 2025.000    1379.58
# Extraer solo el valor del trimestre adicional (último de la tabla)
next_month <- tail(next_month_forecast, 1)
print(paste("Pronóstico para enero 2025:", next_month$Tiempo, "=", next_month$Pronostico))
## [1] "Pronóstico para enero 2025: 2025 = 1379.58"
# Identificación automática del mejor modelo ARIMA
auto_arima_model <- auto.arima(train_ts)  # Busca automáticamente los mejores parámetros del modelo ARIMA
print(auto_arima_model)
## Series: train_ts 
## ARIMA(0,1,0) 
## 
## sigma^2 = 5533:  log likelihood = -664.47
## AIC=1330.93   AICc=1330.97   BIC=1333.68
# Pronosticar octubre 2024
future_forecast_sarima <- forecast(auto_arima_model, h = 1)

# Extraer el valor específico de octubre 2024
forecast_oct2024_sarima <- future_forecast_sarima$mean[1]
print(paste("Pronóstico para octubre 2024:", forecast_oct2024_sarima))
## [1] "Pronóstico para octubre 2024: 1379.58"