`

# BIBLIOTECAS
#----------------
library(PerformanceAnalytics)
## Loading required package: xts
## Loading required package: zoo
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
## 
## Attaching package: 'PerformanceAnalytics'
## The following object is masked from 'package:graphics':
## 
##     legend
library(quantmod)
## Loading required package: TTR
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
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:stats':
## 
##     sigma
library(car)
## Loading required package: carData
library(FinTS)
## Warning: package 'FinTS' was built under R version 4.3.3
library(scales)
library(data.table)
## 
## Attaching package: 'data.table'
## The following objects are masked from 'package:xts':
## 
##     first, last
#Datos
#---------------
symbols <- c("^GSPC")
getSymbols(symbols, from = "2000-01-03", to = "2021-12-31")
## [1] "GSPC"
GSPC.ret <- CalculateReturns(Cl(GSPC), method = "log") # rentabilidad Log
GSPC.ret <- GSPC.ret[-1,] #eliminamos la primera fila
colnames(GSPC.ret) <- "GSPC"
# Análisis EDA
#----------------------------
table.Stats(GSPC.ret)
##                      GSPC
## Observations    5534.0000
## NAs                0.0000
## Minimum           -0.1277
## Quartile 1        -0.0047
## Median             0.0006
## Arithmetic Mean    0.0002
## Geometric Mean     0.0001
## Quartile 3         0.0058
## Maximum            0.1096
## SE Mean            0.0002
## LCL Mean (0.95)   -0.0001
## UCL Mean (0.95)    0.0005
## Variance           0.0002
## Stdev              0.0124
## Skewness          -0.4004
## Kurtosis          11.0561
# Plot series
#-----------------------------
dataToPlot <- cbind(GSPC.ret, GSPC.ret^2,abs(GSPC.ret))
colnames(dataToPlot) <- c("Retornos", "Retornos^2", "abs(Retornos)")
plot.zoo(dataToPlot, main = paste(symbols, "Rentabilidades diarias"), col = "blue")

# Computar el rezago del retorno de ayer

GSPC.ret$yesterday.ret <- data.table::shift(GSPC.ret$GSPC, n = 1, type = "lag")
GSPC.ret <- na.omit(GSPC.ret)

# Test de autocorrelación

lm.autocorr <- lm(coredata(GSPC.ret$GSPC) ~ coredata(GSPC.ret$yesterday.ret))

  # visualizar
  # crear gráficos 2x2
  par(mfrow = c(2,2))
  
# plot 1: Autocorrelación
  
  plot(coredata(GSPC.ret$yesterday.ret), coredata(GSPC.ret$GSPC), col=scales::alpha("black",0.6), pch=16, cex=0.8, main="Autocorrelación de retornos", xlab="retorno t-1", ylab="retorno t")
  abline(lm.autocorr, col="red")
  legend("topleft", legend=c(paste0("Pendiente: ",round(summary(lm.autocorr)$coefficients[2,1],3)," ( t-value ",round(summary(lm.autocorr)$coefficients[2,3],3),")"),
                             paste0("R^2: ",round(summary(lm.autocorr)$r.squared,3))), bty="n")
  box(col="grey")
  
  # plot 2: serie histórica residuales
  
  plot(lm.autocorr$residuals, type="l", main="Residuales")
  
  # plot 3: distribución residuales
  
  hist(lm.autocorr$residuals, breaks=64, main="PDF", col="grey", freq = FALSE, xlab="residuales")
  rug(lm.autocorr$residuals)
  box(col="grey")
  lines(density(lm.autocorr$residuals, bw=0.004), col="red")

  # plot 4: QQ-plot: revisión normalidad
  car::qqPlot(lm.autocorr$residuals, main="QQ-Plot")

## [1] 5080 2206
# Test de autocorrelación
# ----------------------------
par(mfrow=c(1,1))
summary(lm.autocorr)
## 
## Call:
## lm(formula = coredata(GSPC.ret$GSPC) ~ coredata(GSPC.ret$yesterday.ret))
## 
## Residuals:
##       Min        1Q    Median        3Q       Max 
## -0.117897 -0.004927  0.000563  0.005477  0.107994 
## 
## Coefficients:
##                                    Estimate Std. Error t value Pr(>|t|)    
## (Intercept)                       0.0002462  0.0001654   1.488    0.137    
## coredata(GSPC.ret$yesterday.ret) -0.1126219  0.0133484  -8.437   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.0123 on 5531 degrees of freedom
## Multiple R-squared:  0.01271,    Adjusted R-squared:  0.01253 
## F-statistic: 71.19 on 1 and 5531 DF,  p-value: < 2.2e-16

P valor = 0.000 < 0.05. Rechazamos H0 y tenemos un problema de autocorrelación.

# Correlogramas
#-------------------------
par(mfro = c(3,2))
## Warning in par(mfro = c(3, 2)): "mfro" is not a graphical parameter
acf(GSPC.ret$GSPC, main = " FAS ^GSPC Retornos")

pacf(GSPC.ret$GSPC, main = " PACF ^GSPC Retornos")

#-------------------------------------------------
acf(GSPC.ret$GSPC^2, main = " FAS ^GSPC Retornos^2")

pacf(GSPC.ret$GSPC^2, main = " FAS ^GSPC Retornos^2")

#----------------------------------------------------
acf(abs(GSPC.ret$GSPC), main = "^GSPC Abs Retornos")

pacf(abs(GSPC.ret$GSPC), main = "^GSPC Abs Retornos")

par(mfrow=c(1,1))

# Testeando por efectos ARCH/GARCH en retornos
#----------------------------------------------------------------
Box.test(coredata(GSPC.ret$GSPC^2), type="Ljung-Box", lag =12)
## 
##  Box-Ljung test
## 
## data:  coredata(GSPC.ret$GSPC^2)
## X-squared = 6403.1, df = 12, p-value < 2.2e-16

Los errores al cuadrado tienen autocorrelación significativa –> Proceso ARCH/GARCH

GARCH(1,1)

# Construir el modelo GARCH
#---------------------------------
spec = ugarchspec() # Default: GARCH(1,1)

fit = ugarchfit(data = GSPC.ret$GSPC, spec = spec)
fit
## 
## *---------------------------------*
## *          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.000637    0.000087   7.3005    0.000
## ar1     0.742638    0.117394   6.3260    0.000
## ma1    -0.792624    0.106892  -7.4152    0.000
## omega   0.000002    0.000001   3.2905    0.001
## alpha1  0.124890    0.009814  12.7264    0.000
## beta1   0.857993    0.010230  83.8696    0.000
## 
## Robust Standard Errors:
##         Estimate  Std. Error  t value Pr(>|t|)
## mu      0.000637    0.000086  7.43654 0.000000
## ar1     0.742638    0.167454  4.43488 0.000009
## ma1    -0.792624    0.154175 -5.14107 0.000000
## omega   0.000002    0.000004  0.56761 0.570297
## alpha1  0.124890    0.028058  4.45108 0.000009
## beta1   0.857993    0.041024 20.91423 0.000000
## 
## LogLikelihood : 17915.46 
## 
## Information Criteria
## ------------------------------------
##                     
## Akaike       -6.4737
## Bayes        -6.4665
## Shibata      -6.4737
## Hannan-Quinn -6.4712
## 
## Weighted Ljung-Box Test on Standardized Residuals
## ------------------------------------
##                         statistic p-value
## Lag[1]                   0.004055 0.94923
## Lag[2*(p+q)+(p+q)-1][5]  3.967018 0.07233
## Lag[4*(p+q)+(p+q)-1][9]  6.410172 0.19555
## d.o.f=2
## H0 : No serial correlation
## 
## Weighted Ljung-Box Test on Standardized Squared Residuals
## ------------------------------------
##                         statistic p-value
## Lag[1]                     0.8043  0.3698
## Lag[2*(p+q)+(p+q)-1][5]    5.5473  0.1147
## Lag[4*(p+q)+(p+q)-1][9]    7.1614  0.1860
## d.o.f=2
## 
## Weighted ARCH LM Tests
## ------------------------------------
##             Statistic Shape Scale P-Value
## ARCH Lag[3]   0.04944 0.500 2.000  0.8240
## ARCH Lag[5]   2.11410 1.440 1.667  0.4466
## ARCH Lag[7]   2.70822 2.315 1.543  0.5703
## 
## Nyblom stability test
## ------------------------------------
## Joint Statistic:  23.5854
## Individual Statistics:              
## mu     0.57419
## ar1    0.04229
## ma1    0.03849
## omega  2.13973
## alpha1 0.37355
## beta1  0.90989
## 
## 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           3.6308 2.851e-04 ***
## Negative Sign Bias  0.8713 3.836e-01    
## Positive Sign Bias  2.6190 8.843e-03 ***
## Joint Effect       42.4167 3.273e-09 ***
## 
## 
## Adjusted Pearson Goodness-of-Fit Test:
## ------------------------------------
##   group statistic p-value(g-1)
## 1    20     205.4    2.927e-33
## 2    30     234.1    6.035e-34
## 3    40     281.1    2.057e-38
## 4    50     293.9    1.230e-36
## 
## 
## Elapsed time : 0.5137441
# Plot
# -----------------------------------
plot(fit, which = "all")
## 
## please wait...calculating quantiles...

# media incondicional
uncmean(fit)
## [1] 0.0006372291
# varianza incondicional: omega/(alpha1 + beta1)
uncvariance(fit)
## [1] 0.0001386205
# persistencia: alpha1 + beta1
persistence(fit)
## [1] 0.9828833
# half-life: tiempo (días) que toma recuperar la mitad del incremento en la varianza 
halflife(fit)
## [1] 40.14784
# Plot
#----------------------
dataToPlot <- cbind(residuals(fit), sigma(fit))
colnames(dataToPlot) <- c("Residual", "Volatilidad_condicional")
plot.zoo(dataToPlot, main = paste(symbols, "Retornos Diarios"), col = "blue")

SIMULACIÓN

garch11.sim = ugarchsim(fit, n.sim=nrow(GSPC.ret), rseed=12345)

# plotear retornos reales y simulados

par(mfrow=c(2,1))
  plot(GSPC.ret$GSPC, main=paste(symbols,"Retornos realizados"), grid.col=NA, lwd=1)
  plot(as.xts(garch11.sim@simulation$seriesSim, 
              order.by=index(GSPC.ret)),
       main="GARCH(1,1) Retornos Simulados", grid.col=NA, lwd=1)

par(mfrow=c(1,1))

precio.actual = as.numeric(head(GSPC$GSPC.Adjusted[1]))
precio.futuro.sim1 <- precio.actual*(cumprod(1+garch11.sim@simulation$seriesSim))
GSPC$precio.futuro.sim1[3:nrow(GSPC)] <- precio.futuro.sim1
GSPC <-na.omit(GSPC)

plot.sim <- plot(GSPC$precio.futuro.sim1["2000"], type="l", ylim=c(min(GSPC$precio.futuro.sim1["2000"],GSPC$GSPC.Close["2000"]),
       max(GSPC$precio.futuro.sim1["2000"],GSPC$GSPC.Close["2000"])),main="Futuro alterno simulado - data sintética", grid.col=NA)
plot.sim <- lines(GSPC$GSPC.Close, col="red", on=1)
plot.sim <- addLegend("topleft", legend.names=c("Realizado","Simulado"), col=c("red","black"), lwd=2)
plot.sim

CONCLUSIONES

En la práctica, el modelo GARCH(1,1) con innovaciones Normales no se adapta adecuadamente.

Importantes limitaciones:

La especificación de la función generadora modelada ¿es la más aproximada a la volatilidad empírica? Sobre la distribución de los errores, ¿es la mas adecuada? No permite la asimetría. El mercado no reacciona de la misma manera a las noticias positivas y negativas. El modelo debería acomodar la posibilidad de saltos. Conclusión: Es necesario realizar un fit iterativo que pruebe distintos modelos, en distintas configuraciones, incluyendo otras distribuciones de probabilidad. Entonces, elegir el modelo que minimiza el error.