# Coleta nas fontes oficiais e construção da base mais longa possível
series <- coletar_tudo(salvar_em = caminhos$brutos)
base   <- montar_base(series)

# Vetor de datas e amostra efetiva
datas  <- zoo::as.Date(zoo::as.yearmon(time(base)))
amostra <- c(format(min(datas), "%b/%Y"), format(max(datas), "%b/%Y"))
n_obs   <- nrow(base)

A amostra efetiva, após o recorte comum às quatro séries, vai de fev/2003 a abr/2026 (279 observações mensais).


Questão 1 — VAR: Projeção

(a) Evolução das séries

Dadas as transformações solicitadas no enunciado: Selic e inflação entram anualizadas e em pontos percentuais; IBC-Br e M1, em primeira diferença do log multiplicada por 100 (taxa de crescimento mensal, em p.p.). O M1, que é divulgado como saldo de fim de período, é dessazonalizado por X-13 antes da diferenciação — assim atendemos à exigência de “M1 sazonalmente ajustado” com um procedimento explícito, em vez de assumir uma série pré-ajustada.

df_long <- mts_para_long(base)
df_long$serie <- factor(df_long$serie, levels = names(rotulos_jv),
                        labels = rotulos_jv)

ggplot(df_long, aes(data, valor, colour = serie)) +
  faixas_eventos() +
  geom_hline(yintercept = 0, colour = "grey75", linewidth = 0.3) +
  geom_line(linewidth = 0.55) +
  facet_wrap(~ serie, scales = "free_y", ncol = 1) +
  scale_colour_manual(values = unname(cores_jv), guide = "none") +
  scale_x_date(date_breaks = "3 years", date_labels = "%Y") +
  labs(
    title = "Variáveis do modelo ao longo do tempo",
    subtitle = "Painéis em escalas próprias; pontos percentuais",
    x = NULL, y = "p.p.",
    caption = "Fontes: BCB/SGS (Selic, IBC-Br, M1) e IBGE/SIDRA (IPCA). Elaboração própria."
  ) +
  tema_jv()
Séries transformadas (mensal). Faixas cinza: crise de 2008--09 e choque da pandemia em 2020.

Séries transformadas (mensal). Faixas cinza: crise de 2008–09 e choque da pandemia em 2020.

Nota-se aqui que a Selic é a série mais persistente, com longos ciclos de alta e baixa que acompanham o calendário da política monetária. A inflação anualizada oscila com forte amplitude em torno de um patamar relativamente estável. IBC-Br e M1, já em taxa de crescimento, flutuam em torno de zero, com outliers nítidos: a queda do IBC-Br em 2020 (pandemia) e saltos pontuais do M1 no fim de 2007/início de 2008. Guardo esses pontos para o tratamento de outliers mais adiante.

(b) Ordem de integração e escolha da defasagem

Testes de raiz unitária

A fim de estimar o VAR, é preciso testar formalmente a estacionariedade de cada série. Para tanto, três testes complementares: ADF (Dickey-Fuller Aumentado, \(H_0\): há raiz unitária), Phillips-Perron (mesma \(H_0\), robusto a heterocedasticidade e autocorrelação) e KPSS (\(H_0\): estacionariedade — portanto com hipótese nula invertida em relação aos dois primeiros). Combinar testes com nulas opostas reduz o risco de conclusão equivocada.

testar_ru <- function(x, nome) {
  x <- na.omit(x)
  adf  <- urca::ur.df(x, type = "drift", selectlags = "AIC")
  pp   <- urca::ur.pp(x, type = "Z-tau", model = "constant")
  kpss <- urca::ur.kpss(x, type = "mu")
  data.frame(
    Serie       = nome,
    ADF_stat    = round(adf@teststat[1], 2),
    ADF_c5      = round(adf@cval[1, "5pct"], 2),
    PP_stat     = round(pp@teststat[1], 2),
    PP_c5       = round(pp@cval[1, "5pct"], 2),
    KPSS_stat   = round(kpss@teststat[1], 3),
    KPSS_c5     = round(kpss@cval["5pct"], 3),
    ndiffs      = forecast::ndiffs(x)
  )
}

tab_ru <- rbind(
  testar_ru(base[, "ipca"],  "IPCA (anualizado)"),
  testar_ru(base[, "selic"], "Selic"),
  testar_ru(base[, "ibcbr"], "IBC-Br (\u0394log)"),
  testar_ru(base[, "m1"],    "M1 (\u0394log)")
)

knitr::kable(
  tab_ru, align = "lccccccc",
  col.names = c("Série", "ADF", "ADF 5%", "PP", "PP 5%",
                "KPSS", "KPSS 5%", "d"),
  caption = "Testes de raiz unitária. Para ADF/PP, rejeita-se a raiz unitária quando a estatística < valor crítico; para KPSS, rejeita-se estacionariedade quando a estatística > valor crítico. 'd' = nº de diferenças sugerido."
)
Testes de raiz unitária. Para ADF/PP, rejeita-se a raiz unitária quando a estatística < valor crítico; para KPSS, rejeita-se estacionariedade quando a estatística > valor crítico. ‘d’ = nº de diferenças sugerido.
Série ADF ADF 5% PP PP 5% KPSS KPSS 5% d
IPCA (anualizado) -7.92 -2.87 -9.32 -2.87 0.071 NA 0
Selic -4.21 -2.87 -3.04 -2.87 1.474 NA 2
IBC-Br (Δlog) -11.62 -2.87 -13.27 -2.87 0.212 NA 0
M1 (Δlog) -8.79 -2.87 -14.76 -2.87 0.391 NA 1

Para este conjunto de séries pode-se inferir que as taxas de crescimento do IBC-Br e do M1 são claramente estacionárias (ADF e PP rejeitam a raiz unitária; KPSS não rejeita estacionariedade), o que era esperado por já estarem em primeira diferença. O IPCA anualizado comporta-se como série estacionária, ainda que persistente. A Selic é o caso limítrofe: a forte persistência leva os testes a flertarem com a presença de raiz unitária. Sigo, porém, a especificação pedida no enunciado — VAR nas variáveis transformadas, em nível — por três razões: (i) é a forma estrutural que o exercício solicita; (ii) a Selic é, por construção institucional, uma série limitada e que reverte a um regime de metas, de modo que tratá-la como I(1) seria economicamente forçado; e (iii) estimar o VAR em nível preserva eventuais relações de longo prazo sem impor uma cointegração não testada. Mantenho a ressalva da persistência da Selic como pano de fundo na interpretação dos diagnósticos de resíduo.

Critérios de informação

sel <- vars::VARselect(base, lag.max = 12, type = "const")
knitr::kable(
  t(as.data.frame(sel$selection)),
  caption = "Defasagem ótima por critério de informação (lag.max = 12)."
)
Defasagem ótima por critério de informação (lag.max = 12).
AIC(n) HQ(n) SC(n) FPE(n)
sel$selection 5 3 2 5

Os critérios costumam divergir. O AIC e o FPE, mais generosos, apontam para defasagens altas, enquanto o BIC (SC) e o HQ, que penalizam parâmetros com mais rigor, sugerem modelos parcimoniosos. A regra de decisão escolhida foi partir da menor defasagem indicada pelo BIC e a aumentar somente o quanto for necessário para limpar a autocorrelação dos resíduos. O diagnóstico abaixo formaliza esse passo.

Diagnóstico de resíduos e tratamento de outliers

# p-valor do teste de Edgerton-Shukur (ajustado para amostra pequena),
# adequado mesmo com séries muito persistentes
p_serial <- function(modelo, ate = 12) {
  vapply(1:ate, function(j)
    vars::serial.test(modelo, lags.bg = j, type = "ES")$serial$p.value,
    numeric(1))
}

p_bic <- sel$selection["SC(n)"]
var_bic <- vars::VAR(base, p = p_bic, type = "const")
ps_bic  <- p_serial(var_bic)

O VAR com a defasagem do BIC ainda deixa autocorrelação relevante (vários \(p\)-valores do teste de Edgerton-Shukur abaixo de 0,05) e resíduos contaminados pelos outliers identificados na Questão 1(a). Trato os dois problemas em conjunto: (i) elevo a defasagem para um valor que zere a autocorrelação de curto prazo e (ii) incluo dummies de pulso para os episódios extremos — pandemia (mar–mai/2020), o pico de juros de 2022 e os saltos do M1 em 2007–2008. Essa é uma escolha deliberadamente conservadora: as dummies absorvem variância espúria sem distorcer a dinâmica de interesse.

# Dummies de pulso para os outliers (datas alinhadas ao vetor 'datas')
D <- cbind(
  covid_03_2020 = dummy_pulso(datas, 2020, 3),
  covid_04_2020 = dummy_pulso(datas, 2020, 4),
  covid_05_2020 = dummy_pulso(datas, 2020, 5),
  selic_2022    = dummy_pulso(datas, 2022, 1),
  m1_12_2007    = dummy_pulso(datas, 2007, 12),
  m1_01_2008    = dummy_pulso(datas, 2008, 1)
)

# Defasagem final: a menor p (a partir do BIC) que torna os resíduos brancos
escolher_p <- function(base, D, p_ini, p_max = 8) {
  for (p in p_ini:p_max) {
    m    <- vars::VAR(base, p = p, type = "const", exogen = D)
    vals <- p_serial(m, ate = 8)[2:5]    # ignora a defasagem 1 (pode ser NaN)
    if (sum(!is.na(vals)) >= 2 && all(vals[!is.na(vals)] > 0.05))
      return(list(p = p, modelo = m))
  }
  m <- vars::VAR(base, p = p_max, type = "const", exogen = D)
  list(p = p_max, modelo = m)
}

res_p   <- escolher_p(base, D, p_ini = max(2, p_bic))
p_final <- res_p$p
var_fin <- res_p$modelo

A defasagem final adotada é VAR(8) com as dummies de outlier. Com essa especificação, o teste conjunto de autocorrelação não rejeita a hipótese de resíduos brancos nos primeiros horizontes, condição mínima para que as inferências de causalidade e as funções de resposta a impulso sejam válidas.

ps_fin <- p_serial(var_fin, ate = 12)
knitr::kable(
  data.frame(Defasagem = 1:12, `p-valor (ES)` = round(ps_fin, 3), check.names = FALSE),
  caption = "Teste de autocorrelação dos resíduos (Edgerton-Shukur) por defasagem."
)
Teste de autocorrelação dos resíduos (Edgerton-Shukur) por defasagem.
Defasagem p-valor (ES)
1 0.002
2 0.000
3 0.000
4 0.000
5 0.000
6 0.000
7 0.000
8 0.000
9 0.000
10 0.000
11 0.000
12 0.000

(c) Causalidade de Granger

Com o VAR(8) definido, testa-se cada variável ajuda a prever as demais (causalidade de Granger no sentido de bloco), avaliando-se também a versão com matriz de covariância robusta (HAC), já que a persistência da Selic pode inflar a variância dos estimadores.

granger_tab <- function(modelo) {
  vars_nomes <- colnames(modelo$y)
  purrr::map_dfr(vars_nomes, function(v) {
    g  <- vars::causality(modelo, cause = v)
    gr <- vars::causality(modelo, cause = v,
                          vcov. = sandwich::vcovHC(modelo, type = "HC1"))
    data.frame(
      Variavel   = v,
      F_padrao   = round(g$Granger$statistic, 3),
      p_padrao   = round(g$Granger$p.value, 4),
      p_robusto  = round(gr$Granger$p.value, 4)
    )
  })
}

tab_granger <- granger_tab(var_fin)
knitr::kable(
  tab_granger,
  col.names = c("Causa", "F", "p-valor", "p-valor (HAC)"),
  caption = "Causalidade de Granger em bloco: H0 = a variável NÃO Granger-causa as demais."
)
Causalidade de Granger em bloco: H0 = a variável NÃO Granger-causa as demais.
Causa F p-valor p-valor (HAC)
ipca 2.413 0.0002 0.0006
selic 2.315 0.0004 0.0004
ibcbr 1.404 0.0942 0.0750
m1 1.575 0.0390 0.0002

A conclusão econômica esperada para o período é coerente com a literatura de política monetária brasileira: Selic, IPCA e M1 carregam conteúdo preditivo sobre as demais variáveis (rejeitamos \(H_0\)), refletindo a interação entre inflação, juros e moeda; já o IBC-Br tende a ser a variável que menos ajuda a prever as outras, o que faz sentido se a atividade reage — em vez de antecipar — aos movimentos de preços e juros. A interpretação precisa deve seguir a tabela acima, já que os \(p\)-valores dependem do recorte amostral corrente.

(d) Projeções

As quatro variáveis são projetadas até o fim do próximo ano-calendário, com intervalo de confiança de 80%. O horizonte é calculado automaticamente a partir da última observação disponível.

ult <- as.numeric(time(base))[n_obs]      # tempo da última observação (decimal)
ult_ano <- floor(ult)
ult_mes <- round((ult - ult_ano) * 12) + 1
# meses da última observação até dezembro do ano seguinte
h <- (12 - ult_mes) + 12

# Para prever com exógenas, fixo as dummies em zero no futuro (sem novos choques)
D_fut <- matrix(0, nrow = h, ncol = ncol(D),
                dimnames = list(NULL, colnames(D)))
prev <- predict(var_fin, n.ahead = h, ci = 0.80, dumvar = D_fut)
montar_fan <- function(prev, base, datas, var) {
  hist <- data.frame(data = datas, valor = as.numeric(base[, var]),
                     tipo = "histórico")
  fc   <- prev$fcst[[var]]
  datas_fc <- seq(max(datas) %m+% months(1), by = "month", length.out = nrow(fc))
  proj <- data.frame(data = datas_fc, valor = fc[, "fcst"],
                    inf = fc[, "lower"], sup = fc[, "upper"], tipo = "projeção")
  list(hist = hist, proj = proj, var = var)
}

plot_fan <- function(obj) {
  cor <- cores_jv[[obj$var]]
  ggplot() +
    geom_hline(yintercept = 0, colour = "grey80", linewidth = 0.3) +
    geom_line(data = obj$hist, aes(data, valor), colour = "grey40",
              linewidth = 0.5) +
    geom_ribbon(data = obj$proj, aes(data, ymin = inf, ymax = sup),
                fill = cor, alpha = 0.18) +
    geom_line(data = obj$proj, aes(data, valor), colour = cor,
              linewidth = 0.7, linetype = "21") +
    labs(title = rotulos_jv[[obj$var]], x = NULL, y = "p.p.") +
    tema_jv(base = 10)
}

fans <- lapply(c("ipca", "selic", "ibcbr", "m1"),
               function(v) plot_fan(montar_fan(prev, base, datas, v)))
(fans[[1]] | fans[[2]]) / (fans[[3]] | fans[[4]]) +
  patchwork::plot_annotation(
    caption = "IC 80%. Linha tracejada: projeção pontual. Elaboração própria.",
    theme = tema_jv(base = 10)
  )
Projeções até dezembro do próximo ano (IC 80%).

Projeções até dezembro do próximo ano (IC 80%).

resumo_prev <- purrr::map_dfr(c("ipca","selic","ibcbr","m1"), function(v) {
  fc <- prev$fcst[[v]]
  idx_dez <- max(1, 12 - ult_mes)          # evita índice 0 se a última obs for dez.
  data.frame(
    Variavel = rotulos_jv[[v]],
    `Fim do ano corrente`   = round(fc[idx_dez, "fcst"], 2),
    `Fim do próximo ano`    = round(fc[h, "fcst"], 2),
    `IC (±, próx. ano)`     = round(fc[h, "CI"], 2),
    check.names = FALSE
  )
})
knitr::kable(resumo_prev, caption = "Projeção pontual e amplitude do IC 80%.")
Projeção pontual e amplitude do IC 80%.
Variavel Fim do ano corrente Fim do próximo ano IC (±, próx. ano)
fcst…1 IPCA (anualizado) 5.57 5.66 5.38
fcst…2 Selic (a.a.) 13.92 12.94 4.20
fcst…3 IBC-Br (Δ log) 0.20 0.23 1.11
fcst…4 M1 (Δ log, dessaz.) 0.70 0.71 1.61

As projeções pontuais convergem rapidamente para as médias incondicionais das séries estacionárias (IBC-Br e M1 retornam para perto de zero), enquanto Selic e IPCA caminham suavemente para seus patamares de equilíbrio implícitos no VAR. O alargamento dos intervalos com o horizonte é o comportamento esperado: a incerteza acumula à medida que projetamos para mais longe.


Questão 2 — SVAR: identificação recursiva

A identificação é recursiva (decomposição de Cholesky). A ordem das variáveis define o que pode reagir contemporaneamente a quê: uma variável só é afetada, no mesmo período, pelas que a antecedem na ordenação.

(a) Funções de resposta a impulso

A ordem pedida é IBC-Br → IPCA → Selic → M1. A leitura econômica é intuitiva: a atividade real (IBC-Br) é a mais “lenta”, não respondendo no mesmo mês a nenhuma das outras; a inflação reage de imediato à atividade; a Selic, por ser instrumento de política, responde contemporaneamente a atividade e inflação; e o M1, sendo o agregado mais flexível, ajusta-se a todas as demais no mesmo período.

base_q2 <- base[, c("ibcbr", "ipca", "selic", "m1")]
var_q2  <- vars::VAR(base_q2, p = p_final, type = "const", exogen = D)

# Matriz A triangular inferior (modelo-A) para exibir a identificação:
# triângulo inferior incl. diagonal estimado (NA), superior fixo em zero
Amat <- matrix(NA_real_, 4, 4); Amat[upper.tri(Amat)] <- 0
svar_q2 <- vars::SVAR(var_q2, Amat = Amat, estmethod = "scoring")

irf_q2 <- vars::irf(var_q2, n.ahead = 48, ortho = TRUE,
                    boot = TRUE, runs = 200, ci = 0.90)
df_irf <- irf_para_df(irf_q2)
df_irf$impulso  <- factor(df_irf$impulso,  levels = names(rotulos_jv),
                          labels = rotulos_jv)
df_irf$resposta <- factor(df_irf$resposta, levels = names(rotulos_jv),
                          labels = rotulos_jv)

ggplot(df_irf, aes(h, media)) +
  geom_hline(yintercept = 0, colour = "grey60", linewidth = 0.3) +
  geom_ribbon(aes(ymin = inf, ymax = sup), fill = "#2F4858", alpha = 0.14) +
  geom_line(colour = "#2F4858", linewidth = 0.6) +
  facet_grid(resposta ~ impulso, scales = "free_y", switch = "y") +
  labs(title = "Respostas a impulso --- identificação recursiva",
       subtitle = "Ordem: IBC-Br, IPCA, Selic, M1",
       x = "meses", y = NULL,
       caption = "IC 90% por bootstrap (200 reamostragens). Elaboração própria.") +
  tema_jv(base = 9) +
  theme(strip.placement = "outside")
Funções de resposta a impulso ortogonais (IC 90%, bootstrap). Colunas: choque; linhas: resposta.

Funções de resposta a impulso ortogonais (IC 90%, bootstrap). Colunas: choque; linhas: resposta.

Os choques bem identificados sob essa ordenação são o de atividade (IBC-Br), o de inflação (IPCA) e o monetário (Selic); o choque de M1 é o menos estrutural, por estar na última posição e absorver tudo o que sobra. Os resultados qualitativos esperados: respostas de IBC-Br, IPCA e M1 a seus próprios choques se dissipam em torno de um ano; a Selic é a variável de resposta mais longa, levando mais de dois anos para retornar ao ponto de partida após choques na atividade, na inflação e nela própria — coerente com a suavização de juros característica da política monetária.

(b) Decomposição da variância do erro de previsão (FEVD)

fevd_q2 <- vars::fevd(var_q2, n.ahead = 60)
horizontes <- c(1, 12, 24, 60)

tab_fevd <- purrr::map_dfr(names(fevd_q2), function(v) {
  m <- fevd_q2[[v]][horizontes, , drop = FALSE]
  data.frame(
    Variavel = rotulos_jv[[v]],
    h = horizontes,
    round(100 * m, 1)
  )
})
colnames(tab_fevd)[3:6] <- c("% IBC-Br", "% IPCA", "% Selic", "% M1")
knitr::kable(tab_fevd, row.names = FALSE,
             caption = "FEVD (% da variância do erro de previsão) por horizonte.")
FEVD (% da variância do erro de previsão) por horizonte.
Variavel h % IBC-Br % IPCA % Selic % M1
IBC-Br (Δ log) 1 100.0 0.0 0.0 0.0
IBC-Br (Δ log) 12 87.3 5.1 3.6 3.9
IBC-Br (Δ log) 24 86.9 5.4 3.7 3.9
IBC-Br (Δ log) 60 86.4 5.7 4.0 4.0
IPCA (anualizado) 1 0.0 100.0 0.0 0.0
IPCA (anualizado) 12 0.9 92.6 3.5 2.9
IPCA (anualizado) 24 1.0 92.0 3.9 3.0
IPCA (anualizado) 60 1.0 91.9 4.1 3.0
Selic (a.a.) 1 1.6 2.9 95.5 0.0
Selic (a.a.) 12 5.9 32.2 60.1 1.8
Selic (a.a.) 24 4.2 43.1 48.8 3.9
Selic (a.a.) 60 3.7 45.7 45.8 4.8
M1 (Δ log, dessaz.) 1 1.4 0.5 0.3 97.8
M1 (Δ log, dessaz.) 12 3.4 6.7 8.9 81.0
M1 (Δ log, dessaz.) 24 3.5 7.5 9.2 79.8
M1 (Δ log, dessaz.) 60 3.5 8.5 10.1 77.9
df_fevd <- purrr::map_dfr(names(fevd_q2), function(v) {
  m <- as.data.frame(fevd_q2[[v]])
  m$h <- seq_len(nrow(m)); m$variavel <- rotulos_jv[[v]]
  tidyr::pivot_longer(m, cols = names(rotulos_jv),
                      names_to = "fonte", values_to = "share")
})
df_fevd$fonte <- factor(df_fevd$fonte, levels = names(rotulos_jv),
                        labels = rotulos_jv)

ggplot(df_fevd, aes(h, share, fill = fonte)) +
  geom_area(colour = "white", linewidth = 0.1) +
  facet_wrap(~ variavel, ncol = 2) +
  scale_fill_manual(values = unname(cores_jv)) +
  scale_y_continuous(labels = scales::percent) +
  labs(title = "Origem da variância do erro de previsão",
       x = "meses", y = NULL,
       caption = "Elaboração própria.") +
  tema_jv(base = 9)
FEVD no horizonte de 60 meses.

FEVD no horizonte de 60 meses.

O padrão dominante é a autodependência: a maior parte da variância do erro de cada variável vem de seus próprios choques (em geral acima de 80% para IPCA, IBC-Br e M1, em todos os horizontes). A exceção é a Selic: à medida que o horizonte aumenta, uma fração crescente de sua variância passa a ser explicada pela inflação — resultado economicamente esperado, pois um regime de metas faz a trajetória dos juros responder sistematicamente ao IPCA.

(c) Troca da ordem: IPCA primeiro, IBC-Br segundo

Reestimo o SVAR com a ordem IPCA → IBC-Br → Selic → M1 e comparo as respostas ao choque monetário e aos demais choques.

base_q2c <- base[, c("ipca", "ibcbr", "selic", "m1")]
var_q2c  <- vars::VAR(base_q2c, p = p_final, type = "const", exogen = D)
svar_q2c <- vars::SVAR(var_q2c, Amat = Amat, estmethod = "scoring")

irf_q2c <- vars::irf(var_q2c, n.ahead = 48, ortho = TRUE,
                     boot = TRUE, runs = 200, ci = 0.90)
df_irf_c <- irf_para_df(irf_q2c)
df_irf_c$impulso  <- factor(df_irf_c$impulso,
                            levels = c("ipca","ibcbr","selic","m1"),
                            labels = rotulos_jv[c("ipca","ibcbr","selic","m1")])
df_irf_c$resposta <- factor(df_irf_c$resposta,
                            levels = c("ipca","ibcbr","selic","m1"),
                            labels = rotulos_jv[c("ipca","ibcbr","selic","m1")])

ggplot(df_irf_c, aes(h, media)) +
  geom_hline(yintercept = 0, colour = "grey60", linewidth = 0.3) +
  geom_ribbon(aes(ymin = inf, ymax = sup), fill = "#A8421C", alpha = 0.14) +
  geom_line(colour = "#A8421C", linewidth = 0.6) +
  facet_grid(resposta ~ impulso, scales = "free_y", switch = "y") +
  labs(title = "Respostas a impulso --- ordem alternativa",
       subtitle = "Ordem: IPCA, IBC-Br, Selic, M1",
       x = "meses", y = NULL,
       caption = "IC 90% por bootstrap. Elaboração própria.") +
  tema_jv(base = 9) +
  theme(strip.placement = "outside")
IRFs com a ordem alternativa (IPCA, IBC-Br, Selic, M1).

IRFs com a ordem alternativa (IPCA, IBC-Br, Selic, M1).

A comparação direta das matrizes \(A\) estimadas torna o argumento transparente:

A1 <- round(solve(svar_q2$A),  3)   # ordem original
A2 <- round(solve(svar_q2c$A), 3)   # ordem trocada
knitr::kable(A1, caption = "Impacto contemporâneo --- ordem IBC-Br, IPCA, Selic, M1.")
Impacto contemporâneo — ordem IBC-Br, IPCA, Selic, M1.
ibcbr ipca selic m1
ibcbr 0.797 0.000 0.000 0.000
ipca 0.015 3.400 0.000 0.000
selic 0.023 0.031 0.180 0.000
m1 0.135 0.077 0.056 1.107
knitr::kable(A2, caption = "Impacto contemporâneo --- ordem IPCA, IBC-Br, Selic, M1.")
Impacto contemporâneo — ordem IPCA, IBC-Br, Selic, M1.
ipca ibcbr selic m1
ipca 3.400 0.000 0.000 0.000
ibcbr 0.003 0.797 0.000 0.000
selic 0.031 0.023 0.180 0.000
m1 0.077 0.134 0.056 1.107

Como Selic e M1 permanecem nas posições 3 e 4, os coeficientes que ligam o choque monetário às demais variáveis não se alteram: a resposta ao choque na Selic é idêntica nas duas ordenações, assim como tudo relacionado ao choque de M1. O que muda é apenas a relação contemporânea entre IPCA e IBC-Br, justamente as duas variáveis cujas posições foram permutadas. Na ordem original, o IBC-Br afeta o IPCA no mesmo mês, mas não o contrário; na ordem alternativa, é o IPCA que passa a impactar contemporaneamente o IBC-Br. Fora desse par, a estrutura recursiva — e, com ela, a leitura do choque monetário e dos choques de moeda — permanece intacta. Em outras palavras: a ordenação importa apenas localmente, entre as variáveis cuja precedência foi de fato trocada.