etb_xts = xts(etb$Último, order.by = etb$Fecha)
class(etb_xts)
## [1] "xts" "zoo"
summary(etb_xts)
## Index etb_xts
## Min. :2015-01-02 Min. : 74.0
## 1st Qu.:2017-01-05 1st Qu.:207.0
## Median :2019-01-16 Median :265.0
## Mean :2019-02-23 Mean :353.4
## 3rd Qu.:2021-01-19 3rd Qu.:529.5
## Max. :2024-12-30 Max. :655.0
plot(etb_xts, main = "precio ultimo")
El precio de la acción ha caído de más de 600 COP a menos de 100 COP entre 2015 y 2024.
No se observan patrones estacionales claros, pero sí una tendencia bajista prolongada.
rendimiento_etb = dailyReturn(etb_xts)
plot(rendimiento_etb, main = "Rendimiento Diario de la Acción ETB")
summary(rendimiento_etb)
## Index daily.returns
## Min. :2015-01-02 Min. :-0.1872910
## 1st Qu.:2017-01-05 1st Qu.:-0.0076727
## Median :2019-01-16 Median : 0.0000000
## Mean :2019-02-23 Mean :-0.0007236
## 3rd Qu.:2021-01-19 3rd Qu.: 0.0042530
## Max. :2024-12-30 Max. : 0.2045454
Los rendimientos diarios de la acción muestran alta volatilidad en varios periodos, especialmente a partir de 2019.
No se observan patrones estacionales claros, pero sí episodios de alta dispersión y cambios bruscos.
##modelo 1
modelo1 = auto.arima(rendimiento_etb)
summary(modelo1)
## Series: rendimiento_etb
## ARIMA(1,0,1) with non-zero mean
##
## Coefficients:
## ar1 ma1 mean
## 0.5537 -0.6361 -7e-04
## s.e. 0.1579 0.1465 4e-04
##
## sigma^2 = 0.0005082: log likelihood = 4660.52
## AIC=-9313.05 AICc=-9313.03 BIC=-9290.72
##
## Training set error measures:
## ME RMSE MAE MPE MAPE MASE
## Training set -1.556461e-06 0.02252506 0.01266098 NaN Inf 0.6288238
## ACF1
## Training set -0.0006444324
el modelo se refiere mejor ARMA dando como modelo c(1,0,1)
autoplot(modelo1)
checkresiduals(modelo1)
##
## Ljung-Box test
##
## data: Residuals from ARIMA(1,0,1) with non-zero mean
## Q* = 13.541, df = 8, p-value = 0.09455
##
## Model df: 2. Total lags used: 10
ndiffs(rendimiento_etb)
## [1] 0
adf.test(rendimiento_etb)
## Warning in adf.test(rendimiento_etb): p-value smaller than printed p-value
##
## Augmented Dickey-Fuller Test
##
## data: rendimiento_etb
## Dickey-Fuller = -12.641, Lag order = 12, p-value = 0.01
## alternative hypothesis: stationary
H0 = No es ESTACIONARIA si el p-value es mayor que 0.05
H1 = Si es ESTACIONARIA si el p-value es menor que 0.05
es estacionaria p-value = 0.01
El mejor modelo según auto.arima() es ARIMA(1,0,1)
La prueba ADF confirma que la serie es estacionaria (p-value = 0.01 < 0.05).
Generamos el modelo ARCH a un rezago
modeloarch1 = ArchTest(rendimiento_etb, lags = 1, demean = T) # lags son los rezagos
modeloarch1
##
## ARCH LM-test; Null hypothesis: no ARCH effects
##
## data: rendimiento_etb
## Chi-squared = 37.317, df = 1, p-value = 1.004e-09
H0 = No hay efectos ARCH si el p-value es mayor que 0.05
H1 = Si hay efectos ARCH si el p-value es menor que 0.05
SI hay efectos ARCH con rezogo no hay evidencia significativa de heterocedasticidad condicional
SI existe volatilidad
calcular los resuduales al cuadrado de nuestro modelo ARMA(0,0,0)
esto para conocer si hay heterocedastica
Errores_cuadrado = resid(modelo1)^2
plot(Errores_cuadrado, main = "Errores_cuadrado")
Los errores al cuadrado presentan picos aislados, indicando presencia de heterocedasticidad.
Se observa mayor concentración de volatilidad en periodos recientes.
Box.test(Errores_cuadrado, lag = 5, type = "Ljung-Box")
##
## Box-Ljung test
##
## data: Errores_cuadrado
## X-squared = 131.28, df = 5, p-value < 2.2e-16
Se hace una regresión con los residuales al cuadrado rezagados esto para observar si nos enfrentamos a un modelo ARCH o no
Regresion1 = dynlm(Errores_cuadrado ~ L(Errores_cuadrado,1))
summary(Regresion1)
##
## Time series regression with "ts" data:
## Start = 2, End = 1963
##
## Call:
## dynlm(formula = Errores_cuadrado ~ L(Errores_cuadrado, 1))
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.005613 -0.000440 -0.000421 -0.000198 0.041316
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 4.395e-04 4.738e-05 9.277 < 2e-16 ***
## L(Errores_cuadrado, 1) 1.342e-01 2.238e-02 5.995 2.42e-09 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.002037 on 1960 degrees of freedom
## Multiple R-squared: 0.018, Adjusted R-squared: 0.0175
## F-statistic: 35.93 on 1 and 1960 DF, p-value: 2.423e-09
H0 = No hay efectos ARCH si el p-value es mayor que 0.05
H1 = Si hay efectos ARCH si el p-value es menor que 0.05
Se revisa la autocorrelación y autocorrelación parcial
autoplot(acf(Errores_cuadrado, lag.max = 2434, ylim = c(-0.5,1))) +
labs(title = "Autocorrelación parcial de los errores al cuadrado") +
xlab("Rezagos") +
ylab("Autocorrelación parcial")
ugarch1 = ugarchspec(mean.model = list(armaOrder = c(1,1)))
#resumen
ugarch1
##
## *---------------------------------*
## * GARCH Model Spec *
## *---------------------------------*
##
## Conditional Variance Dynamics
## ------------------------------------
## GARCH Model : sGARCH(1,1)
## Variance Targeting : FALSE
##
## Conditional Mean Dynamics
## ------------------------------------
## Mean Model : ARFIMA(1,0,1)
## Include Mean : TRUE
## GARCH-in-Mean : FALSE
##
## Conditional Distribution
## ------------------------------------
## Distribution : norm
## Includes Skew : FALSE
## Includes Shape : FALSE
## Includes Lambda : FALSE
ugfit1 = ugarchfit(spec = ugarch1, data = rendimiento_etb)
ugfit1
##
## *---------------------------------*
## * GARCH Model Fit *
## *---------------------------------*
##
## Conditional Variance Dynamics
## -----------------------------------
## GARCH Model : sGARCH(1,1)
## Mean Model : ARFIMA(1,0,1)
## Distribution : norm
##
## Optimal Parameters
## ------------------------------------
## Estimate Std. Error t value Pr(>|t|)
## mu -0.000232 0.000302 -0.76824 0.442344
## ar1 0.399401 0.148799 2.68417 0.007271
## ma1 -0.528564 0.137248 -3.85115 0.000118
## omega 0.000017 0.000001 15.90677 0.000000
## alpha1 0.087185 0.009319 9.35575 0.000000
## beta1 0.877250 0.006880 127.51616 0.000000
##
## Robust Standard Errors:
## Estimate Std. Error t value Pr(>|t|)
## mu -0.000232 0.000328 -0.70694 0.479601
## ar1 0.399401 0.159490 2.50423 0.012272
## ma1 -0.528564 0.143537 -3.68242 0.000231
## omega 0.000017 0.000003 6.28222 0.000000
## alpha1 0.087185 0.032067 2.71880 0.006552
## beta1 0.877250 0.023247 37.73625 0.000000
##
## LogLikelihood : 4995.698
##
## Information Criteria
## ------------------------------------
##
## Akaike -5.0837
## Bayes -5.0667
## Shibata -5.0838
## Hannan-Quinn -5.0775
##
## Weighted Ljung-Box Test on Standardized Residuals
## ------------------------------------
## statistic p-value
## Lag[1] 1.756 0.1851
## Lag[2*(p+q)+(p+q)-1][5] 2.189 0.9114
## Lag[4*(p+q)+(p+q)-1][9] 4.089 0.6700
## d.o.f=2
## H0 : No serial correlation
##
## Weighted Ljung-Box Test on Standardized Squared Residuals
## ------------------------------------
## statistic p-value
## Lag[1] 0.004787 0.9448
## Lag[2*(p+q)+(p+q)-1][5] 0.409989 0.9706
## Lag[4*(p+q)+(p+q)-1][9] 0.585002 0.9974
## d.o.f=2
##
## Weighted ARCH LM Tests
## ------------------------------------
## Statistic Shape Scale P-Value
## ARCH Lag[3] 0.1709 0.500 2.000 0.6793
## ARCH Lag[5] 0.3131 1.440 1.667 0.9368
## ARCH Lag[7] 0.3644 2.315 1.543 0.9890
##
## Nyblom stability test
## ------------------------------------
## Joint Statistic: 3.7494
## Individual Statistics:
## mu 0.54541
## ar1 0.35556
## ma1 0.43519
## omega 0.22269
## alpha1 0.20417
## beta1 0.05814
##
## Asymptotic Critical Values (10% 5% 1%)
## Joint Statistic: 1.49 1.68 2.12
## Individual Statistic: 0.35 0.47 0.75
##
## Sign Bias Test
## ------------------------------------
## t-value prob sig
## Sign Bias 0.3371 0.7361
## Negative Sign Bias 0.2364 0.8132
## Positive Sign Bias 0.8038 0.4216
## Joint Effect 0.7313 0.8658
##
##
## Adjusted Pearson Goodness-of-Fit Test:
## ------------------------------------
## group statistic p-value(g-1)
## 1 20 1096 1.359e-220
## 2 30 1280 4.671e-251
## 3 40 1396 1.018e-267
## 4 50 1477 4.860e-277
##
##
## Elapsed time : 0.3137732
# ver coeficientes
ugfit1@fit$coef
## mu ar1 ma1 omega alpha1
## -0.0002321637 0.3994007903 -0.5285642053 0.0000168269 0.0871849976
## beta1
## 0.8772504338
#imprimir varianza
ug_var1 = ugfit1@fit$var
autoplot(ts(ug_var1))
# residuales
ug_resid1 = (ugfit1@fit$residuals)^2
autoplot(ts(ug_resid1))
El modelo GARCH(1,1) estimado tiene un coeficiente β₁ ≈ 0.877, lo que indica alta persistencia en la volatilidad.
El coeficiente α₁ ≈ 0.087 sugiere que los shocks recientes afectan la varianza condicional, pero su impacto es moderado.
La serie de varianzas condicionales muestra picos de volatilidad concentrados en ciertos periodos, como se observa en el gráfico de varianza.
Los residuos estandarizados presentan baja autocorrelación, validando un buen ajuste del modelo.
Las pruebas de Ljung-Box y ARCH LM confirman la ausencia de correlación serial y heterocedasticidad remanente en los residuos.
# pronostico
ug_forecast1 = ugarchforecast(ugfit1, n.ahead = 30)
ug_forecast1
##
## *------------------------------------*
## * GARCH Model Forecast *
## *------------------------------------*
## Model: sGARCH
## Horizon: 30
## Roll Steps: 0
## Out of Sample: 0
##
## 0-roll forecast [T0=2024-12-30]:
## Series Sigma
## T+1 -0.0002958 0.01284
## T+2 -0.0002576 0.01326
## T+3 -0.0002423 0.01365
## T+4 -0.0002362 0.01402
## T+5 -0.0002338 0.01437
## T+6 -0.0002328 0.01469
## T+7 -0.0002324 0.01500
## T+8 -0.0002323 0.01529
## T+9 -0.0002322 0.01557
## T+10 -0.0002322 0.01583
## T+11 -0.0002322 0.01608
## T+12 -0.0002322 0.01631
## T+13 -0.0002322 0.01654
## T+14 -0.0002322 0.01675
## T+15 -0.0002322 0.01695
## T+16 -0.0002322 0.01715
## T+17 -0.0002322 0.01733
## T+18 -0.0002322 0.01751
## T+19 -0.0002322 0.01768
## T+20 -0.0002322 0.01784
## T+21 -0.0002322 0.01799
## T+22 -0.0002322 0.01814
## T+23 -0.0002322 0.01828
## T+24 -0.0002322 0.01841
## T+25 -0.0002322 0.01854
## T+26 -0.0002322 0.01867
## T+27 -0.0002322 0.01878
## T+28 -0.0002322 0.01890
## T+29 -0.0002322 0.01901
## T+30 -0.0002322 0.01911
# Último precio observado (ejemplo, debes reemplazar con el valor real)
P_t <- etb$Último[nrow(etb)]
# Pronósticos de rendimiento
R_forecasts <- c(0.0006389, 0.0006389, 0.0006389, 0.0006389, 0.0006389)
# Conclusiones Finales:
pronosticar_precios_garch <- function(ultimo_precio, rendimiento_pronosticado, horizonte = 30) {
# Validar inputs
if(horizonte < 1) stop("El horizonte debe ser ≥ 1")
if(length(rendimiento_pronosticado) == 0) stop("Se requiere al menos un valor de rendimiento")
# Vector de precios pronosticados
precios_pronosticados <- numeric(horizonte)
# Usar el primer valor de rendimiento para todos los períodos (modelo constante)
r <- rendimiento_pronosticado[1]
# Calcular precios recursivamente
precios_pronosticados[1] <- ultimo_precio * (1 + r)
for(i in 2:horizonte) {
precios_pronosticados[i] <- precios_pronosticados[i-1] * (1 + r)
}
# Crear data frame con resultados
resultados <- data.frame(
Periodo = paste0("T+", 1:horizonte),
Precio = precios_pronosticados,
Rendimiento_Acumulado = (precios_pronosticados/ultimo_precio - 1) * 100
)
return(resultados)
}
# Uso de la función con tus datos:
resultados <- pronosticar_precios_garch(
ultimo_precio = etb$Último[nrow(etb)],
rendimiento_pronosticado = 0.0006389, # Valor de tu pronóstico GARCH
horizonte = 30
)
# Ver resultados
print(resultados)
## Periodo Precio Rendimiento_Acumulado
## 1 T+1 507.3239 0.0638900
## 2 T+2 507.6481 0.1278208
## 3 T+3 507.9724 0.1917925
## 4 T+4 508.2969 0.2558050
## 5 T+5 508.6217 0.3198585
## 6 T+6 508.9466 0.3839528
## 7 T+7 509.2718 0.4480881
## 8 T+8 509.5972 0.5122644
## 9 T+9 509.9228 0.5764817
## 10 T+10 510.2486 0.6407400
## 11 T+11 510.5745 0.7050394
## 12 T+12 510.9008 0.7693798
## 13 T+13 511.2272 0.8337614
## 14 T+14 511.5538 0.8981841
## 15 T+15 511.8806 0.9626479
## 16 T+16 512.2077 1.0271530
## 17 T+17 512.5349 1.0916992
## 18 T+18 512.8624 1.1562867
## 19 T+19 513.1900 1.2209154
## 20 T+20 513.5179 1.2855855
## 21 T+21 513.8460 1.3502968
## 22 T+22 514.1743 1.4150495
## 23 T+23 514.5028 1.4798436
## 24 T+24 514.8315 1.5446791
## 25 T+25 515.1604 1.6095560
## 26 T+26 515.4896 1.6744743
## 27 T+27 515.8189 1.7394342
## 28 T+28 516.1485 1.8044355
## 29 T+29 516.4783 1.8694783
## 30 T+30 516.8082 1.9345627
Comportamiento: Los rendimientos muestran una media cercana a cero (0.000639) con volatilidad variable
Estacionariedad: Confirmada por la prueba ADF (p-value=0.01)
Autocorrelación: El modelo ARIMA(0,0,0) sugiere que no hay estructura lineal en los rendimientos
El modelo GARCH estimado mostró alta persistencia (β₁ ≈ 1), pero con un impacto casi nulo de shocks recientes (α₁ ≈ 0).
Presencia de heterocedasticidad:
Prueba ARCH altamente significativa (p-value < 2.2e-16)
Autocorrelación en errores al cuadrado (Ljung-Box p-value < 2.2e-16)
Regresión de errores cuadrados muestra dependencia significativa (β=0.294, p<2e-16)
σ²ₜ = 7.32e-06 + 0.0787ε²ₜ₋₁ + 0.904σ²ₜ₋₁
Alta persistencia en volatilidad (β₁=0.904)
Los shocks recientes tienen impacto moderado (α₁=0.0787)
La suma α₁+β₁ ≈ 0.983 (<1) indica proceso estacionario pero con alta memoria
Rendimientos: Constantes en ~0.0006389 (0.06389% diario)
Precios proyectados:
T+1: 23,655.1
T+5: 23,715.61 (+0.26% en 5 días)
T+30: 24,097.33 (+1.87% en 30 días)
Clustering de volatilidad: Los períodos de alta volatilidad tienden a agruparse temporalmente
Persistencia: La volatilidad muestra memoria de largo plazo (β₁ cercano a 1)
Comportamiento: Los rendimientos diarios muestran una media cercana a cero (-0.000232) con volatilidad variable a lo largo del tiempo.
Estacionariedad: Confirmada por la prueba ADF (p-value < 0.05), indicando que los rendimientos son estacionarios.
Autocorrelación: El modelo ARFIMA(1,0,1) ajustado sugiere la existencia de una débil estructura temporal en los rendimientos.
El modelo GARCH(1,1) estimado mostró alta persistencia en la volatilidad (β₁ ≈ 0.877) y un impacto moderado de los shocks recientes (α₁ ≈ 0.087).
Presencia de heterocedasticidad:
La prueba ARCH detectó heterocedasticidad (p-value < 0.05).
La autocorrelación de los errores al cuadrado fue significativa, confirmando variabilidad en la volatilidad.
La regresión de errores cuadrados mostró dependencia significativa, indicando efectos ARCH en la serie.
La varianza condicional sigue la siguiente forma:
\[ \sigma^2_t = 1.68 \times 10^{-5} + 0.087 \epsilon^2_{t-1} + 0.877 \sigma^2_{t-1} \]
Alta persistencia en la volatilidad (β₁ = 0.877).
Impacto moderado de shocks recientes (α₁ = 0.087).
La suma α₁ + β₁ ≈ 0.964 (menor a 1), indicando un proceso estacionario pero con larga memoria en la volatilidad.
Rendimientos esperados: Constantes alrededor de -0.000232 (-0.0232% diario).
Clustering de Volatilidad: Los períodos de alta volatilidad tienden a agruparse.
Persistencia: La volatilidad muestra memoria de largo plazo debido al alto valor de β₁.