Previsão Macro — Pipeline com Agentes de IA para IPCA, Câmbio, PIB e Selic

Python
Shiny
scikit-learn
skforecast
Nixtla
TimeGPT
Chronos
Foundation Models
statsmodels
Walk-forward
Diebold-Mariano
Mincer-Zarnowitz
BCB
IBGE
Macroeconomia
Política Monetária
GitHub Actions
shinyapps.io
Quarto
Agentes de IA
Claude Code
Pipeline reprodutível em Python que coleta séries macro via APIs (BCB, IBGE, IPEADATA, FRED), gera previsões quinzenais de IPCA, câmbio, PIB e Selic com ensemble de 10 estratégias sobre 6 modelos por variável (clássicos + foundation models), valida estatisticamente contra o Boletim Focus do BCB (Diebold-Mariano + Mincer-Zarnowitz) e publica em dashboard Shiny atualizado por GitHub Actions. A manutenção é feita por agentes Claude Code via Pull Requests.
Published

May 3, 2026

Note📄 Working paper

Esta é a ficha técnica do projeto (metodologia CRISP-DM, arquitetura, agentes de IA na manutenção). Para o working paper completo com Resumo bilíngue, changelog público, Diebold-Mariano contra Focus e PDF para download, veja Previsão Macro — paper.

Visão Geral

Este projeto implementa, seguindo a metodologia CRISP-DM (Cross-Industry Standard Process for Data Mining), um pipeline automatizado para a geração e divulgação de previsões macroeconômicas para o Brasil. Quatro variáveis-chave são previstas em paralelo:

  • IPCA — Índice de Preços ao Consumidor Amplo (IBGE)
  • Câmbio — taxa BRL/USD (BCB/SGS)
  • PIB — Produto Interno Bruto (IBGE/SCN)
  • Selic — Taxa básica de juros (BCB/SGS)

A coleta acontece automaticamente em ciclos quinzenais (dias 1, 8, 15 e 22 de cada mês) via GitHub Actions, alimentando um dashboard Shiny for Python publicado em shinyapps.io. A modelagem combina modelos clássicos (Ridge, Bayesian Ridge, Huber via scikit-learn) com foundation models de séries temporais (Nixtla TimeGPT e Amazon Chronos T5) e, no caso da Selic, com o modelo proprietário Tom-Copom que extrai sentimento das atas via LLM. Sobre os 6 modelos por variável, o módulo ensembles.py aplica 10 estratégias de combinação (3 não-supervisionadas + 7 supervisionadas), avaliadas em janela walk-forward contra o Boletim Focus do BCB com testes formais (Diebold-Mariano com correção HAC e Mincer-Zarnowitz).

TipTese central

A contribuição do projeto é tripla: (1) arquitetura reprodutível em produção, com ensembles.py na raiz importado por produção, paper e curso — zero duplicação de código; (2) validação estatística honesta de 10 estratégias de ensemble em janela walk-forward com filtros estritos anti-vazamento e benchmark formal contra o Focus do BCB; (3) operação contínua sem intervenção humana — Pull Requests são abertos por agentes Claude Code, o autor revisa e mergeia. Um quarto workflow (paper.yml) re-renderiza o paper acadêmico mensalmente. O resultado é um sistema de previsão que opera 24/7, é auditável até a última linha de código e auto-documenta-se na forma de um paper Quarto regenerado mês a mês.


Motivação

Previsões macroeconômicas são insumos críticos para política monetária, alocação de capital e planejamento corporativo. Soluções tradicionais sofrem de três limitações práticas:

  1. Trabalho manual recorrente — coleta, tratamento e re-estimação a cada ciclo consomem horas de analista qualificado;
  2. Concentração em uma única família de modelos — exclusivamente econométrica ou exclusivamente machine learning, raramente ambas;
  3. Distribuição limitada — relatórios em PDF estáticos, sem interatividade ou atualização contínua.

O projeto responde a três perguntas práticas:

  • Como automatizar o ciclo coleta → modelagem → deploy de forma que a publicação seja zero-touch?
  • Que ganho de robustez advém de combinar modelos clássicos (skforecast/scikit-learn) com foundation models (Nixtla TimeGPT)?
  • Como entregar previsões em formato interativo e auditável, com séries históricas, intervalos de confiança e simulação de cenários?

Metodologia — CRISP-DM

O projeto foi estruturado seguindo o processo CRISP-DM, adaptado ao contexto de previsão macroeconômica automatizada com publicação contínua.

Fase Aplicação no Projeto
1. Entendimento do Negócio Definição das 4 variáveis-alvo (IPCA, câmbio, PIB, Selic), horizonte de previsão (12 meses), critério de sucesso (publicação quinzenal estável), público-alvo (analistas, economistas, gestores)
2. Entendimento dos Dados Catálogo de séries em planilha de metadados (Google Sheets), fontes BCB/SGS, BCB/ODATA, IBGE/SIDRA; estrutura de transformações log/diferença codificada como tipo numérico
3. Preparação dos Dados Pipeline modular em 5 scripts (01-bibliotecas05-disponibilizacao); tratamento de séries por frequência (diária, mensal, trimestral, anual); persistência em parquet
4. Modelagem Quatro scripts independentes (06-ipca, 07-cambio, 08-pib, 09-selic); ensemble de Ridge, BayesianRidge, LinearSVR via VotingRegressor + Nixtla TimeGPT como modelo zero-shot; transformações via PowerTransformer
5. Avaliação Métricas out-of-sample por modelo; intervalos de confiança quantílicos; validação visual no painel (histórico vs. previsão)
6. Implantação Pipeline totalmente automatizado em 3 GitHub Actions (base de dados, modelos, dashboard); dashboard Shiny for Python publicado em shinyapps.io; ciclo de atualização quinzenal

Arquitetura do Pipeline

flowchart LR
  subgraph Fontes
    BCB[(BCB/SGS<br>BCB/ODATA)]
    IBGE[(IBGE/SIDRA)]
    META[(Google Sheets<br>metadados)]
  end

  subgraph Coleta_e_Tratamento
    BCB --> COL[03-coleta.py]
    IBGE --> COL
    META --> COL
    COL --> TRA[04-tratamento.py]
    TRA --> DISP[05-disponibilizacao.py]
    DISP --> P1[(dados/df_mensal.parquet)]
    DISP --> P2[(dados/df_diaria.parquet)]
  end

  subgraph Modelagem
    P1 --> M1[06-ipca.py]
    P1 --> M2[07-cambio.py]
    P1 --> M3[08-pib.py]
    P1 --> M4[09-selic.py]
    NIX[(Nixtla TimeGPT)] --> M1
    NIX --> M2
    NIX --> M3
    NIX --> M4
    M1 --> PR1[(previsao/ipca.parquet)]
    M2 --> PR2[(previsao/cambio.parquet)]
    M3 --> PR3[(previsao/pib.parquet)]
    M4 --> PR4[(previsao/selic.parquet)]
  end

  subgraph Deploy
    PR1 --> APP[app.py<br>Shiny for Python]
    PR2 --> APP
    PR3 --> APP
    PR4 --> APP
    APP --> SHINY([shinyapps.io])
  end

  GHA[GitHub Actions<br>cron quinzenal] -.dispara.-> COL
  GHA -.dispara.-> M1
  GHA -.dispara.-> APP


1. Entendimento do Negócio

1.1 Problema

Previsões macroeconômicas servem a três usos centrais: (i) política monetária, (ii) alocação de capital, (iii) planejamento corporativo. O desafio prático é manter um sistema de previsões continuamente atualizado, com qualidade auditável, sem concentrar o trabalho em uma única família de modelos.

1.2 Objetivos

  1. Construir pipeline automatizado de ponta a ponta — coleta, tratamento, modelagem, deploy;
  2. Cobrir as quatro variáveis macro mais demandadas no Brasil — IPCA, câmbio, PIB, Selic;
  3. Combinar modelos clássicos com foundation models de séries temporais para reduzir risco de viés metodológico;
  4. Distribuir resultados em dashboard interativo com atualização quinzenal zero-touch.

1.3 Critérios de sucesso

Critério Meta
Cadência de atualização 4×/mês (dias 1, 8, 15, 22)
Estabilidade do pipeline < 1 falha por mês nos 3 workflows (coleta, modelos, deploy)
Cobertura 4 variáveis × horizonte de 12 meses
Custo operacional Próximo de zero (GitHub Actions + tier gratuito do shinyapps.io)
Reprodutibilidade Pipeline roda do zero apagando cache e parquets

2. Entendimento dos Dados

2.1 Fontes

Fonte Forma de coleta Variáveis típicas
BCB/SGS API do Banco Central (Sistema Gerenciador de Séries Temporais) Selic, câmbio, expectativas Focus
BCB/ODATA API ODATA do Banco Central Câmbio diário, indicadores fiscais
IBGE/SIDRA API do Sistema IBGE de Recuperação Automática IPCA, PIB, atividade

2.2 Catálogo via metadados

A planilha de metadados (Google Sheets) é a fonte única de verdade sobre quais séries entram no pipeline. Cada linha define:

Campo Conteúdo
Identificador Nome canônico da série no projeto
Fonte BCB/SGS, BCB/ODATA, IBGE/SIDRA
Forma de Coleta API
Input de Coleta Código da série na fonte (ex.: 432 para Selic)
Frequência Diária, Mensal, Trimestral, Anual
Transformação Tipo numérico (1 a 6) — nível, diferença, log, log-diferença

A função transformar(x, tipo) no código aplica a transformação correspondente:

switch = {
    "1": lambda x: x,
    "2": lambda x: x.diff(),
    "3": lambda x: x.diff().diff(),
    "4": lambda x: np.log(x),
    "5": lambda x: np.log(x).diff(),
    "6": lambda x: np.log(x).diff().diff(),
}

2.3 Recorte amostral

Início do treino em janeiro de 2004, padronizado entre as 4 variáveis. Horizonte de previsão fixo em 12 meses.


3. Preparação dos Dados

3.1 Pipeline modular em 5 scripts

01-bibliotecas.py        # imports e configurações globais
02-funcoes.py            # coleta_bcb_sgs, coleta_bcb_odata, coleta_ibge_sidra
03-coleta.py             # iteração sobre metadados; bruto por frequência
04-tratamento.py         # alinhamento temporal, agrupamento, sanitização
05-disponibilizacao.py   # persistência em parquet por frequência

3.2 Persistência por frequência

dados/
├── df_diaria.parquet     # séries diárias (câmbio, Selic spot)
├── df_mensal.parquet     # séries mensais (IPCA, expectativas)
├── df_trimestral.parquet # séries trimestrais (PIB)
└── df_anual.parquet      # séries anuais (controle)

3.3 Princípios

  • Catalogação centralizada — a planilha de metadados é editada em um lugar só; o código nunca lista séries hard-coded.
  • Idempotência — re-rodar o pipeline com a mesma planilha produz parquets bit-a-bit iguais.
  • Separação clara entre coleta e tratamento — facilita debug quando uma fonte muda formato.

4. Modelagem

4.1 Quatro scripts independentes

Cada variável tem seu próprio script para permitir paralelização e debug isolado:

Script Variável Frequência
06-ipca.py IPCA Mensal
07-cambio.py Câmbio BRL/USD Mensal (média)
08-pib.py PIB Trimestral
09-selic.py Selic Mensal

4.2 Modelos individuais por variável

Cada 06-09.py mantém 6 modelos por variável combinados em famílias:

Família 1 — Clássicos (refit por vintage via skforecast):

from sklearn.linear_model import Ridge, BayesianRidge, HuberRegressor
from sklearn.preprocessing import PowerTransformer
from skforecast.ForecasterAutoreg import ForecasterAutoreg

Ridge, Bayesian Ridge e Huber treinados com as ~116 séries macro do df_mensal.parquet como features defasadas, transformação PowerTransformer (Yeo-Johnson) para estabilizar variância, lags=12.

Família 2 — Foundation models (zero-shot, sem treino na vintage):

  • Nixtla TimeGPT — API hospedada da Nixtla, paga por requisição; com try/except para tolerar falha de cota sem quebrar o pipeline.
  • Chronos T5-small e T5-base (Amazon, open-source) — tokenizam séries como linguagem; rodam local via chronos-forecasting, peso ~75 MB e ~250 MB respectivamente, cache via HuggingFace.

Família 3 — Tom-Copom (apenas Selic): score de sentimento hawkish/dovish das atas do COPOM, extraído via LLM (Gemini Flash Lite) e calibrado em pontos percentuais da Selic — metodologia completa em Sentimento_COPOM.

4.3 Suite de 10 estratégias de ensemble (ensembles.py)

Sobre os 6 modelos por variável, o módulo ensembles.py na raiz do repositório aplica 10 estratégias agrupadas em 4 famílias:

Família Estratégias
Não-supervisionadas Média simples, Mediana, Trimmed mean (10%)
Ponderadas estáticas \(1/RMSE\), Bates-Granger (1969), Granger-Ramanathan (1984) variant C
Adaptativas Janela rolante 12m, Forgetting factor 0,95
Stacking Pesos por horizonte, Stacking Ridge (k-fold)

ensembles.py é importado pelos três contextos do projeto — produção (06-09.py), paper (paper/14-ensembles.py) e curso (curso/cadernos/03-ensembles.qmd) — garantindo zero duplicação. Uma estratégia nova é desenvolvida uma vez e flui para todos.

4.3 Saídas padronizadas

Cada script produz um parquet em previsao/ com colunas canônicas:

data | valor | tipo (histórico/previsão) | li | ls | modelo
previsao/
├── ipca.parquet
├── cambio.parquet
├── pib.parquet
└── selic.parquet

4.4 Decisões de modelagem

Decisão Valor Justificativa
Horizonte 12 meses Janela típica para política monetária
Início do treino jan/2004 Pós-meta de inflação consolidada
Lags 12 Captura sazonalidade anual
Transformação PowerTransformer (Yeo-Johnson) Estabiliza variância sem assumir positividade
Random seed 1984 Reprodutibilidade exata entre execuções

5. Avaliação

A avaliação tem duas camadas:

5.1 Métricas walk-forward (paper/13-walkforward.py)

Para cada vintage t no tracking.csv (versionado append-only desde 2025-09-02), o pipeline calcula MAE/RMSE/Bias para cada (Variável × Modelo × Horizonte) usando apenas informação disponível em t-1. Filtros estritos anti-vazamento:

  • Horizonte_dias ≥ 7 — exclui pseudo-previsões “para o passado” quando o modelo roda tarde no mês.
  • Vintage_Focus < min(Data da Previsão, Data de Referência) — garante que o Focus capturado nunca viu o realizado.

Saída: paper/results/wf_modelos.parquet (modelos individuais) e paper/results/wf_ensembles.parquet (10 estratégias).

5.2 Testes estatísticos formais (paper/15-avaliacao.py)

Para cada (Variável × Estratégia × Horizonte) com n ≥ 30 pares observados:

  • Diebold-Mariano com correção HAC (Newey-West, lag = h-1) — perda quadrática, \(p_{one}\) unilateral \(H_1\): ensemble melhor que Focus. Implementado via statsmodels.OLS + cov_hac.
  • Mincer-Zarnowitz — OLS Observado = α + β · Previsão, \(F\)-test conjunto \(H_0: \alpha = 0 \wedge \beta = 1\).

Os artefatos (dm_tests.csv, mz_regressions.csv) e as figuras 300 dpi (heatmap DM, scatter MZ, séries de erro) são consumidos diretamente pelo paper Quarto e pela sub-aba “Performance Histórica” do dashboard. Resultados completos em Previsão Macro — paper.

5.3 Validação visual no painel

O dashboard sobrepõe histórico × previsão × IC de forma que o usuário detecta visualmente:

  • Quebras estruturais não absorvidas;
  • Compressão excessiva da amplitude de previsão;
  • Divergência entre modelos no mesmo horizonte.

6. Implantação

6.1 Quatro workflows no GitHub Actions

.github/workflows/
├── base_de_dados.yml   # cron 00:00 UTC dias 1, 8, 15, 22 → roda 03→05
├── modelos.yml         # cron 01:00 UTC dias 1, 8, 15, 22 → roda 06→09
├── dashboard.yml       # push em main → deploy shinyapps via rsconnect
└── paper.yml           # cron mensal (1º dia, 03:00 UTC) → re-render do paper

base_de_dados.yml e modelos.yml compartilham concurrency group (previsao-macro-pipeline-${{ github.ref }}) — modelos depende de dados terem rodado. dashboard.yml está em grupo isolado (previsao-macro-deploy-${{ github.ref }}) para que o deploy rode em paralelo, lição aprendida quando os 3 compartilhavam o mesmo grupo e o deploy era cancelado a cada novo push (sequencialização indevida).

6.2 Dashboard Shiny for Python

Construído com shiny.express, shinyswatch, plotnine, mizani e faicons. Cada uma das 4 variáveis tem sua aba com:

  • KPI da última observação e da próxima previsão;
  • Gráfico histórico × previsão com IC sombreado;
  • Filtros de janela temporal e toggle do IC.

Deploy via rsconnect-python deploy shiny .. URL pública: https://vitorwilher.shinyapps.io/previsao_macro/.

6.3 Secrets necessários

Secret Uso
NIXTLA_API_KEY Chamadas ao TimeGPT
GEMINI_API_KEY Camada opcional de comentário automatizado
ACCOUNT, NAME, TOKEN, SECRET Credenciais shinyapps.io para rsconnect

Estrutura do Projeto

previsao_macro/
│
├── 01-bibliotecas.py           # imports e configurações globais
├── 02-funcoes.py               # funções de coleta por fonte
├── 03-coleta.py                # iteração sobre metadados
├── 04-tratamento.py            # alinhamento e sanitização
├── 05-disponibilizacao.py      # persistência em parquet
│
├── 06-ipca.py                  # modelo IPCA
├── 07-cambio.py                # modelo câmbio
├── 08-pib.py                   # modelo PIB
├── 09-selic.py                 # modelo Selic
│
├── app.py                      # dashboard Shiny for Python
│
├── dados/                      # parquets de séries históricas
├── previsao/                   # parquets de previsões
├── tracking/                   # tracking.csv (ciclos de execução)
├── rsconnect-python/           # metadata do deploy shinyapps
│
├── .github/workflows/          # 3 workflows (base, modelos, dashboard)
│
├── portfolio/                  # template de divulgação
│   ├── previsao-macro.qmd      # ESTE arquivo (CRISP-DM)
│   ├── README.md               # README do GitHub
│   ├── _TEMPLATE.md            # convenção do template
│   └── *.png                   # imagens de capa
│
├── poetry.lock
└── pyproject.toml

Tecnologias

Camada Tecnologia
Linguagem Python 3.13
Gerenciamento Poetry
Coleta requests (BCB/SGS, BCB/ODATA, IBGE/SIDRA, FRED)
Manipulação pandas, numpy, pyarrow
Modelagem clássica skforecast, scikit-learn (Ridge, BayesianRidge, HuberRegressor)
Foundation models nixtla (TimeGPT) + chronos-forecasting (Amazon Chronos T5)
Tom-Copom google-genai (Gemini Flash Lite) — apenas Selic
Ensembles ensembles.py (raiz, compartilhado) — numpy, scipy.optimize (NNLS, SLSQP)
Avaliação estatística statsmodels (OLS + cov_hac Newey-West, f_test para Mincer-Zarnowitz)
Transformações sklearn.preprocessing.PowerTransformer
Visualização plotnine, mizani, matplotlib
Dashboard shiny.express, shinyswatch, faicons
Paper Quarto + LaTeX (xelatex)
Deploy rsconnect-python → shinyapps.io
Orquestração GitHub Actions (cron + workflow_dispatch + 4 workflows)
Persistência Apache Parquet (séries) + CSV (tracking append-only, testes estatísticos)
Manutenção Agentes Claude Code abrem PRs; humano revisa e mergeia

Como Executar Localmente

Pré-requisitos

  • Python 3.12+
  • Poetry 1.8+
  • Chaves de API: Nixtla, Gemini (opcional)
  • Conta shinyapps.io (para deploy)

Instalação

git clone https://github.com/vitorwilher/previsao_macro.git
cd previsao_macro

poetry install --no-root
cp .env.example .env
# edite .env com NIXTLA_API_KEY, GEMINI_API_KEY

Execução manual do pipeline

# 1) Atualiza base de dados
poetry run python -c "exec(open('01-bibliotecas.py').read()); \
exec(open('02-funcoes.py').read()); \
exec(open('03-coleta.py').read()); \
exec(open('04-tratamento.py').read()); \
exec(open('05-disponibilizacao.py').read())"

# 2) Atualiza previsões
poetry run python 06-ipca.py
poetry run python 07-cambio.py
poetry run python 08-pib.py
poetry run python 09-selic.py

# 3) Roda o dashboard localmente
poetry run shiny run app.py

Deploy no shinyapps.io

rsconnect add --account <conta> --name <nome> --token <token> --secret <secret>
rsconnect deploy shiny . --title previsao_macro

Próximos Passos

  1. Walk-forward simulado retrospectivo — refit dos modelos clássicos (Ridge, Bayesian Ridge, Huber) com cortes históricos arbitrários (2024-01, 2024-02, …), expandindo a janela em 5–10×. Sprint própria; saída na versão v2.0 do paper. Vai elevar n típico para ≥ 30 em várias combinações de IPCA e câmbio, permitindo Diebold-Mariano significativo onde hoje só temos MAE preliminar.
  2. Comparação anual de Selic — comparar ensembles anuais de Selic vs Focus anual, removendo o viés do proxy mensal (Focus mensal de Selic é expansão do anual no Olinda).
  3. Polish da sub-aba Tracking no dashboard — após reformulação na Sprint 3.5, ainda há ajustes visuais de eixos, layout e densidade dos cards.
  4. Imersão self-paced — material didático em curso/: 5 cadernos Quarto + 2 decks reveal.js + template-cliente plug-and-play para implantação B2B.
  5. Avaliação de não-tendenciosidade dentro de sub-amostras estáveis — Mincer-Zarnowitz hoje rejeita uniformemente em h=1 na janela curta com choques recentes; sub-amostras pós-COVID-tardio devem permitir conclusões mais finas.
  6. Cobertura de variáveis — adicionar IPCA por núcleo, balança comercial, conta-corrente.

Referências

  • Wirth, R.; Hipp, J. (2000). CRISP-DM: Towards a Standard Process Model for Data Mining.
  • Hyndman, R. J.; Athanasopoulos, G. (2021). Forecasting: Principles and Practice (3rd ed.). OTexts.
  • Bates, J. M.; Granger, C. W. J. (1969). The Combination of Forecasts. JORS 20(4).
  • Granger, C. W. J.; Ramanathan, R. (1984). Improved Methods of Combining Forecasts. JoF 3(2).
  • Stock, J. H.; Watson, M. W. (2004). Combination Forecasts of Output Growth in a Seven-Country Data Set. JoF 23(6).
  • Timmermann, A. (2006). Forecast Combinations. Em Handbook of Economic Forecasting, vol. 1.
  • Wolpert, D. H. (1992). Stacked Generalization. Neural Networks 5(2).
  • Diebold, F. X.; Mariano, R. S. (1995). Comparing Predictive Accuracy. JBES 13(3).
  • Mincer, J. A.; Zarnowitz, V. (1969). The Evaluation of Economic Forecasts. NBER.
  • Newey, W. K.; West, K. D. (1987). A Simple, Positive Semi-Definite, HAC Covariance Matrix. Econometrica 55(3).
  • Garza, A.; Mergenthaler-Canseco, M. (2023). TimeGPT-1. arXiv:2310.03589.
  • Ansari, A. F.; Stella, L.; Turkmen, C.; et al. (2024). Chronos: Learning the Language of Time Series. arXiv:2403.07815.
  • Amat Rodrigo, J.; Escobar Ortiz, J. (2023). skforecast: Time series forecasting with scikit-learn regressors.
  • Banco Central do Brasil. Sistema Gerenciador de Séries Temporais (SGS) e Olinda — API de Expectativas de Mercado (Focus).
  • IBGE. Sistema IBGE de Recuperação Automática (SIDRA).