knitr::opts_chunk$set(echo = TRUE)
options(scipen = 999) # to avoid using scientific notation
library(dplyr) # for the lag( ) function
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(quantmod) # for the getSymbols( ) & charSeries( ) functions
## 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: 'xts'
## The following objects are masked from 'package:dplyr':
## 
##     first, last
## Loading required package: TTR
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
## Version 0.4-0 included new data defaults. See ?getSymbols.
library(tseries) # for the ad.test( ) function
library(urca) # for the ur.df( ) function
library(wbstats) # for the wb( ) function
library(readxl) # for the read_xlsx() function
library(wooldridge)
library(psych) # for the describe() function
library(tseries) # for the jarque.bera.test() function
library(lmtest) # for bptest(), coeftest(), dwtest() & bgtest() functions
library(sandwich) # for vcovHC() function
library(dplyr) # for lag() function
library(car)
## Loading required package: carData
## 
## Attaching package: 'car'
## The following object is masked from 'package:psych':
## 
##     logit
## The following object is masked from 'package:dplyr':
## 
##     recode
library(data.table)
## 
## Attaching package: 'data.table'
## The following objects are masked from 'package:xts':
## 
##     first, last
## The following objects are masked from 'package:dplyr':
## 
##     between, first, last
library(stats)
library(forecast)
library(FinTS) # for the ArchTest( ) function
## 
## Attaching package: 'FinTS'
## The following object is masked from 'package:forecast':
## 
##     Acf
library(rugarch) # for the ugarchspec( ), ugarchfit( ), infocriteria( ), uncvariance( ), sigma( ) functions
## Loading required package: parallel
## 
## Attaching package: 'rugarch'
## The following object is masked from 'package:stats':
## 
##     sigma

1. Resumen ejecutivo

HOSUSA es una empresa líder en su sector, siendo una de las más importantes enlatadoras de alimentos y conservas en el país. Como toda empresa grande y bien administrada, el área de finanzas se enfrenta al reto de preveer con anterioridad las compras de inventario para los siguientes periodos, las ventas, entre otras cosas. No obstante, al estar tomando seguidamente decisiones de inversión y financiamiento, saben que su panorama puede beneficiarse o afectarse con dos variables muy importantes: el tipo de cambio y la inflación. Si la empresa logra tener una noción de cómo se comportarán estos datos en el futuro próximo, podrá tomar mejores decisiones financieras.

Dicho proceso se comenzó obteniendo los datos de la inflación y tipo de cambio dólar-peso mensual de los últimos 5 años. A través de la página del INEGI, y Yahoo Finance, se dio con la información. Ya que un modelo de predicción siempre es mejor con datos estacionarios, se probó la estacionaridad de ambas variables. Ninguna variable resultó estacionaria en niveles, por lo que a través de la diferenciación, se cambió este resultado. Utilizando las pruebas estadísticas de unit root y adf, se comprobaron los resultados. Así mismo, sabiendo que en niveles ambas variables no son estacionarias, se corrió un modelo de regresión que nos mostró que las variables están cointegradas, aunque por muy poco.

Seguidamente, el mejor modelo de predicción para ambas variables se logró con un ARIMA. En el caso de la inflación, un ARIMA (0,1,1) nos mostró que la inflación mensual se mantendrá constante en 0.53% para los siguientes meses; dicho modelo fue comprobado al tener residuales estacionarios. Así mismo, aunque la inflación mostró efectos ARCH, ningún modelo GARCH fue útil para predecir la volatilidad de dicha variable. El ARIMA resulta la mejor alternativa para que HOSUSA conozca que pasará con el fenómeno que causa una alza de precios general en el país.

Para el tipo de cambio, un modelo ARIM (0,1,0) resultó el más conveniente para predecir el USDMXN. Dicho modelo también fue puesto a prueba, y al tener residuales estacionarios, nos permitió conocer que el tipo de cambio se mantendrá constante en $20.24 pesos por dólar. Debido a que el tipo de cambio no mostró efectos ARCH, este es el modelo que más información clara y válida le puede dar a la empresa. HOSUSA determinará si este precio del dólar es conveniente para mantener sus posibles fuentes de financiamiento en dólares, si requerirán la contratación del swap o algún otro instrumento financiero de cobertura, o si podrían esperar ganancias/ pérdidas cambiarias.

2. Problemática

La empresa “HOSUSA Hojalatera del Sur, S.A. de C.V.” es una de las más importantes enlatadoras de alimentos y conservas en el país. Si bien, las empresas de mayor tamaño suelen tener empacadoras de distintos tipos dentro de sus plantas de producción, algunas llevan sus productos a las instalaciones de HOSUSA para el enlatado y etiquetado de los mismos.

Las latas que HOSUSA fabrica están hechas de acero y estaño, materiales que adquiere en distintas partes: el estaño es importado en su mayoría, mientras que el acero es de producción nacional. En HOSUSA se procesan los materiales para lograr un producto de calidad, tanto en diseño, como en resistencia y capacidad de conservación de los alimentos. Como información adicional, todos los clientes de HOSUSA son mexicanos y, aunque algunos exportan sus productos, Hojalatera del Sur no forma parte de esos procesos.

En junio del año pasado, HOSUSA te ha contratado como su gerente financiero. A partir de ese momento, participaste en la planeación de las compras de insumos, en las proyecciones de ventas, en el manejo de información financiera, así como en las decisiones de inversión y financiamiento, por lo que te es de suma importancia conocer las fluctuaciones en la tasa de interés, directamente asociadas con la inflación. En agosto se convocó a una junta el mes siguiente, donde se hablaría de las proyecciones de ventas y adquisiciones, de las necesidades futuras y de temas varios referentes a la planeación que has venido realizando. En ese momento, te diste cuenta de que necesitas preparar un reporte adecuado, por lo que inicias un proceso para completar la información que requerirás en la reunión.

3. Lectura de datos

Lo primero que hacemos es leer los datos del Excel y almacenarlos en 2 variables distintas, debido a que hay una hoja para inflación y otra para tipo de cambio:

# Leemos la info del excel
inflacion <- read_xlsx("DatosEvidenciaST.xlsx", sheet = "Inflación")
head(inflacion, 5)
## # A tibble: 5 x 3
##   Periodos `Mensual anualizada` Mensual
##   <chr>                   <dbl>   <dbl>
## 1 2016/01                  2.61   0.218
## 2 2016/02                  2.87   0.239
## 3 2016/03                  2.6    0.217
## 4 2016/04                  2.54   0.212
## 5 2016/05                  2.6    0.217
TC <- read_xlsx("DatosEvidenciaST.xlsx", sheet = "Tipo de cambio")
head(TC, 5)
## # A tibble: 5 x 3
##   Periodos USDMXN `Rendimiento logarítmico`
##   <chr>     <dbl>                     <dbl>
## 1 2016/01    18.1                  NA      
## 2 2016/02    18.1                   0.00138
## 3 2016/03    17.3                  -0.0483 
## 4 2016/04    17.2                  -0.00613
## 5 2016/05    18.5                   0.0726

4. Estacionaridad

inflacionMensual = na.omit(inflacion$Mensual)
tipoCambio = TC$USDMXN
tipoCambioDif = na.omit(TC$`Rendimiento logarítmico`)
plot(inflacionMensual, type = "l")

plot(tipoCambio, type = "l")

plot(tipoCambioDif, type = "l")

Al graficar las 3 variables creadas, podemos notar cosas interesantes. Primeramente, la inflación parece más un random walk que white noise, al no estar oscilando en el 0. El tipo de cambio en niveles también se ve como un random walk, aunque al graficar los rendimiento logarítmicos, vemos que estos sí se mueven más en la línea del 0, pareciendo white noise

summary(ur.df(inflacionMensual, type = "drift", selectlags = "AIC"))
## 
## ############################################### 
## # Augmented Dickey-Fuller Test Unit Root Test # 
## ############################################### 
## 
## Test regression drift 
## 
## 
## Call:
## lm(formula = z.diff ~ z.lag.1 + 1 + z.diff.lag)
## 
## Residuals:
##       Min        1Q    Median        3Q       Max 
## -0.093518 -0.018484  0.001053  0.017353  0.103677 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)  
## (Intercept)  0.02829    0.01617   1.750   0.0853 .
## z.lag.1     -0.07158    0.04471  -1.601   0.1147  
## z.diff.lag   0.33809    0.13349   2.533   0.0140 *
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.03576 on 59 degrees of freedom
## Multiple R-squared:  0.1199, Adjusted R-squared:  0.09008 
## F-statistic:  4.02 on 2 and 59 DF,  p-value: 0.02309
## 
## 
## Value of test-statistic is: -1.601 1.5695 
## 
## Critical values for test statistics: 
##       1pct  5pct 10pct
## tau2 -3.51 -2.89 -2.58
## phi1  6.70  4.71  3.86

Al aplicar la prueba de unit root a la inflación mensual, vemos que los datos no son estacionarios. El resultado de -1.60 no se encuentra a la izquierda de -3.51, por lo que no es estacionaria.

adf.test(inflacionMensual, k=1)
## 
##  Augmented Dickey-Fuller Test
## 
## data:  inflacionMensual
## Dickey-Fuller = -1.5371, Lag order = 1, p-value = 0.7625
## alternative hypothesis: stationary

Confirmamos la información anterior con la prueba “adf”; la inflación mensual no es estacionaria al tener un p-value mayor a 0.05.

inflacionDif <- diff(inflacionMensual) ## diferenciamos la inflación

summary(ur.df(inflacionDif, type = "drift", selectlags = "AIC"))
## 
## ############################################### 
## # Augmented Dickey-Fuller Test Unit Root Test # 
## ############################################### 
## 
## Test regression drift 
## 
## 
## Call:
## lm(formula = z.diff ~ z.lag.1 + 1 + z.diff.lag)
## 
## Residuals:
##       Min        1Q    Median        3Q       Max 
## -0.108899 -0.015521  0.002061  0.012691  0.108504 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  0.003999   0.004697   0.851 0.398120    
## z.lag.1     -0.701668   0.178189  -3.938 0.000223 ***
## z.diff.lag   0.024711   0.143618   0.172 0.863991    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.03657 on 58 degrees of freedom
## Multiple R-squared:  0.3036, Adjusted R-squared:  0.2796 
## F-statistic: 12.65 on 2 and 58 DF,  p-value: 0.00002768
## 
## 
## Value of test-statistic is: -3.9378 7.907 
## 
## Critical values for test statistics: 
##       1pct  5pct 10pct
## tau2 -3.51 -2.89 -2.58
## phi1  6.70  4.71  3.86

Para arreglar el problema anterior, se diferenció la inflación mensual. Este proceso resulta muy efectivo, ya que al hacer de nuevo la prueba de unit root, vemos que ahora sí el resultado de -3.93 se encuentra a la izquierda de -3.51. Finalmente ya tenemos la inflación estacionaria.

adf.test(inflacionDif, k=1)
## 
##  Augmented Dickey-Fuller Test
## 
## data:  inflacionDif
## Dickey-Fuller = -3.8448, Lag order = 1, p-value = 0.02228
## alternative hypothesis: stationary

Confirmamos que la inflación ya es estacionaria al diferenciarla 1 vez, con un p-value de 0.02.

plot(inflacionDif, type = "l")

Similarmente al tipo de cambio diferenciado, vemos que la inflación ya diferenciada también logra ahora oscilar en la línea del 0, y se aleja de tener una apariencia de random walk.

summary(ur.df(tipoCambio, type = "drift", selectlags = "AIC"))
## 
## ############################################### 
## # Augmented Dickey-Fuller Test Unit Root Test # 
## ############################################### 
## 
## Test regression drift 
## 
## 
## Call:
## lm(formula = z.diff ~ z.lag.1 + 1 + z.diff.lag)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -1.2564 -0.5616 -0.0779  0.3589  4.0071 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)   
## (Intercept)  4.20843    1.56494   2.689   0.0093 **
## z.lag.1     -0.21279    0.07960  -2.673   0.0097 **
## z.diff.lag   0.07681    0.12885   0.596   0.5534   
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.8557 on 59 degrees of freedom
## Multiple R-squared:  0.1086, Adjusted R-squared:  0.07843 
## F-statistic: 3.596 on 2 and 59 DF,  p-value: 0.03361
## 
## 
## Value of test-statistic is: -2.6733 3.625 
## 
## Critical values for test statistics: 
##       1pct  5pct 10pct
## tau2 -3.51 -2.89 -2.58
## phi1  6.70  4.71  3.86

Al aplicar la prueba UR al tipo de cambio en niveles, vemos que este no es estacionario, aunque se queda muy cerca con un valor de -2.67, estando entre un 90 y 95% de confianza.

adf.test(tipoCambio, k =1)
## 
##  Augmented Dickey-Fuller Test
## 
## data:  tipoCambio
## Dickey-Fuller = -3.4123, Lag order = 1, p-value = 0.06186
## alternative hypothesis: stationary

Confirmamos lo anterior con la prueba ADF, la cual nos revela que el tipo de cambio se queda MUY CERCA de ser estacionario en niveles, con un p-value de 0.06.

summary(ur.df(tipoCambioDif, type = "drift", selectlags = "AIC"))
## 
## ############################################### 
## # Augmented Dickey-Fuller Test Unit Root Test # 
## ############################################### 
## 
## Test regression drift 
## 
## 
## Call:
## lm(formula = z.diff ~ z.lag.1 + 1 + z.diff.lag)
## 
## Residuals:
##       Min        1Q    Median        3Q       Max 
## -0.074979 -0.026396 -0.003287  0.024296  0.187761 
## 
## Coefficients:
##              Estimate Std. Error t value     Pr(>|t|)    
## (Intercept)  0.003025   0.005620   0.538        0.592    
## z.lag.1     -1.194016   0.185251  -6.445 0.0000000249 ***
## z.diff.lag   0.151787   0.128693   1.179        0.243    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.04379 on 58 degrees of freedom
## Multiple R-squared:  0.5346, Adjusted R-squared:  0.5186 
## F-statistic: 33.32 on 2 and 58 DF,  p-value: 0.0000000002322
## 
## 
## Value of test-statistic is: -6.4454 20.7752 
## 
## Critical values for test statistics: 
##       1pct  5pct 10pct
## tau2 -3.51 -2.89 -2.58
## phi1  6.70  4.71  3.86

Ahora, aplicamos las mismas pruebas al tipo de cambio en rendimientos logarítmicos. Ya diferenciado, y con un resultado de -6.44, muy a la izquierda de -3.51, podemos confirmar que el tipo de cambio en rendimientos log es estacionario

adf.test(tipoCambioDif)
## Warning in adf.test(tipoCambioDif): p-value smaller than printed p-value
## 
##  Augmented Dickey-Fuller Test
## 
## data:  tipoCambioDif
## Dickey-Fuller = -4.6228, Lag order = 3, p-value = 0.01
## alternative hypothesis: stationary

Con la prueba ADF confirmamos que el tipo de cambio es estacionario con un resultado de 0.01 en el p-value.

6. Cointegración

Para hacer esta prueba, primeramente hacemos un modelo de regresión entre el tipo de cambio y la inflación mensual, siendo el dólar-peso la variable dependiente:

#Modelo de regresión 
regress1 <- lm(tipoCambio ~inflacionMensual)
summary(regress1)
## 
## Call:
## lm(formula = tipoCambio ~ inflacionMensual)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -2.9018 -0.7946 -0.3342  0.7683  3.9835 
## 
## Coefficients:
##                  Estimate Std. Error t value            Pr(>|t|)    
## (Intercept)        20.788      0.612  33.969 <0.0000000000000002 ***
## inflacionMensual   -3.362      1.683  -1.998              0.0501 .  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 1.401 on 62 degrees of freedom
## Multiple R-squared:  0.06049,    Adjusted R-squared:  0.04534 
## F-statistic: 3.992 on 1 and 62 DF,  p-value: 0.05011

De momento, podemos notar que el modelo es poco significativo; la inflación mensual no es significativa y la R2 es de apenas 4%.

summary(ur.df(regress1$residuals, type = "drift", selectlags = "AIC"))
## 
## ############################################### 
## # Augmented Dickey-Fuller Test Unit Root Test # 
## ############################################### 
## 
## Test regression drift 
## 
## 
## Call:
## lm(formula = z.diff ~ z.lag.1 + 1 + z.diff.lag)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -1.4033 -0.5511 -0.0208  0.4018  3.8426 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)   
## (Intercept)  0.04864    0.10772   0.452  0.65327   
## z.lag.1     -0.22652    0.08227  -2.754  0.00782 **
## z.diff.lag   0.05860    0.12841   0.456  0.64982   
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.847 on 59 degrees of freedom
## Multiple R-squared:  0.1159, Adjusted R-squared:  0.08594 
## F-statistic: 3.868 on 2 and 59 DF,  p-value: 0.02641
## 
## 
## Value of test-statistic is: -2.7535 3.9017 
## 
## Critical values for test statistics: 
##       1pct  5pct 10pct
## tau2 -3.51 -2.89 -2.58
## phi1  6.70  4.71  3.86

Para determinar la validez del modelo, aplicamos la prueba UR a los residuales de la regresión, y podemos notar que estos se quedan muy cerca de ser estacionarios, con un resultado de -2.7, quedando fuera del 95% de confianza, aunque muy cerca. PON QUE NO HAY COINTEGRACION

7. Modelo de proyección - Inflación

acf(inflacionDif, lag.max = 40, plot = T)

Al analizar el gráfico ACF de la inflación diferenciada, vemos sólo un rezago algo significativo, alrededor del punto 12. Aunque no es tan clara la disminución exponencial de los rezagos, sí se puede observar una ligera reducción en los mismos.

pacf(inflacionDif, lag.max = 40, plot = T)

Utilizando ahora el PACF, vemos que los rezagos sí disminuyen más poco a poco, así como que un rezago sí sobresale.

auto.arima(inflacionMensual)
## Series: inflacionMensual 
## ARIMA(0,1,1) 
## 
## Coefficients:
##          ma1
##       0.3156
## s.e.  0.1228
## 
## sigma^2 estimated as 0.001287:  log likelihood=120.7
## AIC=-237.4   AICc=-237.2   BIC=-233.12

Dejando libre la opción de que haya estacionalidad, esta función nos revela que el mejor modelo para la inflación mensual NO diferenciada, es el de 1 nivel de diferenciación y 1 MA (0,1,1). Esto es lógico, ya que anteriormente vimos que era necesario diferenciar la inflación, así como coincide con los gráficos anteriores.

modeloinfl <- arima(inflacionMensual, order = c(0,1,1))
modinflSum <- summary(modeloinfl)
## 
## Call:
## arima(x = inflacionMensual, order = c(0, 1, 1))
## 
## Coefficients:
##          ma1
##       0.3156
## s.e.  0.1228
## 
## sigma^2 estimated as 0.001267:  log likelihood = 120.7,  aic = -237.4
## 
## Training set error measures:
##                       ME       RMSE        MAE       MPE     MAPE      MASE
## Training set 0.003784472 0.03531196 0.02443581 0.6329725 7.449378 0.9222901
##                     ACF1
## Training set 0.001034863

Creamos una variable y almacenamos el modelo con el arima sugerido para la inflación NO estacionaria.

summary(ur.df(modeloinfl$residuals, type = "trend", selectlags = "AIC"))
## 
## ############################################### 
## # Augmented Dickey-Fuller Test Unit Root Test # 
## ############################################### 
## 
## Test regression trend 
## 
## 
## Call:
## lm(formula = z.diff ~ z.lag.1 + 1 + tt + z.diff.lag)
## 
## Residuals:
##       Min        1Q    Median        3Q       Max 
## -0.107113 -0.016239  0.002754  0.013055  0.111689 
## 
## Coefficients:
##                Estimate  Std. Error t value  Pr(>|t|)    
## (Intercept)  0.00009671  0.00975780   0.010     0.992    
## z.lag.1     -0.94095839  0.21068450  -4.466 0.0000374 ***
## tt           0.00010437  0.00026236   0.398     0.692    
## z.diff.lag  -0.05046470  0.14503221  -0.348     0.729    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.03673 on 58 degrees of freedom
## Multiple R-squared:  0.4744, Adjusted R-squared:  0.4472 
## F-statistic: 17.45 on 3 and 58 DF,  p-value: 0.00000003416
## 
## 
## Value of test-statistic is: -4.4662 6.9567 10.359 
## 
## Critical values for test statistics: 
##       1pct  5pct 10pct
## tau3 -4.04 -3.45 -3.15
## phi2  6.50  4.88  4.16
## phi3  8.73  6.49  5.47

De nuevo, buscando validar el modelo recién creado, probamos la estacionaridad de los residuales. La prueba UR nos dice que sí son estacionarios.

Sabiendo que tenemos un modelo válido, es posible hacer un pronóstico:

modinflpred <- forecast(modeloinfl, h = 5)
modinflpred
##    Point Forecast     Lo 80     Hi 80     Lo 95     Hi 95
## 65      0.5364666 0.4908547 0.5820784 0.4667093 0.6062238
## 66      0.5364666 0.4610937 0.6118394 0.4211937 0.6517394
## 67      0.5364666 0.4401250 0.6328081 0.3891249 0.6838082
## 68      0.5364666 0.4229663 0.6499669 0.3628828 0.7100503
## 69      0.5364666 0.4080806 0.6648525 0.3401172 0.7328159

Utilizando la función “forecast”, predecimos 5 periodos para adelante de la inflación mensual.

Aquí es importante observar que el punto pronosticado no varia, siendo siempre el mismo 0.53%. Esto ocurre ya que no contamos con un AR, por lo que nuestro modelo se basa siempre en el punto anterior. De nuevo, en base a este modelo, la inflación se mantendrá en alrededor de 0.53% para los siguientes meses.

autoplot(modinflpred)

De nuevo, ahora con el apoyo visual, podemos ver que este modelo se nota plano al tener un MA de corto plazo; así son estos modelos. Sin embargo, el intervalo de confianza (figura morada) sí muestra la posible variación de la inflación mensual.

8. GARCH - Inflación:

plot(density(inflacionDif), main = "Density plot of logreturns")

El density plot da señales de efectos GARCH, con una curva muy similar a la distribución normal.

ArchTest(inflacionDif)
## 
##  ARCH LM-test; Null hypothesis: no ARCH effects
## 
## data:  inflacionDif
## Chi-squared = 24.675, df = 12, p-value = 0.01644

Finalmente, aplicamos la prueba definitiva, y al mostrar un resultado menor a 0.05, rechazamos la hipótesis nula de que no hay efectos ARCH.

Toda la información anterior nos revela que desarrollar un modelo GARCH para la inflación sería apropiado.

Como sabemos, el modelo GARCH se compone de una ecuación de media y una de varianza. La ecuación de media es el ARIMA que ya hicimos y que fue comprobado, así como utilizado para pronosticar; para la inflación usamos un ARIMA (0,1,1). Este será el mismo modelo que usaremos para la ecuación de media de la inflación.

Sin embargo, para la ecuación de varianza, hay que encontrar el modelo apropiado que pueda predecir la volatilidad de la inflación. Esto lo haremos de la siguiente forma:

garchSpec <- ugarchspec(mean.model = list(armaOrder = c(0, 1)),
                        variance.model = list(model = "sGARCH", 
                                          garchOrder = c(1, 1)))

mod0111 <- ugarchfit(spec = garchSpec, data = inflacionDif)
## Warning in .sgarchfit(spec = spec, data = data, out.sample = out.sample, : 
## ugarchfit-->waring: using less than 100 data
##  points for estimation
garchSpec <- ugarchspec(mean.model = list(armaOrder = c(0, 1)),
                        variance.model = list(model = "sGARCH", 
                                          garchOrder = c(1, 0)))

mod0110 <- ugarchfit(spec = garchSpec, data = inflacionDif)
## Warning in .sgarchfit(spec = spec, data = data, out.sample = out.sample, : 
## ugarchfit-->waring: using less than 100 data
##  points for estimation
garchSpec <- ugarchspec(mean.model = list(armaOrder = c(0, 1)),
                        variance.model = list(model = "sGARCH", 
                                          garchOrder = c(0, 1)))

mod0101 <- ugarchfit(spec = garchSpec, data = inflacionDif)
## Warning in .sgarchfit(spec = spec, data = data, out.sample = out.sample, : 
## ugarchfit-->waring: using less than 100 data
##  points for estimation
infocriteria(mod0111)
##                       
## Akaike       -3.696433
## Bayes        -3.526343
## Shibata      -3.707838
## Hannan-Quinn -3.629536
infocriteria(mod0110)
##                       
## Akaike       -3.733521
## Bayes        -3.597449
## Shibata      -3.740960
## Hannan-Quinn -3.680003
infocriteria(mod0101)
##                       
## Akaike       -3.728179
## Bayes        -3.592107
## Shibata      -3.735618
## Hannan-Quinn -3.674661
# mod1301 didn't converge, but it might for other stock or time series
# infocriteria(mod1301) 

A través de la función “infocriteria”, obtenemos diferentes datos acerca de los modelos que recién creamos. Dentro de esta información, buscamos el modelo con el MENOR valor de Akaike. Si observamos, el modelo 0101, es el más indicado. Sin embargo, el modelo 0111 queda muy cerca.

Debido a los resultados anteriores, es conveniente evaluar ambos modelos (0111 y 0101) para determinar si alguno de ellos es estadísticamente significativo para pronosticar. Las condiciones para que un modelo sea significativo son: -Valor de alpha y beta menor a 1 -Omega positivo -Coeficientes significativos

mod0111
## 
## *---------------------------------*
## *          GARCH Model Fit        *
## *---------------------------------*
## 
## Conditional Variance Dynamics    
## -----------------------------------
## GARCH Model  : sGARCH(1,1)
## Mean Model   : ARFIMA(0,0,1)
## Distribution : norm 
## 
## Optimal Parameters
## ------------------------------------
##         Estimate  Std. Error   t value Pr(>|t|)
## mu      0.005162    0.005722   0.90222 0.366942
## ma1     0.299829    0.125796   2.38346 0.017151
## omega   0.000006    0.000007   0.94442 0.344955
## alpha1  0.000000    0.022579   0.00000 1.000000
## beta1   0.999000    0.002856 349.75761 0.000000
## 
## Robust Standard Errors:
##         Estimate  Std. Error  t value Pr(>|t|)
## mu      0.005162    0.005288  0.97619 0.328968
## ma1     0.299829    0.089900  3.33515 0.000853
## omega   0.000006    0.000007  0.86943 0.384612
## alpha1  0.000000    0.014648  0.00000 1.000000
## beta1   0.999000    0.011669 85.61275 0.000000
## 
## LogLikelihood : 121.4376 
## 
## Information Criteria
## ------------------------------------
##                     
## Akaike       -3.6964
## Bayes        -3.5263
## Shibata      -3.7078
## Hannan-Quinn -3.6295
## 
## Weighted Ljung-Box Test on Standardized Residuals
## ------------------------------------
##                         statistic p-value
## Lag[1]                   0.001758  0.9666
## Lag[2*(p+q)+(p+q)-1][2]  0.060797  1.0000
## Lag[4*(p+q)+(p+q)-1][5]  0.615897  0.9876
## d.o.f=1
## H0 : No serial correlation
## 
## Weighted Ljung-Box Test on Standardized Squared Residuals
## ------------------------------------
##                         statistic p-value
## Lag[1]                     0.1213  0.7276
## Lag[2*(p+q)+(p+q)-1][5]    0.5650  0.9472
## Lag[4*(p+q)+(p+q)-1][9]    1.4530  0.9593
## d.o.f=2
## 
## Weighted ARCH LM Tests
## ------------------------------------
##             Statistic Shape Scale P-Value
## ARCH Lag[3]    0.3889 0.500 2.000  0.5329
## ARCH Lag[5]    0.8223 1.440 1.667  0.7863
## ARCH Lag[7]    1.3668 2.315 1.543  0.8477
## 
## Nyblom stability test
## ------------------------------------
## Joint Statistic:  9.0944
## Individual Statistics:             
## mu     0.1686
## ma1    0.3271
## omega  0.2198
## alpha1 0.3445
## beta1  0.1863
## 
## Asymptotic Critical Values (10% 5% 1%)
## Joint Statistic:          1.28 1.47 1.88
## Individual Statistic:     0.35 0.47 0.75
## 
## Sign Bias Test
## ------------------------------------
##                    t-value   prob sig
## Sign Bias          0.08397 0.9334    
## Negative Sign Bias 0.32397 0.7471    
## Positive Sign Bias 0.22860 0.8200    
## Joint Effect       0.15725 0.9842    
## 
## 
## Adjusted Pearson Goodness-of-Fit Test:
## ------------------------------------
##   group statistic p-value(g-1)
## 1    20     31.29      0.03755
## 2    30     36.52      0.15880
## 3    40     58.27      0.02425
## 4    50     58.43      0.16758
## 
## 
## Elapsed time : 0.186666

Del modelo 0111 podemos ver que las primeras 2 condiciones se cumplen, pero no todos los coeficientes son significativos; algunos quedan muy lejanos de serlo. Por lo tanto, este modelo no es válido.

mod0101
## 
## *---------------------------------*
## *          GARCH Model Fit        *
## *---------------------------------*
## 
## Conditional Variance Dynamics    
## -----------------------------------
## GARCH Model  : sGARCH(0,1)
## Mean Model   : ARFIMA(0,0,1)
## Distribution : norm 
## 
## Optimal Parameters
## ------------------------------------
##        Estimate  Std. Error   t value Pr(>|t|)
## mu     0.005162    0.005721   0.90230 0.366897
## ma1    0.299829    0.123544   2.42690 0.015228
## omega  0.000006    0.000014   0.44106 0.659171
## beta1  0.999000    0.008098 123.36568 0.000000
## 
## Robust Standard Errors:
##        Estimate  Std. Error  t value Pr(>|t|)
## mu     0.005162    0.005280   0.9777 0.328225
## ma1    0.299829    0.097026   3.0902 0.002000
## omega  0.000006    0.000002   2.8967 0.003771
## beta1  0.999000    0.007754 128.8337 0.000000
## 
## LogLikelihood : 121.4376 
## 
## Information Criteria
## ------------------------------------
##                     
## Akaike       -3.7282
## Bayes        -3.5921
## Shibata      -3.7356
## Hannan-Quinn -3.6747
## 
## Weighted Ljung-Box Test on Standardized Residuals
## ------------------------------------
##                         statistic p-value
## Lag[1]                   0.001758  0.9666
## Lag[2*(p+q)+(p+q)-1][2]  0.060797  1.0000
## Lag[4*(p+q)+(p+q)-1][5]  0.615897  0.9876
## d.o.f=1
## H0 : No serial correlation
## 
## Weighted Ljung-Box Test on Standardized Squared Residuals
## ------------------------------------
##                         statistic p-value
## Lag[1]                     0.1213  0.7276
## Lag[2*(p+q)+(p+q)-1][2]    0.1232  0.9037
## Lag[4*(p+q)+(p+q)-1][5]    0.5650  0.9472
## d.o.f=1
## 
## Weighted ARCH LM Tests
## ------------------------------------
##             Statistic Shape Scale P-Value
## ARCH Lag[2]  0.003439 0.500 2.000  0.9532
## ARCH Lag[4]  0.387141 1.397 1.611  0.9040
## ARCH Lag[6]  0.896761 2.222 1.500  0.9140
## 
## Nyblom stability test
## ------------------------------------
## Joint Statistic:  2.4488
## Individual Statistics:            
## mu    0.1686
## ma1   0.3271
## omega 0.2198
## beta1 0.1863
## 
## Asymptotic Critical Values (10% 5% 1%)
## Joint Statistic:          1.07 1.24 1.6
## Individual Statistic:     0.35 0.47 0.75
## 
## Sign Bias Test
## ------------------------------------
##                    t-value   prob sig
## Sign Bias          0.08397 0.9334    
## Negative Sign Bias 0.32397 0.7471    
## Positive Sign Bias 0.22860 0.8200    
## Joint Effect       0.15725 0.9842    
## 
## 
## Adjusted Pearson Goodness-of-Fit Test:
## ------------------------------------
##   group statistic p-value(g-1)
## 1    20     31.29      0.03755
## 2    30     36.52      0.15880
## 3    40     58.27      0.02425
## 4    50     58.43      0.16758
## 
## 
## Elapsed time : 0.1927471

El modelo 0101 pasa por lo mismo que el 0111, ya que la 3era condición no se cumple; este modelo tampoco será útil para pronosticar.

Hasta este punto, aunque la inflación mostró efectos ARCH, ningún modelo GARCH fue válido como para ser utilizado para predecir. Aunque la ecuación de media es válida, la ecuación de varianza no lo es; en otras palabras, no es posible pronosticar la volatilidad de la inflación. Esto no es necesariamente algo negativo, simplemente nos indica que el ARIMA (0,1,1) será el modelo con el cual trabajaremos los valores futuros de la inflación.

9. Modelo de proyección - Tipo de cambio

pacf(tipoCambioDif, lag.max = 100, plot = T)

Notamos claramente que los rezagos van disminuyendo poco a poco. Sólo hay uno que resalta, alrededor del lugar 15, aunque no de una forma muy significativa

acf(tipoCambioDif, lag.max = 100, plot = T)

Ahora, el ACF de nuevo nos demuestra como los rezagos van disminuyendo significativamente. En este caso, no se identifica alguno que sea significativo.

auto.arima(tipoCambio)
## Series: tipoCambio 
## ARIMA(0,1,0) 
## 
## sigma^2 estimated as 0.7705:  log likelihood=-81.18
## AIC=164.36   AICc=164.43   BIC=166.5

Al apoyarse en la función “auto.arima” para encontrar el mejor modelo para el tipo de cambio NO diferenciado, vemos que obtenemos un modelo (0,1,0). Esto hace sentido, ya que en los gráficos anteriores vimos que ningún rezago era significativo, lo único que resalta el modelo es el nivel de diferenciación para el tipo de cambio.

modTC <- arima(tipoCambio, order = c(0,1,0))
modTCSum <- summary(modTC)
## 
## Call:
## arima(x = tipoCambio, order = c(0, 1, 0))
## 
## 
## sigma^2 estimated as 0.7705:  log likelihood = -81.18,  aic = 164.36
## 
## Training set error measures:
##                      ME     RMSE       MAE        MPE     MAPE      MASE
## Training set 0.03358766 0.870897 0.6099877 0.08598028 3.043078 0.9848319
##                    ACF1
## Training set -0.0260312

Con la variable mod2, almacenamos el modelo con el arima (0,1,0) para el tipo de cambio NO estacionario.

summary(ur.df(modTC$residuals, type = "trend", selectlags = "AIC"))
## 
## ############################################### 
## # Augmented Dickey-Fuller Test Unit Root Test # 
## ############################################### 
## 
## Test regression trend 
## 
## 
## Call:
## lm(formula = z.diff ~ z.lag.1 + 1 + tt + z.diff.lag)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -1.4581 -0.5125 -0.0722  0.4797  4.0935 
## 
## Coefficients:
##              Estimate Std. Error t value     Pr(>|t|)    
## (Intercept)  0.092308   0.237268   0.389        0.699    
## z.lag.1     -1.202875   0.185791  -6.474 0.0000000223 ***
## tt          -0.001524   0.006389  -0.239        0.812    
## z.diff.lag   0.171317   0.129682   1.321        0.192    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.9 on 58 degrees of freedom
## Multiple R-squared:  0.5274, Adjusted R-squared:  0.503 
## F-statistic: 21.58 on 3 and 58 DF,  p-value: 0.000000001644
## 
## 
## Value of test-statistic is: -6.4743 13.9772 20.9642 
## 
## Critical values for test statistics: 
##       1pct  5pct 10pct
## tau3 -4.04 -3.45 -3.15
## phi2  6.50  4.88  4.16
## phi3  8.73  6.49  5.47

Con el fin de validar el modelo 0,1,0 para el tipo de cambio, probamos la estacionaridad de los residuales. Con un resultado de -6.4, los residuales son estacionarios.

modTCpred <- forecast(modTC, h = 5)
modTCpred
##    Point Forecast    Lo 80    Hi 80    Lo 95    Hi 95
## 65        20.2415 19.11658 21.36642 18.52109 21.96191
## 66        20.2415 18.65062 21.83238 17.80847 22.67453
## 67        20.2415 18.29308 22.18992 17.26165 23.22135
## 68        20.2415 17.99166 22.49134 16.80067 23.68233
## 69        20.2415 17.72611 22.75689 16.39454 24.08846

A través de la función forecast, predecimos 5 periodos para adelante del tipo de cambio. Vemos que el pronóstico queda siempre en 20.24, lo cual sucede por la configuración del ARIMA; el modelo se queda con el valor anterior, siendo este el más útil para predecir el siguiente.

autoplot(modTCpred)

Similarmente a la inflación, al graficar el tipo de cambio, vemos una línea recta causada por la configuración del modelo. No obstante, el intervalo de confianza sí varía.

Nuestro modelo ARIMA 0,1,0 nos revela que el tipo de cambio se mantendrá en alrededor de 20.24 pesos por dólar para los siguientes periodos.

10. GARCH - Tipo de cambio

plot(density(tipoCambioDif), main = "Density plot of logreturns")

Ahora, el gráfico de densidad del tipo de cambio diferenciado nos muestra algo similar a una distribución normal, aunque no tan estética como la de la inflación; vemos una cola derecha muy larga.

ArchTest(tipoCambioDif)
## 
##  ARCH LM-test; Null hypothesis: no ARCH effects
## 
## data:  tipoCambioDif
## Chi-squared = 2.8959, df = 12, p-value = 0.9962

La prueba ARCH nos confirma lo anterior: el tipo de cambio no tiene efectos, y por lo tanto un modelo GARCH no sería adecuado para predecir.

Hasta este punto, de forma similar a como sucedió con la inflación, nos quedaremos con nuestro modelo ARIMA (0,1,0) para dar con los valores próximos del USDMXN.

11. Conclusiones y recomendaciones

En resumen, apoyándonos de las pruebas estadísticas vistas en este ejercicio, la inflación y el tipo de cambio no son variables estacionarias en niveles. A través de la diferenciación, pudimos convertir estos datos en unos semejantes a lo que sería “white noise”. Habiendo hecho esto, fue interesante descubrir que, sería posible concluir que la inflación y el tipo de cambio son variables cointegradas, y decimos “sería posible”, ya que las pruebas lo confirman por muy poco, como vimos con el modelo de regresión hecho.

A través de pruebas visuales, y con el apoyo de la función “auto-arima”, se determinó que la inflación puede ser pronosticada con un ARIMA (0,1,1). Dicho modelo pasó las pruebas estadísticas, y nos mostró que la inflación mensual se mantendrá en 0.53% para los siguientes periodos. Dicho modelo no pudo ser superado por uno GARCH; de forma interesante, aunque la variable mostró efectos ARCH cuando fue puesta a prueba con métodos visuales y estadísticos, ningún modelo resultó significativo para predecir la volatilidad de dicha variable. Por esta razón, el ARIMA construido anteriormente, será la mejor opción de predicción.

Para el caso del tipo de cambio, las pruebas visuales y la función “auto.arima” nos arrojó un modelo ideal de (0,1,0). Interesantemente, este modelo sólo nos indica un nivel de diferenciación, que fue lo que se le hizo al tipo de cambio para hacerlo estacionario desde el inicio. El modelo fue validado y nos mostró que el tipo de cambio se mantendrá también en 20.24 para los siguientes períodos. Por último, un modelo GARCH no fue necesario, ya que la variable no mostró efectos ARCH en ninguna prueba realizada.

Para la elaboración de este ejercicio, no hubieron mayores dificultades. Los datos de inflación y tipo de cambio eran correctos y no necesitaron ningún tratamiento. Durante el proceso para dar con el mejor modelo de predicción, ambas variables fueron sometidas a diversas pruebas y procedimientos que no presentaron mayor complicación técnica. Más que una dificultad técnica, este ejercicio requeririó tener una comprensión teórica acerca de los temas puestos en prueba, para tener una correcta interpretación de los resultados obtenidos.

Seguidamente, es importante mencionar que es muy válido que una empresa como HOSUSA busque realizar un ejercicio de esta naturaleza. Siendo una empresa que planea con gran anterioridad la compra de insumos, ventas, decisiones de inversión y financiamiento, está claro que sus decisiones será afectadas por la inflación y el tipo de cambio de ese momento. Si el día de hoy quieren adquirir inventario, podrían notar que los precios subieron debido a una mayor inflación, y el no haber prevenido eso, puede dejarlos sin los insumos suficientes; por otra parte, el buscar un financiamiento en dólares podría resultar peligroso financieramente si no se sabe cómo podría comportarse el tipo de cambio en el futuro próximo. Todo el ejercicio anterior le ayuda a la empresa a tener un sustento más, y una mejor comprensión del futuro cercano de dos variables macro económicas relevantes para le empresa, para la mejor toma de decisiones. Ya será labor de la empresa analizar si una inflación mensual de 0.53%, o un tipo de cambio constante en $20.24 es algo que les beneficia al no haber cambios, o que les perjudica porque esperaban un escenario mejor.

Finalmente, surgió la cuestión de si es posible usar estos modelos para otra empresa que pase por una situación similar. Esta duda surge principalmente por las limitantes legales. Está claro que no es sería legal compartir estos modelos de predicciones, si de alguna forma tuvieran datos sensibles de la empresa, en este caso HOSUSA; los artículos 210 y 211 del Código Penal Federal de México mencionan que quien copie y divulgue información contenida en sistemas de computación protegidos, así como información obtenida por su cargo o puesto de empleo, sin consentimiento de la organización empleadora, podría ser sancionado con 3 meses a 1 año de prisión, así como hasta 200 jornadas de trabajo comunitario (Lemus, 2018). No obstante, debido a que en este ejercicio no se utilizó información de la empresa en ningún momento, más que para el planteamiento de la problemática, sí sería posible utilizar estos modelos y compartirlos con otra organización.

12. Referencias

INEGI. (2021). Índice de Precios al Consumidor- Información Mensual. De: INEGI. Disponible en: https://www.inegi.org.mx/app/indicesdeprecios/Estructura.aspx?idEstructura=112001300030&T=Índices%20de%20Precios%20al%20Consumidor&ST=Inflación%20Mensual.

Lemus, L. (2018). Consecuencias legales del robo de información en una empresa. De: Foro Jurídico. Disponible en:https://forojuridico.mx/consecuencias-legales-del-robo-de-informacion-en-una-empresa/.

S/a. (2021). USD/MXN (MXN=X). De: Yahoo Finance. Disponible en: https://finance.yahoo.com/quote/MXN=X?p=MXN=X&.tsrc=fin-srch.