Os arquivos disponibilizados pela BM&FBovespa trazem variáveis fundamentais para a compreenssão das expectativas dos agentes econômicos acerca do futuro da economia e do desenrolar das políticas macroeconômicas. Uma das variáveis mais importantes é a curva de taxas de juros pré-fixados, a curva pré, também definida como estrutura a termo de taxas de juros pré-fixados. Esta curva traz expectativas de taxas de juros para diversos prazos e que são utilizadas no mercado para o apreçamento de diversos instrumentos financeiros, desde CDBs a opções e por isso também é considerada como uma proxy para taxas de juros livres de risco. Por exemplo, você tem uma grana para recever em uma data futura, digamos 1 ano a frente. Qual taxa de juros utilizar para calcular o valor presente dessa grana hoje. Bem, um bom candidato para essa taxa de juros é a taxa na curva pré referente ao prazo em que a grana será recebida no futuro.

Neste post vou mostrar como utilizar 2 dos arquivos disponibilizados pela BM&FBovespa para construir esta curva a partir das cotações dos negócios de contratos futuros de taxa de juros sobre DI de 1 dia, ou como são conhecido contratos sobre DI1. Os arquivos são:

  • BD_Final.txt: Negócios Realizados em Pregão - Final
  • Indic.txt: Indicadores Econômicos e Agropecuários - Final

O arquivo BD_Final.txt traz as cotações dos contratos futuros e o Indic.txt traz indicadores econômicos, em particular a taxa CDI divulgada pela CETIP, que é necessária na construção da curva.

Vamos começar importando os pacotes necessários.

library(rbmfbovespa)
library(dplyr)
library(tidyr)
library(ggplot2)
library(forcats)

O arquivo BD_Final.txt é baixado da página de Pesquisa por Pregão do site da BM&FBovespa selecionando o arquivo: Mercado de Derivativos - Negócios Realizados em Pregão - Final. Este arquivo é carregado diretamente com a função read_marketdata do pacote rbmfbovespa.

bdi <- read_marketdata('datasets/BD_Final.txt', template = 'BD_Final')
dim(bdi)
## [1] 1124   80

Este arquivo traz 80 variáveis e pouco mais de 1000 registros. Vamos filtrar os registros dos contratos futuros de DI1 utilizando cod_mercadoria == 'DI1' e selecionar as variáveis data_vencimento, que é o vencimento do contrato futuro e a variável cot_ult_negocio, que é o valor em taxa da cotação do último negócio de futuros de DI1.

curva_pre <- bdi %>% filter(cod_mercadoria == 'DI1') %>%
  select(data_vencimento, taxa = cot_ult_negocio) %>%
  arrange(data_vencimento)
curva_pre
##    data_vencimento   taxa
## 1       2017-03-01 12.797
## 2       2017-04-03 12.420
## 3       2017-05-02 12.229
## 4       2017-06-01 11.980
## 5       2017-07-03 11.765
## 6       2017-08-01 11.625
## 7       2017-09-01 11.400
## 8       2017-10-02 11.260
## 9       2017-11-01  0.000
## 10      2017-12-01  0.000
## 11      2018-01-02 10.870
## 12      2018-02-01 10.760
## 13      2018-04-02 10.640
## 14      2018-07-02 10.460
## 15      2018-10-01 10.370
## 16      2019-01-02 10.300
## 17      2019-04-01 10.330
## 18      2019-07-01 10.350
## 19      2019-10-01 10.400
## 20      2020-01-02 10.440
## 21      2020-04-01 10.500
## 22      2020-07-01 10.550
## 23      2020-10-01 10.590
## 24      2021-01-04 10.590
## 25      2021-04-01 10.630
## 26      2021-07-01 10.660
## 27      2021-10-01  0.000
## 28      2022-01-03 10.750
## 29      2022-07-01  0.000
## 30      2023-01-02 10.850
## 31      2023-07-03  0.000
## 32      2024-01-02 10.890
## 33      2024-07-01  0.000
## 34      2025-01-02 10.910
## 35      2026-01-02 10.910
## 36      2027-01-04 10.940
## 37      2028-01-03  0.000
## 38      2029-01-02  0.000
## 39      2030-01-02  0.000

A variáveis cot_ult_negocio foi renomeada como taxa para simplicar o tratamento e evitar ficar carregando um nome extenso e estranho. Na sequência os dados são ordenado pela data de vencimento, pois cada ponto da curva é refente a uma data e portanto é necessário que estes estejam em sequência.

Observando os dados, identificamos que algumas taxas são zero, indicando que para a data de referência do arquivo (ou do pregão) não houveram negociações de contratos futuros de DI1 para estes vencimentos. Portanto, é necessário excluir todos os registros com taxas zeradas.

curva_pre <- curva_pre %>% filter(taxa != 0)

Agora podemos visualizar a curva pré.

ggplot(data = curva_pre,
       aes(x = data_vencimento, y = taxa)) +
  geom_point() +
  geom_line()

plot of chunk curva_de_juros_pre_com_rbmfbovespa-5

Entretanto essa curva começa no primeiro vencimento de futuro de DI1. É necessário definir o vértice de 1 dia, referente a taxa de juros de overnight. Essa taxa de juro é obtida no arquivo Indic.txt com o código do indicador igual a 'DI1'.

indic <- read_marketdata('datasets/Indic.txt', template = 'Indic')
indic %>%
  filter (cod_indicador == 'DI1') %>%
  select(data_geracao_arquivo, valor_indicador)
##   data_geracao_arquivo valor_indicador
## 1           2017-02-01           12.88
## 2           2017-02-02           12.88

Como se observa há duas datas de geração do arquivo, isso acontece por que neste arquivo são divulgadas informações para a data de referência e para o dia anterior. A nossa data de referência será a data de geração do arquivo BD_Final.txt obtida da variável data_geracao_arquivo.

ref_date <- bdi$data_geracao_arquivo[1]
cdi <- indic %>%
  filter (cod_indicador == 'DI1', data_geracao_arquivo == ref_date) %>%
  select(data_vencimento = data_geracao_arquivo, taxa = valor_indicador)
cdi
##   data_vencimento  taxa
## 1      2017-02-02 12.88

Note que eu já gerei uma tabela com as colunas data_vencimento e taxa que são as mesmas da curva_pre. Entretanto é necessário fazer uma ajuste na data de vencimento de cdi, porque essa é a data de referência da taxa e não a sua data de vencimento. Como a taxa CDI é a taxa de overnight é preciso mover essa data de 1 dia útil. Para fazer isso utilizamos a função offset do pacote bizdays utilizando o calendário Brazil/ANBIMA, que já vem com o pacote.

cdi <- cdi %>% mutate(data_vencimento = bizdays::offset(data_vencimento, 1, 'Brazil/ANBIMA'))
cdi
##   data_vencimento  taxa
## 1      2017-02-03 12.88

Para incluir este vértice a curva vamos utilizar o rbind, atualizando curva_pre e na sequência já colocamos a visualização dos dados.

curva_pre <- curva_pre %>% rbind(cdi) %>% arrange(data_vencimento)

ggplot(data = curva_pre,
       aes(x = data_vencimento, y = taxa)) +
  geom_point() +
  geom_line()

plot of chunk curva_de_juros_pre_com_rbmfbovespa-9

Na visualização não muda muito, mas esse primeiro vértice é muito importante para ancorar o começo da curva permitindo utilizar algumas técnicas de interpolação de dados para obter estimativas de taxas de juros que não estão presentes na curva.

Há outras formas de selecionar as cotações para a construção da curva, aqui adotamos a cotação do último negócio, poderiamos ter adotado as taxas implícitas no preço de ajuste dos futuros (variável valor_ajuste), que são os preços utilizados no cálculo dos ajustes diários pagos aos investidores que possuem posições em aberto nos contrados de DI1. Poderiamos também fazer uma avaliação de liquidez, observando a quantidade de negócios e o número de contratos negociados (variáveis qtd_negocios e qtd_contr), afim de construir uma curva com os vencimentos mais líquidos.

Outra observação interessante é o formato da curva, ela está indicando queda de juros para os próximos 2 anos. Ao observamos as curvas de períodos anteriores, em particular do ano de 2015, não havia expectativa de redução da taxa de juros. Veja o post Empenada na Curva de Juros de DI1 para ter uma ideia de como eram os níveis de taxas de juros em 2015. Esse é um resultado direto da forma como a política econômica vem sendo tocada pela atual equipe do Ministério da Fazenda e do Banco Central.