PREDICCIÓN TIPO DE CAMBIO CON MODELOS ARIMA
# La biblioteca quantmod (Quantitative Financial Modelling Framework) se utiliza para poder llamar la función getSymbols y .xts
library(quantmod)
## Loading required package: xts
## Loading required package: zoo
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
## Loading required package: TTR
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
# La biblioteca tseries (Time Series Analysis and Computational Finance) se utiliza para el análisis de Series de Tiempo
library(tseries)
# La biblioteca forecast (Forecasting Functions for Time Series and Linear Models) se utiliza para analizar y visualizar eries del tiempo univariadas.
library(forecast)
# Se utiliza para poder usar la función auto.arima(), la cual nos ayudará a generar un modelo arima.
library(lmtest)
getSymbols(Symbols="DEXMXUS", src="FRED")
## [1] "DEXMXUS"
# Indicamos la fecha de inicio para tomar los datos de la base de datos
DEXMXUS=DEXMXUS["1990-01-01/"]
#Dado que la base de datos con la que estamos trabajando tiene una periodicidad diaria es necesario convertirla a mensual con la función "to.monthly"
mrate.xts = to.monthly(DEXMXUS)
## Warning in to.period(x, "months", indexAt = indexAt, name = name, ...): missing
## values removed from data
plot(mrate.xts)
#Una vez teniendo los valores mensuales tomamos el precio de cierre con la función Cl.
mrate = Cl(mrate.xts)
# Transformamos el DataFrame a un objeto TimeSeries con frecuencia mensual. La función de ts() se usa para crear objetos de SeriesdeTiempo. Se le indica el incio y el final con una frecuencia mensual
mrate<-ts(coredata(mrate),start=c(1990,1), end=c(2023,1),frequency=12)
#Calculamos el logaritmo de la variable mrate y después la graficamos con respecto al tiempo
lnmrate<- log(mrate)
plot(lnmrate)
# Sacamos la diferencia del logaritmo de nuestra variable mrate con la función "diff()"
dif_log = diff(lnmrate, lag=12)
#Prácticamente lo que estamos calculando es la diferencia que existe entre el log de la variable del tipo de cambio (mrate) y el log de la misma variable, pero de hace 12 meses, es por esto que es anual. Podemos calcular esto mismo de la siguiente manera: dif_log=lnmrate-lag(lnmrate,12)
plot(dif_log)
Como podemos observar, los datos visualmente se ven estacionarios, pero
para corroborar que en efecto los datos sean estacionarios vamos a
realizar el test de Dicky-Fuller.
El Dicky-Fuller test nos ayudará a determinar si hay o no presencia de tendencia en una autoregresión.
La hipotesis nula establece la presencia de tendencia entre las observaciones (no estacionaria) y la alternativa establece que no hay presencia de tendencia (estacionaria).
Si como resultado del test obtenemos que la variable es estacionaria, entonces D = 1 y d = 0.
#Augmented Dickey Fuller Test (ADF Test)
adf.test(dif_log,k=1)
## Warning in adf.test(dif_log, k = 1): p-value smaller than printed p-value
##
## Augmented Dickey-Fuller Test
##
## data: dif_log
## Dickey-Fuller = -4.5867, Lag order = 1, p-value = 0.01
## alternative hypothesis: stationary
H0: raíz unitaria – no estacionaria H1: no ha raíz unitaria – sí estacionaria
El p valor es 0.01 < 0.05. Rechazamos H0 y la serie de la diferencia del logaritmo sí es estacionaria en la media.
Como podemos observar, el p valor del test es de 0.01 al 95% de confianza, por lo que rechazamos la hipotesis nula, concluyendo así que la diferencia estacional del logaritmo es estacionaria.
Una vez teniendo los datos con los que vamos a trabajar de manera estacionaria y sabiendo que D=1 y d=0, hace falta definir los valores p, q, P, Q. Utilizando la variable estacionaria, procederemos a realizar las gráficas de autocorrelación ACF (autocorrelación) y PACF (autocorrelación parcial) para identificar los parámetros p, q, P, Q, dependiendo del comportamiento de éstas.
Los 2 patrones más comunes que podemos encontrar en las gráficas son los siguientes:
-Firma AR: cuando la magnitud de las autocorrelaciones del ACF van decayendo de manera progresiva y son positivas, mientras que las autocorrelaciones del PACF con positivas pero disminuyen rápidamente después del lag 1,2 o 3. Si esto se cumple entonces p=número de lags positivos significativos y q= 0
-Firma MA: cuando hay una autocorrelación negativa y significativa en el mismo número de lag para ambas gráficas. Si esto se cumple q= al número del lag negativo más significativo.
Procederemos a gráficarlas en los siguientes correlogramas:
# La función acf2() la extraemos de la biblioteca astsa
library(astsa)
##
## Attaching package: 'astsa'
## The following object is masked from 'package:forecast':
##
## gas
# Introducimos la variable "dif_log", la cual tiene asingados los valores logarítmicos de la variación del tipo de cambio e indicamos un máximo de 24 lags
acf2(dif_log, max.lag=24)
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
## ACF 0.92 0.83 0.73 0.63 0.54 0.45 0.36 0.27 0.18 0.08 -0.03 -0.13
## PACF 0.92 -0.16 -0.06 -0.06 -0.03 -0.04 -0.06 -0.05 -0.12 -0.11 -0.11 -0.13
## [,13] [,14] [,15] [,16] [,17] [,18] [,19] [,20] [,21] [,22] [,23] [,24]
## ACF -0.17 -0.17 -0.17 -0.16 -0.14 -0.14 -0.13 -0.13 -0.13 -0.12 -0.10 -0.08
## PACF 0.43 0.05 0.00 -0.05 0.00 -0.10 -0.03 -0.03 -0.06 0.02 -0.09 -0.08
ACF = un decaimiento en los primeros retardos. AR() PACF vemos la primera autocorrelación y la s = 12 significativas AR(1) y SAR(1)12
Para poder interpretar estas gráficas, es importante entender lo que esta ocurriendo. Primero que nada, como se mencionó anteriormente, tenemos dos gráficas:
ACF nos indica la autocorrelación entre los valores de las series que se encuentran a k intervalos de distancia. PACF nos indica las autocorrelación entre los valores de las series que se encuentran a k intervalos de distancia, teniendo en cuenta los valores de los intervalos intermedios. En ambas gráficas, el eje de las x tenemos los lag (periodo), mientras que en el eje ‘y’ tenemos el nivel de autocorrelación. Además, las líneas negras verticales representan el nivel de autocorrelación existente entre el valor actual de Y(t) y sus porpios lags (Yt-1, Yt-2,…) y las líneas horizontales azules delimitan el intervalo del 95% de confianza para las autocorrelaciones.
Una vez sabiendo esto, podemos observar de manera sencilla cuales son los lags de la variable que tienen una autocorrelación significante. Si la línea vertical sobresale de las líneas punteadas entonces podemos concluir que la autocorrelación de la variable Y(t), con su correspondiente lag Yt-1 es estadisticamente diferente a cero.
Analizando los valores obtenidos en el ACF podemos ver que LAG 1 (Yt-1) esta significativamente autocorrelacionada de manera positiva con el valor actual de la variable (Yt), ya que su valor es mayor a cero (0.92). Esto significa que el valor de Y en cualquier punto del tiempo tiene una autocorrelación promedio de 0.92 con respecto a su propio valor en t-1.
Por el otro lado, en la gráfica PACF lo que podemos concluir es que el lag 1 está autocorrelacionado con el valor actual después de considerar el efecto de los valores intermedios, o en otra palabras, la variación del tipo de cambio del mes actual parece estar positivamente correlacionado con su propio valor del siguiente mes.
Finalmente, analizando los patrones,la magnitud de las autocorrelaciones del ACF van decayendo de manera progresiva y son positivas, mientras que las autocorrelaciones del PACF disminuyen rápidamente después del lag 1. Indicandonos que estamos frente a un patrón tipo AR, por lo cual podemos decir que p=1 y q=0.
Ahora sólo hace falta comprobar si existe una autocorrelación significativa entre los rezagos estacionales de ACF y PACF para poder encontrar los valores de P y Q. Al estar manejando datos mensuales, deberemos hacer una autocorrelación significativa en el lag 12.
Si es significativa y positiva entonces P = 1 y Q = 0. Si es significativa y negativa, definimos P = 0 y Q = 1. Si no hay una autocorrelación significativa, entonces P = 0 y Q = 0. Debido a que no tenemos autocorrelación significativa entonces P=0 y Q=0.
model1 <- Arima(mrate,
lambda = 0, # Aplicamos el logaritmo natural a la variable
order = c(1,0,0), #p=1; 2=0; q=0
seasonal = list(order=c(1,1,0),period=12), #P=1,D=1,Q=0
include.constant = TRUE,
)
coeftest(model1)
##
## z test of coefficients:
##
## Estimate Std. Error z value Pr(>|z|)
## ar1 0.9488584 0.0161967 58.5836 <2e-16 ***
## sar1 -0.4876036 0.0447775 -10.8895 <2e-16 ***
## drift 0.0035417 0.0063338 0.5592 0.576
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
El coeficiente del auto regresivo general (AR[1]) es significativo p valor = 0.000 < 0.05. El coeficiente del auto regresivo estacional (SAR[1]12) es significativo p valor = 0.000 < 0-05
Respecto a la constante, su p valor es 0.56 >0.05. Esto indica que la constante es igual a cero al 95% de confianza. Es irrelevante, por lo que hay que eliminarla del modelo.
model2 <- Arima(mrate,
lambda = 0, # Aplicamos el logaritmo natural a la variable
order = c(1,0,0), #p=1; 2=0; q=0
seasonal = list(order=c(1,1,0),period=12), #P=1,D=1,Q=0
include.constant = FALSE,
)
coeftest(model2)
##
## z test of coefficients:
##
## Estimate Std. Error z value Pr(>|z|)
## ar1 0.949515 0.016202 58.604 < 2.2e-16 ***
## sar1 -0.487308 0.044784 -10.881 < 2.2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Una vez corrido el arima, es importante verificar si los errores o los residuales son una serie estacionaria. De ser así, esto significa que tenemos todos los términos, que permiten la explicación de la serie.
errors <- model2$residuals
acf2(errors,max.lag = 24)
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13]
## ACF 0.11 0.02 0.04 -0.01 0.01 0.01 -0.02 0.06 0.04 0.06 0.08 -0.16 -0.14
## PACF 0.11 0.01 0.04 -0.01 0.01 0.01 -0.02 0.06 0.03 0.05 0.07 -0.18 -0.11
## [,14] [,15] [,16] [,17] [,18] [,19] [,20] [,21] [,22] [,23] [,24]
## ACF -0.06 -0.03 -0.04 0.05 0 0.01 -0.01 -0.03 -0.01 -0.05 -0.29
## PACF -0.04 0.00 -0.03 0.07 0 -0.01 -0.01 -0.01 0.02 -0.01 -0.30
Tenemos autocorrelaciones significativas en el ACF y PACF, dinicando que el error no es ruido blanco. Debemos buscar otro modelo más adecuado, ya que el modelo AR81) SAR(1)12 es incorrecto.
model3 <- Arima(mrate, order = c(1,0,0),#p=1; d=0; q=0
seasonal = list(order=c(0,1,1),period=12), #P=0,D=1,**Q=1**
include.constant = TRUE,
lambda = 0)
coeftest(model3)
##
## z test of coefficients:
##
## Estimate Std. Error z value Pr(>|z|)
## ar1 0.9840308 0.0115869 84.9261 <2e-16 ***
## sma1 -0.9192193 0.0334871 -27.4500 <2e-16 ***
## drift 0.0020238 0.0026207 0.7723 0.44
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
model4 <- Arima(mrate, order = c(1,0,0),#p=1; d=0; q=0
seasonal = list(order=c(0,1,1),period=12), #P=0,D=1,**Q=1**
include.constant = FALSE,
lambda = 0)
coeftest(model4)
##
## z test of coefficients:
##
## Estimate Std. Error z value Pr(>|z|)
## ar1 0.986636 0.010903 90.496 < 2.2e-16 ***
## sma1 -0.917048 0.032959 -27.824 < 2.2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
errors2<- model4$residuals
acf2(errors2,max.lag = 24)
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13]
## ACF 0.06 0.01 0.03 -0.04 0.01 -0.01 -0.01 0.02 0.05 0.05 0.03 -0.05 -0.17
## PACF 0.06 0.01 0.03 -0.04 0.01 -0.01 -0.01 0.02 0.04 0.05 0.02 -0.05 -0.16
## [,14] [,15] [,16] [,17] [,18] [,19] [,20] [,21] [,22] [,23] [,24]
## ACF -0.06 -0.01 -0.05 0.07 0.00 0.02 0.00 -0.01 0.02 -0.05 -0.07
## PACF -0.04 0.01 -0.04 0.07 -0.01 0.01 -0.01 0.00 0.04 -0.03 -0.05
En este caso, el modelo AR(1) SMA(1)12 muestra un error con estructura de ruido blanco (estacionario)
Box.test(residuals(model4), type="Ljung-Box")
##
## Box-Ljung test
##
## data: residuals(model4)
## X-squared = 1.3372, df = 1, p-value = 0.2475
H0: No autocorrelación – El error es ruido blanco (estacionario) H1: Sí autocorrelación – El error no es ruido blanco (no estacionario)
El p valor es 0.2588 > 0.05, tenemos evidencia para indicar que el error es estacionario y no presenta autocorrelación en ningún lag.
# Se utiliza la función forecast para predecir los valores futuros de los siguientes 12 meses
mrate_forecast <- forecast(model4, h=12)
autoplot(mrate_forecast)
tail(mrate_forecast$mean,12)
## Jan Feb Mar Apr May Jun Jul Aug
## 2023 7.667734 7.723176 7.850257 7.011622 7.259034 7.381604 7.458092
## 2024 7.814905
## Sep Oct Nov Dec
## 2023 7.533900 7.559022 7.673434 7.782152
## 2024
Referencias:
https://www.machinelearningplus.com/time-series/arima-model-time-series-forecasting-python/ https://rpubs.com/cdorante/fz2020_w3 https://rpubs.com/Stefan240sx/e1fe2 https://rpubs.com/Rafael_Romo/779985 https://www.estadistica.net/ECONOMETRIA/SERIES-TEMPORALES/modelo-arima.pdf https://www.researchgate.net/publication/328633706_Forecasting_of_demand_using_ARIMA_model https://www.sciencedirect.com/science/article/abs/pii/S0360835298000667