The historical prices of all futures contracts traded at B3 can be obtained with the futures_mget
function. These are the settlement prices delivered daily by B3 at the Trading session settlements page.
library(rb3)
library(ggplot2)
library(stringr)
library(dplyr)
library(bizdays)
<- futures_mget(
df first_date = "2021-01-01",
last_date = "2022-04-27",
by = 5
)
The interest rates can be extracted from the futures prices. The DI1 futures matures at the first day of the month. The code below generates the maturities from the three characters maturity codes. After the business days, the implied rates are calculated, once we know that the notional amount of these contracts is 100000.
In the graphic we can see the dynamics of the nominal interest rates of the contracts DI1F23 and DI1F33. These contracts are exactly 10 years distant from each other.
<- df |>
di1_futures filter(commodity == "DI1") |>
mutate(
maturity_date = maturity2date(maturity_code),
fixing = following(maturity_date, "Brazil/ANBIMA"),
business_days = bizdays(refdate, maturity_date, "Brazil/ANBIMA"),
adjusted_tax = (100000 / price) ^ (252 / business_days) - 1
|>
) filter(business_days > 0)
|>
di1_futures filter(symbol %in% c("DI1F23", "DI1F33")) |>
ggplot(aes(x = refdate, y = adjusted_tax, color = symbol, group = symbol)) +
geom_line() +
geom_point() +
labs(
title = "DI1 Future Rates - Nominal Interest Rates",
caption = str_glue("Data imported using rb3 at {Sys.Date()}"),
x = "Date",
y = "Interest Rates",
color = "Symbol"
+
) scale_y_continuous(labels = scales::percent)
Differently from DI1 contracts, that trade nominal interest rates, the DAP contracts trade real interest rates.
<- df |>
dap_futures filter(commodity == "DAP") |>
mutate(
maturity_date = maturity2date(maturity_code, "15th day"),
fixing = following(maturity_date, "Brazil/ANBIMA"),
business_days = bizdays(refdate, maturity_date, "Brazil/ANBIMA"),
adjusted_tax = (100000 / price) ^ (252 / business_days) - 1
|>
) filter(business_days > 0)
|>
dap_futures filter(symbol %in% c("DAPF23", "DAPK35")) |>
ggplot(aes(x = refdate, y = adjusted_tax, group = symbol, color = symbol)) +
geom_line() +
geom_point() +
labs(
title = "DAP Future Rates - Real Interest Rates",
caption = str_glue("Data imported using rb3 at {Sys.Date()}"),
x = "Date",
y = "Interest Rates",
color = "Symbol"
+
) scale_y_continuous(labels = scales::percent)
With the difference between real and nominal interest rates we can obtain the forward inflation implied in these contracts.
Using the contracts DI1F23 and DAPF23, which matures in the same month, with a difference of a few days. The implied inflation can be computed by the division of the prices of these contracts.
<- df |>
infl_futures filter(symbol %in% c("DI1F23", "DAPF23")) |>
mutate(
maturity_date = if_else(commodity == "DI1",
maturity2date(maturity_code),
maturity2date(maturity_code, "15th day")
),fixing = following(maturity_date, "Brazil/ANBIMA"),
business_days = bizdays(refdate, maturity_date, "Brazil/ANBIMA"),
adjusted_tax = (100000 / price) ^ (252 / business_days) - 1
|>
) arrange(refdate)
<- infl_futures |>
infl_expec select(symbol, price, refdate) |>
::pivot_wider(names_from = symbol, values_from = price) |>
tidyrmutate(inflation = DAPF23 / DI1F23 - 1)
|>
infl_expec ggplot(aes(x = refdate, y = inflation)) +
geom_line() +
geom_point()
10Y Forward rates implied in DI1 Futures prices. The contracts DI1F23 and DI1F33 are used to compute the 10Y forward rates that ranges from Jan. 2023 to Jan. 2033.
<- df |>
df_fut filter(symbol %in% c("DI1F23", "DI1F33")) |>
mutate(
maturity_date = maturity2date(maturity_code) |> following("Brazil/ANBIMA"),
business_days = bizdays(refdate, maturity_date, "Brazil/ANBIMA")
)
<- df_fut |>
df_du select(refdate, symbol, business_days) |>
::pivot_wider(names_from = symbol, values_from = business_days) |>
tidyrmutate(
du = DI1F33 - DI1F23
|>
) select(refdate, du)
<- df_fut |>
df_fwd select(refdate, symbol, price) |>
::pivot_wider(names_from = symbol, values_from = price) |>
tidyrinner_join(df_du, by = "refdate") |>
mutate(
fwd = (DI1F23 / DI1F33)^(252 / du) - 1
|>
) select(refdate, fwd) |>
na.omit()
|>
df_fwd ggplot(aes(x = refdate, y = fwd)) +
geom_line() +
labs(
x = "Date", y = "Forward Rates",
title = "Historical 10Y Forward Rates - F23:F33",
caption = "Source B3 - package rb3"
)