# Carregando os pacotes necessários (conferir Apêndice para instalação)
library(vars)
library(VARsignR)
library(readxl)
library(ggplot2)
library(dplyr)
library(tidyr)
library(tseries)
# Seeding para reprodutibilidade
set.seed(42)Econometria Aplicada - Exercício 1
1 Introdução
Em modelos VAR estruturais (SVAR), o objetivo é decompor os movimentos das variáveis em choques estruturais com interpretação econômica (por exemplo, um choque de política monetária). Partimos do VAR reduzido e da sua matriz de covariância dos resíduos; o desafio de identificação surge porque múltiplas decomposições ortogonais dessa covariância são possíveis, levando a diferentes mapas entre resíduos (reduzidos) e choques (estruturais). Em macroeconomia, essa identificação é crucial para interpretar funções impulso-resposta (IRFs) como efeitos causais e, assim, avaliar mecanismos e políticas.
Duas estratégias comuns são: (i) identificação recursiva via decomposição de Cholesky e (ii) restrições de sinais (Uhlig, 2005).
Identificação recursiva (Cholesky): impõe uma ordenação das variáveis e zera alguns efeitos contemporâneos. Em termos práticos, assume que certas variáveis não reagem instantaneamente a outras dentro do mesmo período. Pontos positivos: simples, transparente e fácil de implementar. Pontos negativos: sensível à ordenação escolhida e impõe restrições de tempo/zeros potencialmente fortes.
Restrições de sinais (Uhlig, 2005): em vez de zeros contemporâneos, impõe-se que as IRFs de determinadas variáveis tenham sinais específicos por alguns períodos após o choque (por exemplo, um aperto monetário eleva a taxa de juros e reduz inflação e produto por alguns trimestres). Procura-se uma decomposição que satisfaça essas restrições, usualmente por amostragem sobre rotações ortogonais. Pontos positivos: evita hipóteses rígidas de ordenação/zeros e permite incorporar conhecimento teórico mais fraco. Pontos negativos: identificação em conjunto (conjuntos de soluções), intervalos potencialmente amplos e resultados dependentes da escolha de sinais e janelas.
Comparar as duas abordagens é útil porque elas refletem suposições diferentes sobre a dinâmica contemporânea e sobre o conteúdo informacional das respostas. Em particular, Uhlig (2005) reporta que um choque contracionista aumenta juros e reduz inflação como esperado, mas os efeitos sobre o produto podem surpreender; aqui investigaremos a robustez desse resultado sob diferentes especificações e variáveis no VAR.
Esse documento está estruturado de forma a apresentar os códigos construídos para cada etapa do exercício à medida que avançamos na análise. A seguir, detalhamos os dados, a metodologia (VAR reduzido, Cholesky e restrições de sinais), os resultados (IRFs e análises de robustez), discussão e conclusão.
2 Dados
Utilizamos dados trimestrais para os EUA (1965.Q1–2005.Q4), consistentes com a base utilizada em Uhlig (2005) e disponibilizada no curso. O conjunto inclui: PIB real (GDP), deflator implícito do PIB (Deflator), índice de preços ao produtor para commodities (Commodity), taxa efetiva dos federal funds (FFD), reservas totais e não tomadas emprestadas das instituições depositárias (TotReserves, NonReserves), consumo real (Consumption), investimento privado doméstico real (Investment) e o spread entre o rendimento de títulos corporativos Aaa e o Treasury de 10 anos (spread). O spread está disponível a partir de 1983.Q1. Para descrição agregada rápida, reportamos abaixo estatísticas sumárias da base carregada. Em termos de transformações, adotaremos log das variáveis em nível real e de preços (rgdp, pgdp, pcomm_sa, rcons, rinv) e manteremos em porcentagem as variáveis já em taxa/nível percentual (ff, spread). Eventuais ajustes adicionais (dessazonalização, diferenciação para estacionariedade) serão discutidos na etapa de pré-processamento do VAR.
# Carregamento e descrição básica dos dados
df <- read_excel("../references/data_ea1_uhlig.xlsx")
summary(df) dates GDP Deflator Commodity
Min. :1965 Min. : 4062 Min. :18.34 Min. : 31.87
1st Qu.:1975 1st Qu.: 5701 1st Qu.:30.57 1st Qu.: 57.80
Median :1985 Median : 7953 Median :56.55 Median :102.73
Mean :1985 Mean : 8500 Mean :53.48 Mean : 92.78
3rd Qu.:1996 3rd Qu.:10683 3rd Qu.:74.67 3rd Qu.:123.85
Max. :2006 Max. :15067 Max. :91.98 Max. :163.58
FFD TotReserves NonReserves Consumption
Min. : 0.980 Min. :21.26 Min. :20808 Min. : 2466
1st Qu.: 4.525 1st Qu.:34.69 1st Qu.:34246 1st Qu.: 3594
Median : 5.690 Median :41.00 Median :39944 Median : 5114
Mean : 6.518 Mean :42.15 Mean :41408 Mean : 5492
3rd Qu.: 8.398 3rd Qu.:49.65 3rd Qu.:49065 3rd Qu.: 6957
Max. :19.100 Max. :62.67 Max. :60953 Max. :10175
Investment spread
Min. : 508.5 Min. :-0.0900
1st Qu.: 739.0 1st Qu.: 0.8375
Median :1130.3 Median : 1.0400
Mean :1238.5 Mean : 1.1451
3rd Qu.:1543.7 3rd Qu.: 1.4500
Max. :2743.8 Max. : 2.5700
NA's :72
A Figura 1 apresenta as séries temporais já transformadas (isto é, já em log quando necessário).
# Grid de gráficos das séries
df <- df %>%
mutate(dates = as.numeric(dates),
GDP = log(GDP),
Deflator = log(Deflator),
Commodity = log(Commodity),
Consumption = log(Consumption),
Investment = log(Investment),
NonReserves = log(NonReserves),
TotReserves = log(TotReserves))
df_long <- df %>%
pivot_longer(cols = -dates, names_to = "variavel", values_to = "valor")
plot1 <- ggplot(df_long, aes(x = dates, y = valor)) +
geom_line(color = "black") +
facet_wrap(~ variavel, scales = "free_y", ncol = 3) +
theme_bw() +
labs(x = "Tempo", y = "Valor")
plot1É importante notar que a variável de spread bancário possui dados ausentes para o período anterior a 1983. Isso é bastante relevante, uma vez que a estimação do modelo com o spread implica a redução do tamanho da amostra e a análise de um período diferente do usado por Uhlig (2005).
3 Metodologia
Esse relatório possui dois objetivos. Em primeiro lugar, replicar os resultados de Uhlig (2005) e discutir os resultados de cada uma das abordagens de identificação (Cholesky e restrições de sinais). Em segundo lugar, explorar variações na especificação do VAR (número de defasagens, inclusão/exclusão de variáveis). Portanto, vamos estimar dois VARs em janelas temporais diferentes. O primeiro VAR será bastante próximo do modelo original, utilizando as mesmas variáveis e período (1965.Q1–2005.Q4), mas com 4 defasagens (em vez de 12, como no artigo original, que utiliza dados mensais). O segundo VAR será estimado a partir de 1983.Q1 (para incluir o spread bancário) e com a inclusão das variáveis de investimento e consumo. Para ambos os casos, verificaremos a estacionariedade dos resíduos do VAR reduzido antes de prosseguir para a identificação estrutural, que será feita via Cholesky e restrições de sinais também para ambos os VARs.
4 Resultados
4.1 Modelo original (1965.Q1 a 2005.Q4, sem spread, consumo e investimento)
4.1.1 VAR reduzido
df_var1 <- df %>% select(-c(dates, Consumption, Investment, spread))
var_model <- VAR(df_var1, p = 4, type = "none")
# Teste ADF nos resíduos (uma série por coluna)
residuos <- residuals(var_model)
adf_list <- lapply(as.data.frame(residuos), function(x) tseries::adf.test(x))
adf_table <- data.frame(
variavel = names(adf_list),
statistic = sapply(adf_list, function(r) unname(r$statistic)),
p_value = sapply(adf_list, function(r) r$p.value),
row.names = NULL
)
adf_table variavel statistic p_value
1 GDP -5.087838 0.01
2 Deflator -5.197799 0.01
3 Commodity -5.248986 0.01
4 FFD -4.053174 0.01
5 TotReserves -4.535321 0.01
6 NonReserves -4.623392 0.01
Com base na tabela de ADF acima, como os p-valores são inferiores a 1% para todas as séries de resíduos, rejeitamos a hipótese nula de raiz unitária. Portanto, os resíduos do VAR são estacionários. Com isso verificado, podemos prosseguir para as duas estratégias de identificação: a recursiva (Cholesky) e as restrições de sinais.
4.1.2 Identificação recursiva (Cholesky)
# Identificação recursiva (Cholesky) via VARsignR::rfbvar
# Choque de política monetária na taxa de juros (FFD)
# Convertendo os dfs para ts
df1 <- df %>% select(-c(Consumption, Investment, spread))
df1$dates <- as.yearqtr(df1$dates)
mat1 <- as.matrix(select(df1, -dates))
df1_ts <- ts(data = mat1,
start = c(1965, 1),
end = c(2005, 4),
frequency = 4)
# Identificação
model_chol <- rfbvar(Y = df1_ts,
nlags = 4,
draws = 1000,
constant = FALSE,
steps = 20,
shock = 4)
# IRFs
irfs_chol1 <- model_chol$IRFS
vl <- c("GDP", "GDP Deflator", "Comm.Pr.Index", "Fed Funds Rate",
"Total Reserves", "Nonborrowed Reserves")
irfplot(irfdraws = irfs_chol1, type = "median", labels = vl,
save = TRUE, bands = c(0.16, 0.84), grid = TRUE, bw = TRUE)
# Obs: o irfplot apenas desenha o gráfico, mas não retorna o objeto.
# Portanto, é necessário salvar a imagem para plotar.Esses resultados são bastante próximos dos que Uhlig consegue com dados mensais fazendo a decomposição de Cholesky. O choque contracionista eleva fortemente a FFD no impacto e a resposta decai gradualmente. Observa-se um price puzzle claro no GDP Deflator, com aumento persistente nos primeiros trimestres, apesar do aperto monetário. Comm.Pr.Index cai, e Nonborrowed Reserves recuam, enquanto Total Reserves exibem resposta mista (elevação inicial e queda subsequente). O GDP recua no curto prazo, como os modelos econômicos prevêem. Em suma, a identificação recursiva reproduz o price puzzle clássico e gera um impacto negativo na atividade.
4.1.3 Restrições de sinais (Uhlig, 2005)
# SVAR com restrições de sinais — modelo original (1965Q1–2005Q4)
# Ordem em df1_ts: GDP, Deflator, Commodity, FFD, Total Reserves, Nonborrowed Reserves
# Restrições (Uhlig, 2005, adaptado p/ dados trimestrais, janela 1–4):
# 1. PIB (sem restrição)
# 2. Deflator -
# 3. Comm Price -
# 4. Juros (primeira) +
# 5. Total reserves (sem restrição)
# 6. Nonborrowed reserves -
# Choque é no juros -> Primeira a especificar
constr1 <- c(+4, -2, -3, -6)
model_sign1 <- uhlig.reject(
Y = df1_ts,
nlags = 4,
draws = 200,
subdraws = 200,
nkeep = 500,
KMIN = 1,
KMAX = 2,
constrained = constr1,
constant = FALSE,
steps = 20
)
irfs_sign1 <- model_sign1$IRFS
vl1 <- c("GDP", "GDP Deflator", "Comm.Pr.Index", "Fed Funds Rate",
"Total Reserves", "Nonborrowed Reserves")
irfplot(irfdraws = irfs_sign1, type = "median", labels = vl1,
save = FALSE, bands = c(0.16, 0.84), grid = TRUE, bw = TRUE)As restrições eliminam o price puzzle por construção: GDP Deflator e Comm.Pr.Index caem após o choque e FFD sobe no impacto. O resultado mais controverso aparece no GDP: a contração é fraca e, em alguns horizontes, a resposta tende a zero ou mesmo levemente positiva, reproduzindo a evidência surpreendente de Uhlig (2005) de efeitos pouco negativos do aperto sobre o produto. Nonborrowed Reserves caem de forma pronunciada, coerente com contração monetária. Assim, as restrições corrigem o price puzzle, mas levam ao “resultado estranho” para o GDP. ### Modelo alternativo (1983.Q1 a 2005.Q4, com spread, consumo e investimento)
4.1.4 VAR reduzido – 1983.Q1 a 2005.Q4 (com spread, consumo e investimento)
df_var2 <- df %>% select(-c(dates)) %>% drop_na()
var_model <- VAR(df_var2, p = 4, type = "none")
# Teste ADF nos resíduos (uma série por coluna)
residuos <- residuals(var_model)
adf_list <- lapply(as.data.frame(residuos), function(x) tseries::adf.test(x))
adf_table <- data.frame(
variavel = names(adf_list),
statistic = sapply(adf_list, function(r) unname(r$statistic)),
p_value = sapply(adf_list, function(r) r$p.value),
row.names = NULL
)
adf_table variavel statistic p_value
1 GDP -5.427101 0.01
2 Deflator -4.222661 0.01
3 Commodity -5.059293 0.01
4 FFD -6.190668 0.01
5 TotReserves -5.418485 0.01
6 NonReserves -4.814872 0.01
7 Consumption -5.487023 0.01
8 Investment -4.853466 0.01
9 spread -5.566311 0.01
Novamente, a hipótese nula é rejeitada em todos os casos, indicando que os resíduos do VAR são estacionários. Isso nos permite prosseguir para as estratégias de identificação estrutural.
4.1.5 Identificação recursiva (Cholesky)
# Identificação recursiva (Cholesky) via VARsignR::rfbvar
# Choque de política monetária na taxa de juros (FFD)
# Convertendo os dfs para ts
df2 <- df %>% drop_na()
df2$dates <- as.yearqtr(df2$dates)
mat2 <- as.matrix(select(df2, -dates))
df2_ts <- ts(data = mat2,
start = c(1983, 1),
end = c(2005, 4),
frequency = 4)
# Identificação
model_chol2 <- rfbvar(Y = df2_ts,
nlags = 4,
draws = 1000,
constant = FALSE,
steps = 20,
shock = 4)
# IRFs
irfs_chol2 <- model_chol2$IRFS
vl <- c("GDP", "GDP Deflator", "Comm.Pr.Index", "Fed Funds Rate",
"Total Reserves", "Nonborrowed Reserves", "Consumption", "Investment", "Spread")
irfplot(irfdraws = irfs_chol2, type = "median", labels = vl,
save = TRUE, bands = c(0.16, 0.84), grid = TRUE, bw = TRUE)Com a janela pós‑1983 e inclusão de Consumption, Investment e Spread, a resposta da FFD é menos persistente. O GDP Deflator já não exibe price puzzle tão forte; a inflação tende a cair após o choque. Consumption e Investment caem no curto prazo e se normalizam lentamente, e o Spread aumenta (aperto financeiro). O GDP mostra queda pequena e transitória. A ampliação de variáveis e a mudança de amostra parecem mitigar o price puzzle sob Cholesky.
4.1.6 Restrições de sinais (Uhlig, 2005)
# SVAR com restrições de sinais — modelo alternativo (1983Q1–2005Q4)
# Ordem em df2_ts: GDP, Deflator, Commodity, FFD, Total Reserves, Nonborrowed Reserves, Consumption, Investment, Spread
# Restrições (choque monetário, janela 1–4):
# 1. PIB (sem restrição)
# 2. Deflator -
# 3. Comm Price -
# 4. Juros (primeira) +
# 5. Total reserves (sem restrição)
# 6. Nonborrowed reserves -
# 7. Consumption (sem restrição)
# 8. Investment (sem restrição)
# Choque é no juros -> Primeira a especificar
constr2 <- c(+4, -2, -3, -6)
model_sign2 <- uhlig.reject(
Y = df2_ts,
nlags = 4,
draws = 200,
subdraws = 200,
nkeep = 500,
KMIN = 1,
KMAX = 2,
constrained = constr2,
constant = FALSE,
steps = 20
)
irfs_sign2 <- model_sign2$IRFS
vl2 <- c("GDP", "GDP Deflator", "Comm.Pr.Index", "Fed Funds Rate",
"Total Reserves", "Nonborrowed Reserves", "Consumption", "Investment", "Spread")
irfplot(irfdraws = irfs_sign2, type = "median", labels = vl2,
save = FALSE, bands = c(0.16, 0.84), grid = TRUE, bw = TRUE)As restrições novamente garantem queda de GDP Deflator e Comm.Pr.Index e aumento de FFD no impacto. Nonborrowed Reserves caem, e o Spread sobe, ambos consistentes com aperto monetário. Em linha com o caso replicado, o GDP permanece com resposta fraca e, por vezes, próxima de zero, reforçando o achado “agnóstico” de Uhlig de efeitos pouco negativos sobre o produto mesmo quando o price puzzle é resolvido. Consumption e Investment caem no curto prazo, mas a contração é moderada.
5 Conclusão
Este exercício estimou dois modelos VAR trimestrais com 4 defasagens e sem constante para estudar os efeitos de choques monetários: (i) um modelo “original” (1965.Q1–2005.Q4) alinhado a Uhlig (2005), e (ii) um modelo “alternativo” (1983.Q1–2005.Q4) com inclusão de consumo, investimento e spread. Em ambos, verificamos a estacionariedade dos resíduos (ADF) antes da identificação estrutural via (a) Cholesky e (b) restrições de sinais (janela curta 1–2 trimestres), com choque na taxa de juros (FFD).
No modelo original com Cholesky, reproduzimos o price puzzle: o deflator sobe após um aperto monetário. O PIB recua pouco e gradualmente. Com restrições de sinais no modelo original, o price puzzle é eliminado por construção (inflação e commodities caem), mas o PIB mostra resposta fraca/próxima de zero, replicando o achado “surpreendente” de Uhlig (2005). No modelo 1983–2005 com Cholesky, o price puzzle é muito atenuado: a inflação cai, o spread sobe e PIB/consumo/investimento recuam moderadamente. Com restrições de sinais no modelo 1983–2005, o padrão teórico é reforçado (inflação/commodities caem, reservas não‑tomadas emprestadas recuam, spread sobe), enquanto o efeito sobre o PIB permanece pequeno.
Em síntese, as restrições de sinais corrigem o price puzzle observado com Cholesky, mas implicam respostas modestas do produto — resultado robusto às especificações analisadas. A mudança de amostra e a inclusão de variáveis financeiras também mitigam o price puzzle sob Cholesky. Extensões naturais incluem: verificar janelas alternativas de restrição, diferentes ordenações/priors, e explorar especificações com medidas adicionais do canal de crédito.
6 Referências
Uhlig, H. (2005). What are the effects of monetary policy on output? Results from an agnostic identification procedure. Journal of Monetary Economics, 52, 381–419.
7 Apêndice: Script de instalação de pacotes
A instalação do pacote VARsignR requer o pacote minqa, que por sua vez depende do mvnfast. O pacote HI também é necessário para algumas funções auxiliares. Ambos os pacotes não estão disponíveis no CRAN, mas podem ser instalados a partir dos arquivos .tar.gz fornecidos na pasta packages/, que foram baixados diretamente do endereço do GitHub correspondente a cada pacote.
# Script para instalação dos pacotes necessários para o projeto
# Execute este script ANTES de renderizar o documento Quarto
# Configurar repositório CRAN
options(repos = c(CRAN = "https://cran.rstudio.com/"))
# Instalar pacotes do CRAN
install.packages("vars")
install.packages("minqa")
install.packages("mvnfast")
# Instalar pacotes locais (certifique-se de que os arquivos .tar.gz estão na pasta packages/)
install.packages("packages/HI_0.5_fixed3.tar.gz", repos = NULL, type = "source")
install.packages("packages/VARsignR_0.1.2.tar.gz", repos = NULL, type = "source")
# Verificar se os pacotes foram instalados corretamente
library(vars)
library(minqa)
library(mvnfast)
library(HI)
library(VARsignR)
cat("Todos os pacotes foram instalados com sucesso!\n")