Pipeline de dados CVM para cálculo de indicadores de análise fundamentalista de companhias abertas brasileiras.
Baixa os demonstrativos contábeis publicados na CVM (BPA, BPP, DRE), ingere no DuckDB, normaliza/deduplica e calcula 15 indicadores por empresa/período — sem dependência de banco de dados externo.
| Ferramenta | Versão mínima |
|---|---|
| Python | 3.12 |
| uv | 0.5+ |
| make | qualquer |
Conexão com a internet é necessária apenas na etapa de download.
git clone <repo-url> cvmdata
cd cvmdata
uv sync # cria .venv e instala todas as dependênciasPara desenvolvimento (linter + testes + cobertura):
uv sync --extra devmake all # executa download → load → normalize → indicatorsOu passo a passo:
make download # baixa ZIPs CVM para data/raw/ (ITR + DFP, 2021–2025)
make load # ingere CSVs em DuckDB (data/db/cvmdata.duckdb)
make normalize # dedup + cast de tipos → tabelas *_clean
make indicators # calcula 15 indicadores → tabela indicatorsBaixa os arquivos ZIP da CVM e extrai os CSVs de BPA, BPP e DRE.
cvmdata download # todos os anos configurados (2021–2025)
cvmdata download --year 2024 # apenas 2024
cvmdata download --year 2024 --force # re-baixa mesmo se ZIP já existir
cvmdata download --verbose # log detalhadoIngere os CSVs extraídos nas tabelas raw do DuckDB (idempotente: DELETE + INSERT).
cvmdata load # todos os anos disponíveis em data/raw/
cvmdata load --year 2024 # apenas 2024
cvmdata load --verboseDeduplica (mantém VERSAO mais recente), filtra ORDEM_EXERC = 'ÚLTIMO' e faz cast de tipos.
Cria tabelas raw_*_clean no DuckDB.
cvmdata normalizeCalcula os 15 indicadores fundamentalistas para todos os pares (cnpj_cia, dt_refer) e persiste em indicators.
cvmdata indicators # todas as empresas
cvmdata indicators --cnpj "00.000.000/0001-91" # apenas BCO BrasilExibe os indicadores calculados em tabela formatada.
cvmdata query --cnpj "00.000.000/0001-91" # todos os períodos de uma empresa
cvmdata query --cnpj "00.000.000/0001-91" --year 2024 # filtrar por ano
cvmdata query # top-10 empresas com mais indicadores| Categoria | Indicadores |
|---|---|
| Rentabilidade | ROE, ROA, Margem Bruta, Margem Operacional, Margem Líquida, Giro do Ativo |
| Liquidez | Liquidez Corrente, Liquidez Seca, Liquidez Imediata, Liquidez Geral |
| Endividamento | Endividamento Geral, Dívida Bruta, Dívida Líquida, Dívida Líquida/PL, Cobertura de Juros |
Fórmulas completas e mapeamento de contas CVM: docs/analise_fundamentalista.md.
Indicadores de valuation (P/L, P/VPA, DY) dependem de preço de ação e estão documentados em docs/valuation_future.md.
cvmdata/
├── src/cvmdata/
│ ├── cli.py # entrypoint Typer (download/load/normalize/indicators/query)
│ ├── config.py # Settings via pydantic-settings (.env)
│ ├── ingestion/
│ │ ├── db.py # DDLs e get_connection()
│ │ ├── downloader.py # download streaming + extração ZIP
│ │ └── loader.py # parse CSV → INSERT DuckDB
│ └── transform/
│ ├── account_map.py # mapeamento CD_CONTA → componente
│ ├── indicators.py # funções puras + orquestrador calculate_all()
│ └── normalize.py # dedup + cast de tipos
├── tests/
│ ├── conftest.py # fixture db (DuckDB in-memory)
│ ├── fixtures/ # CSVs de amostra para testes
│ ├── test_downloader.py
│ ├── test_indicators.py
│ ├── test_loader.py
│ └── test_normalize.py
├── data/
│ ├── raw/{itr,dfp}/{ano}/ # CSVs baixados da CVM
│ └── db/cvmdata.duckdb # banco de dados local
├── docs/
│ ├── analise_fundamentalista.md
│ └── valuation_future.md
├── specs/001-cvm-pipeline/ # spec, plan e tasks do pipeline
├── .env.example # variáveis de ambiente disponíveis
├── Makefile
└── pyproject.toml
Copie .env.example e ajuste conforme necessário:
cp .env.example .env| Variável | Padrão | Descrição |
|---|---|---|
DATA_DIR |
data |
Diretório raiz dos dados |
DB_PATH |
data/db/cvmdata.duckdb |
Caminho do arquivo DuckDB |
YEARS |
2021,2022,2023,2024,2025 |
Anos a baixar/processar |
ITR_URL |
URL CVM ITR | Base URL dos ZIPs de ITR |
DFP_URL |
URL CVM DFP | Base URL dos ZIPs de DFP |
make test # uv run pytest --tb=short
make lint # uv run ruff check src/ tests/
# Cobertura de testes
uv run pytest --cov=src/cvmdata/transform --cov-report=term-missingCobertura atual de transform/: 99% (100/100 testes passando, 2 xfailed esperados).
- Encoding: arquivos CVM usam
latin-1; o loader converte automaticamente. - Idempotência:
downloadpula ZIPs já existentes (use--forcepara re-baixar);loadfaz DELETE+INSERT por(source, year, demo, consolidation). - Deduplicação:
normalizemantém apenas o registro comVERSAOmais alta para cada(CNPJ_CIA, DT_REFER, CD_CONTA, ORDEM_EXERC). - Mapeamento multi-setor: contas de bancos e industriais diferem; casos xfail documentados em
tests/test_indicators.py. Veraccount_map.pypara# TODO: sector_profile.