O relatório FOCUS divulga semanalmente um conjunto de expectativas de diversas variáveis de mercado (índices, taxas de juros, moedas, …). Uma destas é a taxa SELIC, são informadas expectativas desta taxa para diversas reuniões futuras do COPOM. Estas expectativas podem ser obtidas com o pacote rbcb.

No código abaixo obtemos as expectativas de taxa SELIC para as próximas reuniões do COPOM.

library(tidyverse)
#> ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.2 ──
#>  ggplot2 3.3.6      purrr   0.3.4
#>  tibble  3.1.8      dplyr   1.0.9
#>  tidyr   1.2.0      stringr 1.4.0
#>  readr   2.1.2      forcats 0.5.1
#> ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
#>  dplyr::filter() masks stats::filter()
#>  dplyr::lag()    masks stats::lag()
library(fixedincome)
#> 
#> Attaching package: 'fixedincome'
#> 
#> The following objects are masked from 'package:dplyr':
#> 
#>     first, last

refdate <- as.Date("2022-04-29")

df <- rbcb::get_market_expectations("top5s-selic",
  start_date = refdate,
  end_date = refdate
)
df <- df |>
  mutate(
    Reuniao_ano = str_split(reuniao, "/", simplify = TRUE)[, 2],
    Reuniao_cod = str_split(reuniao, "/", simplify = TRUE)[, 1],
    reuniao = str_c(Reuniao_ano, Reuniao_cod)
  ) |>
  arrange(reuniao) |>
  filter(tipoCalculo == "C") |>
  select(reuniao, mediana)
df
#> # A tibble: 16 × 2
#>    reuniao mediana
#>    <chr>     <dbl>
#>  1 2022R3    12.8 
#>  2 2022R4    13.2 
#>  3 2022R5    13.2 
#>  4 2022R6    13.2 
#>  5 2022R7    13.2 
#>  6 2022R8    13.2 
#>  7 2023R1    13.2 
#>  8 2023R2    12.8 
#>  9 2023R3    12.2 
#> 10 2023R4    11.8 
#> 11 2023R5    11   
#> 12 2023R6    10.4 
#> 13 2023R7    10   
#> 14 2023R8     9.62
#> 15 2024R1     9   
#> 16 2024R2     8.5

As expectativas são relacionadas às reuniões do COPOM, na coluna reuniao temos um código formado pelo ano e um contador de reuniões por ano. Dessa forma, 2022R3 representa a terceira reunião de 2022, e assim por diante. Na coluna mediana temos a mediana da amostra de expectativas informadas pelos participantes de mercado.

No gráfico abaixo observa-se a estrutura a termo das expectativas pelas reuniões futuras.

df |>
  ggplot(aes(x = reuniao, y = mediana)) +
  geom_point() +
  geom_text(aes(label = mediana, hjust = 0.5, vjust = -1.0)) +
  labs(
    x = "Meeting",
    y = "SELIC Rate",
    title = "SELIC Rates Expectations",
    caption = "Source: FOCUS Report (rbcb package)"
  )

Assumindo a estrutura a termo abaixo para a data de referência 2022-04-29.

terms <- c(1, 23, 44, 65, 88, 109, 129, 149, 171, 193, 211, 234, 252)
rates <- c(
  0.1165, 0.1247, 0.1265, 0.1281, 0.1294, 0.1298, 0.1301, 0.1304,
  0.1303, 0.1305, 0.1306, 0.1302, 0.1300
)
curve <- spotratecurve(
  rates, terms, "discrete", "business/252", "Brazil/ANBIMA",
  refdate = refdate
)

A idéia é utilizar as expectativas fornecidas no relatório FOCUS com a interpolação FlatForwardCOPOM e avaliar como seria a estrutura a termo interpolada sujeita a estas expectativas.

Para isso vamos considerar as próximas 8 datas futuras de reunião do COPOM. Vamos pegar as 8 expectativas referentes a estas reuniões. É necessário subtrair 0.1% das expectativas, pois essa é a diferença típica (nos dias atuais) entre a taxa SELIC meta e a taxa DI (CDI).

library(copom)
#> Loading required package: bizdays
#> 
#> Attaching package: 'bizdays'
#> The following object is masked from 'package:stats':
#> 
#>     offset
copom_dates <- get_copom_dates(refdate, 8)
fwd <- (df[["mediana"]][1:8] - 0.1) / 100

Para aplicar a interpolação FlatForwardCOPOM utilizando as expectativas, utilizamos a função interp_copomscenarios passando as datas futuras de reuniões e as taxas futuras, atribuindo em seguida a curva de juros, via o método interpolation. Como resultado podemos obter do objeto de interpolação as mudanças na taxa de juros implícitas nas expectativas.

interpolation(curve) <- interp_copomscenarios(copom_dates, future_rates = fwd)
interpolation(curve)@copom_moves * 1e4
#> [1] 100  50   0   0   0   0   0 -50

Observa-se que as expectativas trazem um mudança de 100 bps na SELIC, seguida por uma mudança de 50 bps, um período sem mudanças e uma mudança de -50 bps na oitava reunião.

Uma vez que definimos a interpolação na curva de juros podemos visualizar o efeito da interpolação com as expectativas do FOCUS conjuntamente com os pontos da curva de juros.

plot(curve, use_interpolation = TRUE)

Podemos ver que os pontos da curva estão próximos a curva interpolada, demostrando alguma conformidade do mercado com as expectativas do FOCUS.

Outra alternativa é fornecer as mudanças nas taxas de juros, ao invés das taxas futuras, na função interp_copomscenarios.

No código abaixo vamos considerar o cenário onde teremos uma mudança de 100 bps seguida de 2 mudanças de 25 bps e sem mais mudanças, para as próximas 8 reuniões.

moves <- c(100, 25, 25, 0, 0, 0, 0, 0) / 1e4
interpolation(curve) <- interp_copomscenarios(copom_dates, copom_moves = moves)
plot(curve, use_interpolation = TRUE)

Nota-se um leve descolamento entre os pontos da curva e a interpolação, após o terceiro vencimento. Dando a entender que a curva de juros traz um movimento implícito maios próximos das expectativas do FOCUS, com uma mudança de 100 bps seguida por outra de 50 bps, ao invés dos cenários avaliados.

Um ponto importante é que com a função interp_copomscenarios é possível testar diversos cenários de movimentos futuros para a taxa SELIC e comparar os resultados com uma curva de mercado. Eventualmente estes cenários podem trazer novos formatos e níveis para a curva de juros.