1 Introdução

Este relatório estima a Regra de Taylor com suavização (interest rate smoothing) para o Brasil no período 1999 T3 – 2025 T4. A equação de estimação é:

\[i_t = \alpha + \rho\,i_{t-1} + \gamma_\pi\,(\pi_t - \pi^*_t) + \gamma_y\,\tilde{y}_t + \varepsilon_t\]

com \(\alpha=(1-\rho)\,i^*\), \(\gamma_\pi=(1-\rho)\,\phi_\pi\) e \(\gamma_y=(1-\rho)\,\phi_y\). Após a estimação por MQO recuperamos os parâmetros estruturais \(\rho\), \(i^*\), \(\phi_\pi\) e \(\phi_y\).


2 Obtenção dos dados

Dados coletados da API do SGS/BCB via pacote GetBCBData.

Séries utilizadas e fontes.
Variável Descrição Série SGS
i_t Selic over diária (% a.d.) 11
pi_t IPCA acumulado 12 meses, mensal (% a.a.) 13522
Y_t PIB — índice de volume encadeado, trim. 22099

A meta \(\pi^*_t\) é construída manualmente a partir do histórico oficial do BCB.

ini <- as.Date("1999-01-01")
fim <- as.Date("2025-12-31")

df_raw <- gbcbd_get_series(
  id          = c(selic = 11, ipca12 = 13522, pib = 22099),
  first.date  = ini,
  last.date   = fim,
  be.quiet    = TRUE,
  use.memoise = FALSE
)

selic_d <- df_raw |> filter(id.num == 11)    |> select(date = ref.date, selic = value)
ipca12  <- df_raw |> filter(id.num == 13522) |> select(date = ref.date, ipca12 = value)
pib_raw <- df_raw |> filter(id.num == 22099) |> select(date = ref.date, pib = value)

3 Construção das variáveis

3.1 Taxa Selic trimestral

A série 11 está em % a.d. Anualizamos cada observação diária e depois tomamos a média aritmética simples das observações dentro do trimestre:

\[i^{\text{a.a.}}_d = \bigl[(1 + i^{\text{a.d.}}_d / 100)^{252} - 1\bigr]\times 100.\]

selic_tri <- selic_d |>
  mutate(selic_aa = ((1 + selic / 100)^252 - 1) * 100,
         tri      = as.yearqtr(date)) |>
  group_by(tri) |>
  summarise(i = mean(selic_aa, na.rm = TRUE), .groups = "drop")

3.2 IPCA acumulado em 12 meses (fim de trimestre)

Valor do último mês de cada trimestre (março, junho, setembro, dezembro):

ipca_tri <- ipca12 |>
  filter(month(date) %in% c(3, 6, 9, 12)) |>
  mutate(tri = as.yearqtr(date)) |>
  select(tri, pi = ipca12)

3.3 Meta de inflação (centro da meta)

Série anual construída a partir do histórico oficial do CMN/BCB (https://www.bcb.gov.br/controleinflacao/historicometas).

Nota (2003–2004): usamos as metas ajustadas da Carta Aberta de 21/01/2003 (8,5% para 2003 e 5,5% para 2004), que foram as metas efetivamente perseguidas pelo BCB. As metas originais (4,0% e 3,75%) estão comentadas para robustez.

metas <- tibble::tribble(
  ~ano, ~pi_star,
  1999, 8.00,  2000, 6.00,  2001, 4.00,  2002, 3.50,
  2003, 8.50,  # meta ajustada; original = 4.00
  2004, 5.50,  # meta ajustada; original = 3.75
  2005, 4.50,  2006, 4.50,  2007, 4.50,  2008, 4.50,
  2009, 4.50,  2010, 4.50,  2011, 4.50,  2012, 4.50,
  2013, 4.50,  2014, 4.50,  2015, 4.50,  2016, 4.50,
  2017, 4.50,  2018, 4.50,  2019, 4.25,  2020, 4.00,
  2021, 3.75,  2022, 3.50,  2023, 3.25,  2024, 3.00,
  2025, 3.00   # meta contínua — Decreto 12.079/2024
)

3.4 Hiato do produto (filtro HP, \(\lambda = 1600\))

O PIB trimestral é dessazonalizado (X-13ARIMA-SEATS via seasonal; fallback por STL), tomamos o logaritmo e aplicamos o filtro HP: \(\tilde{y}_t = 100\,(\ln Y_t - \ln Y^*_t)\).

pib_q <- pib_raw |>
  mutate(tri = as.yearqtr(date)) |>
  arrange(tri)

gdp_ts <- ts(pib_q$pib,
             start     = c(year(min(pib_q$date)), quarter(min(pib_q$date))),
             frequency = 4)

gdp_sa <- tryCatch({
  sa <- seasonal::seas(gdp_ts)
  seasonal::final(sa)
}, error = function(e) {
  message("X-13 indisponível — usando STL.")
  st <- stl(log(gdp_ts), s.window = "periodic")
  exp(log(gdp_ts) - st$time.series[, "seasonal"])
})

log_gdp   <- log(as.numeric(gdp_sa))
hp        <- mFilter::hpfilter(log_gdp, freq = 1600, type = "lambda")
hiato_vec <- 100 * (log_gdp - as.numeric(hp$trend))
hiato_tri <- tibble(tri = pib_q$tri, hiato = hiato_vec)

3.5 Painel trimestral final

base <- selic_tri |>
  inner_join(ipca_tri,  by = "tri") |>
  inner_join(hiato_tri, by = "tri") |>
  mutate(ano = as.integer(floor(as.numeric(tri)))) |>
  left_join(metas, by = "ano") |>
  mutate(desvio = pi - pi_star) |>
  arrange(tri) |>
  mutate(i_lag = lag(i)) |>
  filter(tri >= as.yearqtr("1999 Q3"),
         tri <= as.yearqtr("2025 Q4")) |>
  drop_na(i, i_lag, desvio, hiato)

kb(head(base |> mutate(tri = as.character(tri)), 6),
   cap = "Primeiras observações do painel (1999 T3 …).")
Primeiras observações do painel (1999 T3 …).
tri i pi hiato ano pi_star desvio i_lag
1999 Q3 19.89 6.25 -0.32 1999 8 -1.75 28.19
1999 Q4 18.95 8.94 0.00 1999 8 0.94 19.89
2000 Q1 18.88 6.92 -0.01 2000 6 0.92 18.95
2000 Q2 18.39 6.51 0.99 2000 6 0.51 18.88
2000 Q3 16.64 7.77 1.75 2000 6 1.77 18.39
2000 Q4 16.43 5.97 2.10 2000 6 -0.03 16.64

4 Análise exploratória

4.1 Séries no tempo

base |>
  mutate(data = as.Date(tri)) |>
  select(data, `Selic (i)` = i, `IPCA 12m` = pi, `Meta (π*)` = pi_star) |>
  pivot_longer(-data, names_to = "série", values_to = "valor") |>
  ggplot(aes(data, valor, colour = série)) +
  geom_line(linewidth = 0.8) +
  scale_x_date(date_breaks = "3 years", date_labels = "%Y") +
  labs(x = NULL, y = "% a.a.", colour = NULL) +
  theme(legend.position = "bottom")
Selic, IPCA 12m e meta de inflação (% a.a.).

Selic, IPCA 12m e meta de inflação (% a.a.).

Episódios de afastamento da inflação em relação à meta. A inflação superou significativamente a meta em três grandes momentos: (i) 2002–2003 — crise de confiança pré-eleitoral e forte depreciação cambial (IPCA de 12,5% em 2002 e 9,3% em 2003); (ii) 2015–2016 — recessão e crise fiscal/política, com IPCA de 10,67% em 2015; e (iii) 2021–2022 — choque pós-pandemia de energia, câmbio e commodities (IPCA de 10,1% em 2021). Em cada episódio a Selic respondeu com elevação acentuada. O desvio negativo persistente de 2017–2018 e o vale de 2020 marcam as fases de afrouxamento.

4.2 Estatísticas descritivas e correlações

vars <- base |> select(i, i_lag, pi, pi_star, desvio, hiato)

desc <- tibble(
  Variável    = c("i_t", "i_{t-1}", "pi_t", "pi*_t", "Desvio", "Hiato"),
  Média       = sapply(vars, mean,   na.rm = TRUE),
  `Desv.Pad.` = sapply(vars, sd,     na.rm = TRUE),
  Mínimo      = sapply(vars, min,    na.rm = TRUE),
  Máximo      = sapply(vars, max,    na.rm = TRUE)
)
kb(desc, cap = "Estatísticas descritivas.")
Estatísticas descritivas.
Variável Média Desv.Pad. Mínimo Máximo
i_t 12.43 4.96 1.90 26.24
i_{t-1} 12.55 5.18 1.90 28.19
pi_t 6.25 2.69 2.13 16.57
pi*_t 4.50 1.15 3.00 8.50
Desvio 1.75 2.39 -1.96 9.03
Hiato 0.01 1.80 -10.13 3.46
kb(as.data.frame(round(cor(vars, use = "complete.obs"), 2)),
   cap = "Matriz de correlação.")
Matriz de correlação.
i i_lag pi pi_star desvio hiato
i 1.00 0.96 0.55 0.46 0.40 -0.08
i_lag 0.96 1.00 0.43 0.55 0.22 -0.14
pi 0.55 0.43 1.00 0.46 0.90 -0.08
pi_star 0.46 0.55 0.46 1.00 0.04 -0.12
desvio 0.40 0.22 0.90 0.04 1.00 -0.04
hiato -0.08 -0.14 -0.08 -0.12 -0.04 1.00

5 Estimação por MQO

5.1 Amostra completa (1999 T3 – 2025 T4)

m_full <- lm(i ~ i_lag + desvio + hiato, data = base)
modelsummary(
  m_full,
  coef_rename = c("(Intercept)" = "Constante (α)",
                  "i_lag"       = "i(t-1)  —  ρ̂",
                  "desvio"      = "π - π*  —  γ̂_π",
                  "hiato"       = "Hiato ỹ  —  γ̂_y"),
  gof_map  = c("nobs","r.squared","adj.r.squared"),
  stars    = TRUE,
  title    = "Regra de Taylor — MQO, amostra completa (1999 T3 – 2025 T4)",
  notes    = "* p<0,1 ; ** p<0,05 ; *** p<0,01. Erros-padrão entre parênteses."
)
Regra de Taylor — MQO, amostra completa (1999 T3 – 2025 T4)
(1)
+ p < 0.1, * p < 0.05, ** p < 0.01, *** p < 0.001
* p<0,1 ; ** p<0,05 ; *** p<0,01. Erros-padrão entre parênteses.
Constante (α) 0.627*
(0.267)
i(t-1) — ρ̂ 0.882***
(0.020)
π - π* — γ̂_π 0.415***
(0.043)
Hiato ỹ — γ̂_y 0.169**
(0.057)
Num.Obs. 106
R2 0.958
R2 Adj. 0.956

5.2 Recuperação dos parâmetros estruturais

recuperar <- function(m) {
  b   <- coef(m)
  rho <- unname(b["i_lag"])
  c(rho    = rho,
    i_star = unname(b["(Intercept)"]) / (1 - rho),
    phi_pi = unname(b["desvio"])      / (1 - rho),
    phi_y  = unname(b["hiato"])       / (1 - rho))
}
est <- recuperar(m_full)

kb(tibble(
  Parâmetro  = c("ρ  (suavização)",
                 "i* (juro neutro, % a.a.)",
                 "φ_π (resposta à inflação)",
                 "φ_y (resposta ao hiato)"),
  Estimativa = round(est, 3)
), cap = "Parâmetros estruturais recuperados.")
Parâmetros estruturais recuperados.
Parâmetro Estimativa
ρ (suavização) 0.88
i* (juro neutro, % a.a.) 5.32
φ_π (resposta à inflação) 3.52
φ_y (resposta ao hiato) 1.43

5.3 Interpretação econômica

(a) Suavização — \(\hat\rho\). O coeficiente estimado é \(\hat\rho = 0.882\), grau elevado (forte suavização). Valores próximos a 1 indicam que o BCB ajusta a Selic de forma gradual e persistente: cada decisão incorpora forte inércia da taxa do trimestre anterior. Esse padrão é consistente com a literatura empírica de política monetária e reflete a preferência por trajetórias suaves que preservam previsibilidade e evitam volatilidade excessiva nos mercados financeiros.

(b) Princípio de Taylor — \(\hat\phi_\pi\). A resposta de longo prazo à inflação é \(\hat\phi_\pi = 3.519\), valor que satisfaz o Princípio de Taylor (\(\phi_\pi > 1\)). Quando \(\phi_\pi > 1\), o banco central eleva a taxa de juros real em resposta a desvios positivos da inflação — condição necessária para a estabilidade nominal e a ancoragem das expectativas. Um valor abaixo de 1 implicaria política monetária acomodatícia e potencialmente desestabilizadora.

(c) Resposta ao hiato — \(\hat\phi_y\). Estima-se \(\hat\phi_y = 1.434\), de sinal positivo — sinal esperado pela teoria e estatisticamente significante (p < 0,05). O sinal positivo é o previsto pelo modelo NK: o BCB tende a elevar os juros quando o produto está acima do potencial (hiato positivo), sinal de pressão de demanda. A magnitude modesta reflete o foco primário do regime de metas na inflação, não no nível de atividade.

(d) Taxa de juros neutra implícita — \(\hat i^*\). A taxa nominal neutra implícita é \(\hat i^* = 5.32\%\) a.a. Como a amostra cobre 1999–2025 — período que inclui anos com Selic acima de 20% — este valor tende a ser elevado sobre a janela completa. Estimativas em subperíodos mais recentes devem mostrar queda gradual, refletindo o processo de desinflação e redução do juro estrutural brasileiro.

5.4 Taxa prescrita vs. Selic efetiva

base <- base |> mutate(i_hat = predict(m_full), gap = i - i_hat)

base |>
  mutate(data = as.Date(tri)) |>
  select(data, `Selic efetiva` = i, `Regra estimada` = i_hat) |>
  pivot_longer(-data, names_to = "série", values_to = "valor") |>
  ggplot(aes(data, valor, colour = série)) +
  geom_line(linewidth = 0.8) +
  scale_x_date(date_breaks = "3 years", date_labels = "%Y") +
  labs(x = NULL, y = "% a.a.", colour = NULL) +
  theme(legend.position = "bottom")
Selic efetiva vs. taxa prescrita pela regra estimada (valores ajustados do modelo).

Selic efetiva vs. taxa prescrita pela regra estimada (valores ajustados do modelo).

A diferença \(i_t - \hat\imath_t\) (coluna gap) identifica subperíodos em que o BCB operou acima (postura mais contracionista que o prescrito) ou abaixo (mais expansionista). Em geral, episódios de combate à inflação alta tendem a mostrar Selic acima da regra; fases de afrouxamento agressivo (2012–2013 e 2020) costumam mostrar Selic abaixo. Comente os subperíodos concretos que aparecerem no seu gráfico.


6 Análise por subperíodos (bônus)

base <- base |>
  mutate(periodo = case_when(
    tri >= as.yearqtr("1999 Q3") & tri <= as.yearqtr("2002 Q4") ~ "I (99-02)",
    tri >= as.yearqtr("2003 Q1") & tri <= as.yearqtr("2010 Q4") ~ "II (03-10)",
    tri >= as.yearqtr("2011 Q1") & tri <= as.yearqtr("2016 Q4") ~ "III (11-16)",
    tri >= as.yearqtr("2017 Q1") & tri <= as.yearqtr("2024 Q4") ~ "IV (17-24)",
    TRUE ~ NA_character_
  ))

m1 <- lm(i ~ i_lag + desvio + hiato, data = filter(base, periodo == "I (99-02)"))
m2 <- lm(i ~ i_lag + desvio + hiato, data = filter(base, periodo == "II (03-10)"))
m3 <- lm(i ~ i_lag + desvio + hiato, data = filter(base, periodo == "III (11-16)"))
m4 <- lm(i ~ i_lag + desvio + hiato, data = filter(base, periodo == "IV (17-24)"))
modelsummary(
  list("I (99-02)" = m1, "II (03-10)" = m2,
       "III (11-16)" = m3, "IV (17-24)" = m4),
  coef_rename = c("(Intercept)" = "Constante (α)",
                  "i_lag"       = "i(t-1)  (ρ)",
                  "desvio"      = "π - π*  (γ_π)",
                  "hiato"       = "Hiato ỹ  (γ_y)"),
  gof_map  = c("nobs","r.squared","adj.r.squared"),
  stars    = TRUE,
  title    = "Regra de Taylor por subperíodo (MQO)",
  notes    = "* p<0,1 ; ** p<0,05 ; *** p<0,01."
)
Regra de Taylor por subperíodo (MQO)
I (99-02) II (03-10) III (11-16) IV (17-24)
+ p < 0.1, * p < 0.05, ** p < 0.01, *** p < 0.001
* p<0,1 ; ** p<0,05 ; *** p<0,01.
Constante (α) 11.689*** 2.330** -1.289 -0.023
(2.456) (0.767) (0.888) (0.223)
i(t-1) (ρ) 0.317* 0.784*** 1.029*** 0.940***
(0.117) (0.056) (0.084) (0.023)
π - π* (γ_π) 0.321* 0.592*** 0.379*** 0.360***
(0.127) (0.108) (0.094) (0.033)
Hiato ỹ (γ_y) -0.524 0.349* 0.289** 0.063
(0.333) (0.130) (0.084) (0.045)
Num.Obs. 14 32 24 32
R2 0.672 0.954 0.961 0.985
R2 Adj. 0.574 0.949 0.955 0.983
estr_sub <- t(sapply(list(`I`=m1,`II`=m2,`III`=m3,`IV`=m4), recuperar))

kb(as.data.frame(round(estr_sub, 3)),
   cap = "Parâmetros estruturais por subperíodo.")
Parâmetros estruturais por subperíodo.
rho i_star phi_pi phi_y
I 0.32 17.10 0.47 -0.77
II 0.78 10.79 2.74 1.62
III 1.03 44.75 -13.17 -10.04
IV 0.94 -0.38 6.02 1.04

Comparação entre subperíodos. Avalie na tabela acima: (i) se \(\hat\phi_\pi\) aumentou ao longo do tempo, indicando reação mais intensa à inflação e satisfação mais robusta do Princípio de Taylor — o que sinalizaria amadurecimento institucional do RMI; (ii) se \(\hat\phi_y\) ganhou relevância como estabilizador cíclico; e (iii) se o grau de suavização \(\hat\rho\) variou entre gestões do BCB.

Ressalva: os subperíodos I e III têm poucas observações (~14 e ~24 trimestres), o que amplia os erros-padrão. Os parâmetros estruturais — que dividem por \((1-\hat\rho)\) — podem ficar instáveis quando \(\hat\rho\) é grande.


7 Nota sobre erros-padrão (robustez)

Com a variável dependente defasada e possível autocorrelação dos resíduos, convém verificar erros-padrão HAC (Newey–West, \(\ell=4\)):

coeftest(m_full, vcov. = NeweyWest(m_full, lag = 4, prewhite = FALSE))
## 
## t test of coefficients:
## 
##             Estimate Std. Error t value              Pr(>|t|)    
## (Intercept) 0.627365   0.409033  1.5338             0.1281805    
## i_lag       0.882043   0.040037 22.0309 < 0.00000000000000022 ***
## desvio      0.415048   0.060921  6.8129       0.0000000006814 ***
## hiato       0.169110   0.049553  3.4127             0.0009235 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Se os erros HAC forem substancialmente maiores que os OLS padrão, a inferência clássica pode estar otimista — vale mencionar isso na discussão.


## Sessão R: 2026-06-03 16:03:37.731824
## R version 4.5.1 (2025-06-13 ucrt)
## Platform: x86_64-w64-mingw32/x64
## Running under: Windows 11 x64 (build 26200)
## 
## Matrix products: default
##   LAPACK version 3.12.1
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
##  [1] lmtest_0.9-40      sandwich_3.1-1     kableExtra_1.4.0   knitr_1.50        
##  [5] modelsummary_2.6.0 mFilter_0.1-5      ggplot2_4.0.1      zoo_1.8-15        
##  [9] lubridate_1.9.4    tidyr_1.3.2        dplyr_1.2.1        GetBCBData_0.9.1  
## 
## loaded via a namespace (and not attached):
##  [1] sass_0.4.10         generics_0.1.4      xml2_1.4.1         
##  [4] stringi_1.8.7       lattice_0.22-7      digest_0.6.38      
##  [7] magrittr_2.0.4      evaluate_1.0.5      grid_4.5.1         
## [10] timechange_0.3.0    RColorBrewer_1.1-3  fastmap_1.2.0      
## [13] jsonlite_2.0.0      backports_1.5.0     seasonal_1.10.0    
## [16] purrr_1.2.0         viridisLite_0.4.2   scales_1.4.0       
## [19] codetools_0.2-20    textshaping_1.0.4   jquerylib_0.1.4    
## [22] cli_3.6.6           x13binary_1.1.61.2  rlang_1.2.0        
## [25] performance_0.17.0  litedown_0.9        tinytable_0.16.0   
## [28] withr_3.0.2         cachem_1.1.0        yaml_2.3.10        
## [31] datawizard_1.3.1    tools_4.5.1         checkmate_2.3.4    
## [34] bayestestR_0.18.1   vctrs_0.7.3         R6_2.6.1           
## [37] lifecycle_1.0.5     stringr_1.6.0       insight_1.5.1      
## [40] pkgconfig_2.0.3     pillar_1.11.1       bslib_0.9.0        
## [43] gtable_0.3.6        glue_1.8.0          data.table_1.18.2.1
## [46] systemfonts_1.3.1   xfun_0.57           tibble_3.3.1       
## [49] tidyselect_1.2.1    parameters_0.29.1   rstudioapi_0.17.1  
## [52] farver_2.1.2        htmltools_0.5.8.1   tables_0.9.33      
## [55] labeling_0.4.3      rmarkdown_2.30      svglite_2.2.2      
## [58] compiler_4.5.1      S7_0.2.1