Introducción

El análisis de series de tiempo financieras ha sido un campo de estudio de alto valor dentro de las finanzas. Con el paso del tiempo han surgido nuevas propuestas de modelación, ya sean nuevas o modificaciones de modelos conocidos, que son de gran útilidad para estimar el comportamiento de un indicador financiero a partir de datos históricos.

En este documento se desarrolla el análisis de una serie de tiempo financiera relacionada con el precio de un producto agrícola cotidiano: el café. Primero, se presenta una breve descripción de la base de datos y luego se realiza el diagnóstico como serie de tiempo.

Base de datos

La base de datos contiene el precio diario de cierre del café arábigo en centavos [¢] registrado desde el 01 de enero de 2015 hasta el 31 de diciembre de 2021 y fue tomada de Yahoo Finance, una plataforma que proporciona la información financiera de empresas, activos o productos.

El café arábigo es un tipo de semilla que contiene más aceites y azúcares naturales en comparación del café robusto. Es importante tener en cuenta que son dos tipos de semillas diferentes, lo que implica que su precio puede diferir.

En la siguiente línea de código se importa la información correspondiente al precio de cierre del café arábigo en el período de tiempo que se desea estudiar.

Ahora, se presenta un resumen de la base de datos Coffe. En el período de tiempo estudiado, el precio mínimo y máximo de cierre para este insumo agrícola fue de $ 86.65¢$ y \(250.20¢\), respectivamente. Además, en la base de datos se presentan dos fechas que registran un valor NA.

summary(Coffe)
##      Index                Close       
##  Min.   :2015-01-02   Min.   : 86.65  
##  1st Qu.:2016-09-28   1st Qu.:110.15  
##  Median :2018-07-03   Median :123.10  
##  Mean   :2018-07-03   Mean   :127.87  
##  3rd Qu.:2020-04-02   3rd Qu.:137.70  
##  Max.   :2021-12-30   Max.   :250.20  
##                       NA's   :2

Para evitar inconvenientes con el software, se descartan estos NA y se continúa con el análisis.

Coffe  <- Coffe[!is.na(Coffe),]

A continuación, se presenta el gráfico del precio de cierre del café. Se puede observar que desde el año 2021 su precio ha presentado un alza considerable, lo que se puede relacionar con múltiples factores como el clima de los países con mayor índice de producción y expotación o el mismo cambio de moneda que incrementará los costos de transporte.

plot(Coffe, type = "l", col = "orange", ylab = "Precio [¢]", xlab = "Tiempo [días]", main = "Precio de cierre - Café")

grid(nx = NULL, ny = NULL)

Análisis de la serie de tiempo

Ahora, se realiza el análisis de la base de datos como serie de tiempo. A continuación, se presenta el gráfico de descomposición de la misma. De acuerdo con el gráfico, se puede observar una tendencia de incremento a partir del 2021 que se presenta después de una caída del precio. Note que la caída se presenta en fechas coincidentes con la pandemia, factor que puede haber afectado duramente el precio de un producto agrícola.

fit<-decompose(Coffe.ts, type = "multiplicative")
autoplot(fit, ts.colour = "red", ts.linetype = "dashed")

Estimación de un modelo lineal

Aunque el análisis gráfico anterior permite establecer que la serie de tiempo no se ajusta a un modelo lineal debido a su tendencia, esta sección se va a desarrollar como ejercicio práctico de regresión. En la siguiente línea de código se estima una regresión lineal para el precio de cierre del Café.

modelo1<-lm(Coffe.ts~time(Coffe.ts))
summary(modelo1)
## 
## Call:
## lm(formula = Coffe.ts ~ time(Coffe.ts))
## 
## Residuals:
##    Min     1Q Median     3Q    Max 
## -42.31 -19.20  -4.03  12.13 117.86 
## 
## Coefficients:
##                  Estimate Std. Error t value Pr(>|t|)    
## (Intercept)    -2493.4141   648.3277  -3.846 0.000124 ***
## time(Coffe.ts)     1.2986     0.3212   4.043  5.5e-05 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 27.3 on 1759 degrees of freedom
## Multiple R-squared:  0.009208,   Adjusted R-squared:  0.008645 
## F-statistic: 16.35 on 1 and 1759 DF,  p-value: 5.501e-05

De acuerdo con los resultados, se observa que el \(R^2\) de ajuste es bajo, lo que indica que la estimación utilizando un modelo de regresión lineal no es la más eficiente para la base de datos en estudio. Además, el error estandar es considerable. Luego, realizando la verificación de los supuestos sobre los residuales (errores) del modelo, se tiene lo siguiente:

checkresiduals(modelo1)

## 
##  Breusch-Godfrey test for serial correlation of order up to 10
## 
## data:  Residuals
## LM test = 1742.2, df = 10, p-value < 2.2e-16

Primero, note que el comportamiento de los residuos indica que la varianza no es constante. Además, en el gráfico de la autocorrelación parcial se observa que los valores salen del límite en los primeros 30 rezagos. Por último, se evidencia que los residuos no cumplen con el supuesto de normalidad. Para confirmar esto último, se realiza un test de Shapiro-Wilk, el cual sostiene como hipótesis nula que los residuos presentan una variable normal, mientras que la alternativa indica que presentan un comportamiento no normal.

shapiro.test(rstudent(modelo1))
## 
##  Shapiro-Wilk normality test
## 
## data:  rstudent(modelo1)
## W = 0.89495, p-value < 2.2e-16

Tomando un nivel de significancia del 5%, se rechaza la hipótesis nula, lo cual confirma que los residuos no presentan un comportamiento normal. De esta manera, se confirma que el modelo de regresión lineal no es el más adecuado poara nuestro estudio.

Estimación de un modelo cuadrático

Ahora, se intenta realizar el ajuste de la serie de tiempo utilizando un modelo cuadrático. Por supuesto, se sabe que por la tendencia conocida de los datos, este modelo no presentará un resultado favorable como sucedió con el modelo de regresión lineal.

modelo2<-lm(Coffe~time(Coffe.ts)+ I(time(Coffe.ts)^(2)))
summary(modelo2)
## 
## Call:
## lm(formula = Coffe ~ time(Coffe.ts) + I(time(Coffe.ts)^(2)))
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -35.538 -17.482  -5.156  15.135  81.947 
## 
## Coefficients:
##                         Estimate Std. Error t value Pr(>|t|)    
## (Intercept)            1.895e+07  5.637e+05   33.62   <2e-16 ***
## time(Coffe.ts)        -1.878e+04  5.586e+02  -33.62   <2e-16 ***
## I(time(Coffe.ts)^(2))  4.652e+00  1.384e-01   33.62   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 21.3 on 1758 degrees of freedom
## Multiple R-squared:  0.397,  Adjusted R-squared:  0.3963 
## F-statistic: 578.7 on 2 and 1758 DF,  p-value: < 2.2e-16

A partir de los resultados se evidencia que el \(R^2\) de ajuste es bajo, lo que indica que la estimación utilizando un modelo cuadrático no es la más eficiente para la base de datos en estudio. Además, el error estandar es considerable. Aunque estos valores son más favorables en comparación con los obtenidos en el modelo de regresión lineal, siguen siendo críticos.

Luego, realizando la verificación de los supuestos sobre los residuales (errores) del modelo, se tiene lo siguiente:

checkresiduals(modelo2)

## 
##  Breusch-Godfrey test for serial correlation of order up to 10
## 
## data:  Residuals
## LM test = 1733.3, df = 10, p-value < 2.2e-16

Primero, note que el comportamiento de los residuos indica que la varianza no es constante. Además, en el gráfico de la autocorrelación parcial se observa que los valores salen del límite en los primeros 30 rezagos. Por último, se evidencia que los residuos no cumplen con el supuesto de normalidad. Para confirmar esto último, se realiza un test de Shapiro-Wilk, el cual sostiene como hipótesis nula que los residuos presentan una variable normal, mientras que la alternativa indica que presentan un comportamiento no normal.

shapiro.test(rstudent(modelo2))
## 
##  Shapiro-Wilk normality test
## 
## data:  rstudent(modelo2)
## W = 0.89495, p-value < 2.2e-16

Tomando un nivel de significancia del 5%, se rechaza la hipótesis nula, lo cual confirma que los residuos no presentan un comportamiento normal. De esta manera, se confirma que el modelo de regresión cuadrático no es el más adecuado poara nuestro estudio.

Por último, se presenta el siguiente gráfico que resalta la tendencia de la serie de tiempo relacionada con el precio de cierre del café. Es evidente que una regresión lineal o cuadrática no son las más adecuadas para simular el comportamiento histórico que presentan los datos. Esto resalta la importancia de realizar un breve análisis gráfico de la información previo al desarrollo de propuestas de modelización.

ggplot(Coffe.ts, aes(y=Coffe.ts, x=time(Coffe.ts)))+geom_point()+geom_smooth(se=FALSE)
## Don't know how to automatically pick scale for object of type ts. Defaulting to continuous.
## Don't know how to automatically pick scale for object of type ts. Defaulting to continuous.
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'

Estimación del modelo ARIMA

Ahora, se realiza la estimación del modelo ARIMA de ajuste para la serie de tiempo relacionada con el precio de cierre del café.

Prueba de estacionariedad sobre la serie

En primera instancia, se verifica si los datos cumplen con las condiciones de estacionariedad. Para esto, se utiliza el test de Dicker-Fuller (\(adf.test\)) sobre la base de datos, el cual tiene como hipótesis nula que la serie no es estacionaria.

adf.test(Coffe.ts, alternative = c("stationary", "explosive"))
## Warning in adf.test(Coffe.ts, alternative = c("stationary", "explosive")): p-
## value greater than printed p-value
## 
##  Augmented Dickey-Fuller Test
## 
## data:  Coffe.ts
## Dickey-Fuller = -0.2459, Lag order = 12, p-value = 0.99
## alternative hypothesis: stationary

Considerando que \(p>0.05\), no se puede rechazar la hipotesis nula, por lo que no se puede garantizar la estacionariedad de la serie de tiempo. Por esta razón, se requiere una diferenciación en los datos.

Diferenciación de la serie

En la siguiente línea de código se determina la cantidad de difereciaciones que requiere la serie de tiempo para que cumpla con el supuesto de estacionariedad.

ndiffs(Coffe.ts)
## [1] 1

De acuerdo con lo anterior, una diferenciación es suficiente para alcanzar el supuesto de estacionariedad. A continuación, se realiza la diferenciación correspondiente a la serie de tiempo relacionada con el precio de cierre del café. Además, se presenta el comportamiento de esta nueva serie de tiempo utilizando una herramienta gráfica.

dif.Coffe.ts<-diff(Coffe.ts)

plot(dif.Coffe.ts, type = "l", col = "orange", ylab = "Precio [¢]", xlab = "Tiempo [días]", main = "Primera diferenciación - Precio del café")

grid(nx = NULL, ny = NULL)

Ahora, se verifica si la diferenciación de la serie de tiempo cumple con las condiciones de estacionariedad usando el test de Dicker-Fuller (\(adf.test\)).

adf.test(dif.Coffe.ts, alternative = c("stationary", "explosive"))
## Warning in adf.test(dif.Coffe.ts, alternative = c("stationary", "explosive")):
## p-value smaller than printed p-value
## 
##  Augmented Dickey-Fuller Test
## 
## data:  dif.Coffe.ts
## Dickey-Fuller = -12.828, Lag order = 12, p-value = 0.01
## alternative hypothesis: stationary

Considerando que \(p<0.05\), se rechaza la hipotesis nula, lo cual indica con un 95% de confianza que la diferenciación de la serie es estacionaria, por lo que no es necesario realizar una diferenciación adicional.

Autocorrelación y Autocorrelación Parcial

En esta sección se presentan los gráficos de autocorrelación y autocorrelación parcial para la diferenciación de la serie de tiempo en estudio.

En el caso de la autocorrelación, considerando que nisiquiera alcanza el primer rezago, puede que la serie de tiempo no presente comportamiento AR.

ACF<-acf(dif.Coffe.ts)

En el caso de la autocorrelación parcial, se presenta un comportamiento similar al gráfico ACF, lo que puede indicar que la serie de tiempo no presenta comportamiento MA.

PACF<-pacf(dif.Coffe.ts)

Sin embargo, considerando que esta metodología es empírica, en la siguiente sección se utiliza la función \(auto.arima\) para la construcción del modelo ARIMA de la diferenciación de la serie de tiempo en estudio.

Estimación del modelo ARIMA

El modelo ARIMA que simula el comportamiento de la diferenciación de la serie de tiempo se construye en la siguiente línea de código.

modeloARIMA<-auto.arima(dif.Coffe.ts)
modeloARIMA
## Series: dif.Coffe.ts 
## ARIMA(2,0,0) with zero mean 
## 
## Coefficients:
##          ar1     ar2
##       0.0354  0.0260
## s.e.  0.0239  0.0239
## 
## sigma^2 = 7.245:  log likelihood = -4239.06
## AIC=8484.13   AICc=8484.14   BIC=8500.54

De acuerdo con lo anterior, el modelo de mayor ajuste para la diferenciación de la serie de tiempo vinculada al precio de cierre del café es un \(AR(2)\) con coeficientes:

\[ AR(2) = 0.035X_{t-1}+0.026X_{t-2}\]

Aunque ya se realizó la prueba de Dicker-Fuller para confirmar la estacionariedad de la serie, se presenta el siguiente gráfico que muestra que los inversos de los coeficientes del modelo AR se encuentran dentro del círculo unitario. Con esto se confirma la causalidad del método y por lo tanto, la estacionariedad.

plot(modeloARIMA)

Ahora, se verifican los supuestos sobre los residuos del modelo \(AR(2)\) construido.

checkresiduals(modeloARIMA)

## 
##  Ljung-Box test
## 
## data:  Residuals from ARIMA(2,0,0) with zero mean
## Q* = 340.52, df = 350, p-value = 0.6316
## 
## Model df: 2.   Total lags used: 352

De acuerdo con el gráfico anterior, se puede observar que los residuos presentan un comportamiento normal, por lo que este supuesto se cumple. Sin embargo, al revisar el gráfico de la autocorrelación, se evidencia que para algunos rezagos el valor sale del límite estipulado, lo que puede indicar que el supuesto de varianza constante no se cumple.

Para confirmar esto, se realiza una prueba de efectos ARCH por medio del \(ArchTest\) disponible en el software.

library(FinTS)
## Warning: package 'FinTS' was built under R version 4.1.3
## 
## Attaching package: 'FinTS'
## The following object is masked from 'package:forecast':
## 
##     Acf
#Generamos el modelo ARCH a un rezago
ModeloARCH1 = ArchTest(dif.Coffe.ts, lags = 1, demean = TRUE)

#Revisamos
ModeloARCH1
## 
##  ARCH LM-test; Null hypothesis: no ARCH effects
## 
## data:  dif.Coffe.ts
## Chi-squared = 59.092, df = 1, p-value = 1.504e-14
#H0: No hay efectos ARCH si el p-value es mayor que 0.05
#H1: Sí hay efectos ARCH si el p-value es menor que 0.05
#Conclusión: Sí hay efectos ARCH con un rezago

#Existe volatilidad al primer rezago

Considerando que \(p<0.05\), se rechaza la hipotesis nula, lo cual indica con un 95% de confianza que los residuos del modelo AR(2) si tiene efectos ARCH, lo que indica que los residuos tienen una varianza heterocedástica. Por esto, en la siguiente sección se desarrolla la construcción de un modelo GARCH para la varianza del modelo.

Estimación del modelo GARCH

A continuación, se presenta el comportamiento de la varianza de los residuos del modelo AR(2).

ug_var = ugfit@fit$var

autoplot(ts(ug_var)) + 
  geom_line(color = "green") + labs(title = "Varianza del modelo ARMA (2,0)")

Se puede observar que la varianza de los residuos no es constante para todo el período de estudio, pues presenta cambios bruscos evidentes.

Usando la libreria \(rugarch\), se estima el modelo GARCH que mejor se ajusta al comportamiento de la varianza de los residuos del modelo AR(2) que simula la diferenciación de la serie de tiempo vinculada al precio de cierre del café.

ugfit = ugarchfit(spec = ugarch2, data = dif.Coffe.ts)

ugfit@fit$coef
##           mu          ar1          ar2        omega       alpha1        beta1 
## -0.014954622  0.022821544 -0.006055432  0.170379132  0.075700600  0.899794714

De acuerdo con los resultados, el modelo que mejor se ajusta a la varianza es un \(GARCH(1,1)\) con coeficientes:

\[ \sigma^2 = 0.17 + 0.075 \epsilon ^2 _{t-1}+ 0.899 \sigma ^2 _{t-1}\]

Pronóstico de la serie de tiempo

Antes de realizar el pronóstico, se verifica si hay un punto de cambio sobre la media a lo largo de la serie de tiempo con el propósito de garantizar que los datos históricos base para el pronóstico son significativos.

mval<-cpt.mean(dif.Coffe.ts,method = "AMOC")

plot(mval, type = "l", cpt.col = "blue", xlab = "Value", cpt.width = 4, main = "Comportamiento de la media del DIF del precio de cierre del Café")

De acuerdo con el gráfico, no se evidencia un punto de cambio de la media que influya significativamente el pronóstico. Por esto, se utiliza toda la infomarción disponible para la predicción.

A continuación, se realiza el pronóstico de la diferenciación de la serie de tiempo vinculada al precio de cierre del café para 1 año (365 días).

tiempopronostico <- 365

pred<-forecast(dif.Coffe.ts,h=tiempopronostico)

plot(pred, main="Predicción DIF Precios del Café ", ylab="Precio [¢]", xlab="Tiempo [días]")

grid(nx = NULL, ny = NULL)

Note que la predicción de la serie de tiempo presenta un comportamiento consistente respecto a la información histórica. Sin embargo, realizar un pronóstico a tanto tiempo no es recomendable para el contexto que se desea simular, pues el precio de un producto agrícola como el café está sujeto a factores que cambian, incluso, de un día para otro. Por esto, la predicción se realiza preferiblemente a períodos cortos de tiempo.

Por último, se realiza un pronóstico utilizando los métodos mean(media), naive y naive estacional.

Coffe1 <- meanf(dif.Coffe.ts,h = tiempopronostico)
Coffe2 <- rwf(dif.Coffe.ts,h = tiempopronostico)
Coffe3 <- snaive(dif.Coffe.ts,h = tiempopronostico)
Coffe4 <- naive(dif.Coffe.ts, h = tiempopronostico)
plot(Coffe1)

grid(nx = NULL, ny = NULL)

plot(Coffe2)

grid(nx = NULL, ny = NULL)

plot(Coffe3)

grid(nx = NULL, ny = NULL)

plot(Coffe4)

grid(nx = NULL, ny = NULL)

De acuerdo con los gráficos anteriores, se concluye que el método de predicción de naive estacional presenta un comportamiento razonable, dando continuidad a la tendencia presentada por los datos históricos.

Conclusiones

Referencias

[1] Yahoo Finance, «Coffee Mar 23 (KC=F),» Yahoo Finance, [En línea]. Available: https://es-us.finanzas.yahoo.com/quote/KC%3DF?p=KC%3DF. [Último acceso: 24 11 2022].

[2] barchart, «Café Mar ’23 (KCH23),» barchart, 2022. [En línea]. Available: https://www.barchart.com/futures/quotes/KCH23.

[3] El Financiero, «Futuros del café van al alza por clima en Brasil,» 2022. [En línea]. Available: https://www.elfinanciero.com.mx/mercados/futuros-del-cafe-van-al-alza-por-clima-en-brasil/.

[4] V. Baez y L. Gonzalez, «Trabajo Final Series De Tiempo,» RPubs, [En línea]. Available: https://rpubs.com/adrianleo169/398515.