Explorando correlaciones de los futuros con el CO2

Las relaciones entre variables constituyen el primer análisis serio para cualquier analista y/o trader del mercado eléctrico. Comparando diferentes periodos u horizontes temporales, se puede ver cómo dichas variables interaccionan con el mercado spot o con los contratos de futuros, pero a veces no resulta fácil llegar a una conclusión por la complejidad del propio sistema, el dinamismo del comportamiento del mercado y la no tan escasa aparición de datos anómalos que despistan a nuestro modelo.

Un buen ejercicio para abordar la correlación estadística sería analizar la situación que se lleva viviendo desde el segundo trimestre de 2018 con la cotización de los derechos de emisión de CO2 (EUA CO2) y su afectación a los futuros. Para realizar un análisis más realista, realizaré una correlación múltiple entre el precio del CO2, el del carbón, el del gas y por último, el de la cotización de los futuros de electricidad en España, concretamente sobre el producto anual del año 2019.

Conseguir los datos de cotizaciones de CO2, carbón y gas

En general, fuentes públicas de información no abundan para descargar automáticamente los datos, pero existe una que únicamente pide registrarse y de esta forma, poder llamar a su API un número limitado de veces al día sobre una base de datos realmente impresionante de productos, entre ellos, los que necesito.

Conectarse a Quandl

Quandl es un website donde se puede buscar cualquier fundamental que se necesite, en particular resulta potente su apartado de datos financieros. Tan sólo basta registrarse para conseguir un token o clave y poder utilizar su API con algunas restricciones. (El código de abajo tiene anonimizada mi token, ya que es personal).

library(Quandl)
library(dplyr)
library(lubridate)

# Establecimiento del token de Quandl
# Quandl.api_key("pega_aqui_tu_token_de_Quandl")

# Llamada a la API
gas_TTF <- Quandl("CHRIS/ICE_TFM1.4", type="raw") %>% rename(gas = Settle)
carbon_API2 <- Quandl("CHRIS/CME_MTF2.6", type="raw") %>% rename(carbon = Settle)
CO2_EUA <- Quandl("CHRIS/ICE_C1.4", type="raw") %>% rename(CO2 = Settle)

Con esta llamada he recuperado los siguientes productos:

  • Precio del gas TTF: futuro de la carga base del spot month continuous. Datos en €/MWh
  • Precio del carbón API2: futuro de la tonelada de carbón del índice McCloskey del spot month continuous.
  • Precio del derecho de emisión de CO2: futuro de la tonelada de CO2, del spot month continuous.

Descarga de datos de cotización del Cal’19

En cuanto a la variable que nos falta, me descargaré todo el histórico de la cotización del Cal’19 desde MEFF. Una vez descargado el archivo, selecciono el producto que me interesa:

** Recomiendo fervientemente abrir el archivo descargado (.xls) y guardarlo en formato xlsx. También es aconsejable desactivar las celdas agrupadas y colocar bien la cabecera, ya que se dispone en dos filas.*

library(readxl)

# Lectura de los datos del Cal19
cal19 <- read_excel("/Users/pherreraariza/Documents/energychisquared/post_inputs/4_post/PreciosCierreDerEnergia.xlsx") %>%
         filter(Cod. == "FTBCCAL19") %>% 
         select(Fecha, Precio) %>%
         rename(Date = Fecha,
                cal19 = Precio) %>%
         mutate(Date = as.Date(Date)) %>%
         left_join(gas_TTF, by = "Date") %>%
         left_join(carbon_API2, by = "Date") %>%
         left_join(CO2_EUA, by = "Date")


# Join de todos los datos
str(cal19)
## Classes 'tbl_df', 'tbl' and 'data.frame':    426 obs. of  5 variables:
##  $ Date  : Date, format: "2017-01-02" "2017-01-03" ...
##  $ cal19 : num  44.9 44.5 43.6 43.8 43.7 ...
##  $ gas   : num  19.2 18.4 18.8 18.9 18.5 ...
##  $ carbon: num  NA NA NA 79.2 78.7 ...
##  $ CO2   : num  6.12 5.43 5.72 5.29 5.05 5.27 5.51 5.52 5.04 5.04 ...

Correlación de las variables fundamentales con el precio del Cal19

Evalución del supuesto de normalidad

En primer lugar, para saber el grado de correlación, necesito saber cómo se distribuyen los valores de las variables, para ver si se evalúa de forma paramétrica o no.

library(tidyr)
library(ggplot2)

cal19 %>% select(-Date) %>% 
      gather() %>% 
      ggplot(aes(value)) + geom_histogram() +
                           facet_wrap(~key, scales = "free")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## Warning: Removed 15 rows containing non-finite values (stat_bin).

La distribución de los histogramas ya me indica que debo utilizar técnicas no paramétricas para calcular la correlación: utilizaré Spearman. Una de las cosas que es necesario recordar con la correlación es que ésta mide el grado de asociación entre variables, pero no nos permite identificar una dependencia causal. Es decir, no nos permite establecer cuál de ellas es la causa y cuál es el efecto. Por este motivo, no hay variable dependiente y variable independiente.

Cálculo de la correlación de Spearman

library(corrr)

# Cálculo de la correlación de Spearman
cor_cal19 <- cal19 %>% select(-Date) %>%
                       correlate(method = "spearman")
## 
## Correlation method: 'spearman'
## Missing treated using: 'pairwise.complete.obs'
# Tabla de datos de la correlación
cor_cal19 %>% fashion()
##   rowname cal19  gas carbon  CO2
## 1   cal19        .72    .78  .95
## 2     gas   .72         .72  .78
## 3  carbon   .78  .72         .76
## 4     CO2   .95  .78    .76
# Gráfico de correlación
cor_cal19 %>% network_plot()

cor_cal19 %>% rplot(print_cor = TRUE)

El grado de asociación entre la cotización del Cal19 y el EUA CO2 es de un 95%, mucho más elevada que la que presenta con el carbón API2 (78%) y el gas TTF (76%). Ya cabía esperar que la correlación fuera alta, pero no esperaba un valor tan elevado. Todas las correlaciones son positivas, es decir, directamente proporcionales.

Si grafico directamente las curvas forward, se ve aún más clara la correlación. El problema es ¿qué variable causa primero la tendencia alcista a cual?

cal19 %>% gather(key = variable, value = precio, -Date) %>% 
          ggplot(aes(x=Date, y=precio, colour = variable)) + geom_line() + 
                                                             facet_grid(variable ~ ., scales = "free_y")
## Warning: Removed 3 rows containing missing values (geom_path).

 
comments powered by Disqus