FRE Companhias Abertas — leitura¶
Leitura (← CVM) do Formulário de Referência das companhias abertas (fre_cia_aberta_AAAA.zip),
publicado no
portal de dados abertos da CVM.
Veja também: Referência da API · Uso · o IPE, o VLMO, o FCA e o CGVN.
⚠️ O maior dataset do portal — entregue em 4 fatias¶
O FRE tem 36 membros e ~131 mil linhas (o FCA, o segundo maior, tem 10 membros). Foi implementado em 4 PRs temáticos, cada um revisável e releasável sozinho:
| fatia | tema | membros | estado |
|---|---|---|---|
| 1 | índice + estrutura de capital | 8 | ✅ |
| 2 | administração / pessoas (todos os membros com CPF) | 7 | ✅ |
| 3 | diversidade (contagens agregadas) | 11 | ✅ |
| 4 | remuneração + valores mobiliários + transações | 10 | ✅ esta |
Com esta fatia o dataset está completo: 36 de 36 membros.
Os 8 membros da fatia 1 — índice + capital¶
| reader | membro | cols | linhas (2025) | colunas de data |
|---|---|---|---|---|
FreCiaAbertaReader |
índice | 9 | 4.931 | DT_REFER, DT_RECEB |
FreCiaAbertaCapitalSocialReader |
capital_social |
13 | 2.402 | Data_Referencia, Data_Autorizacao_Aprovacao |
FreCiaAbertaCapitalSocialClasseAcaoReader |
capital_social_classe_acao |
8 | 292 | Data_Referencia |
FreCiaAbertaCapitalSocialTituloConversivelReader |
capital_social_titulo_conversivel |
8 | 26 | Data_Referencia |
FreCiaAbertaDistribuicaoCapitalReader |
distribuicao_capital |
15 | 700 | Data_Referencia, Data_Ultima_Assembleia |
FreCiaAbertaDistribuicaoCapitalClasseAcaoReader |
distribuicao_capital_classe_acao |
9 | 170 | Data_Referencia |
FreCiaAbertaResponsavelReader |
responsavel |
7 | 1.413 | Data_Referencia |
FreCiaAbertaMercadoEstrangeiroReader |
mercado_estrangeiro |
17 | 11 | Data_Referencia, Data_Emissao, Data_Inicio_Listagem |
Os 7 membros da fatia 2 — administração / pessoas¶
| reader | membro | cols | linhas (2025) | colunas de data |
|---|---|---|---|---|
FreCiaAbertaAuditorReader |
auditor |
18 | 1.097 | Data_Referencia, Data_Inicio_Contratacao, Data_Fim_Contratacao, Data_Inicio_Prestacao_Servico |
FreCiaAbertaAdministradorMembroConselhoFiscalReader |
administrador_membro_conselho_fiscal |
21 | 8.988 | Data_Referencia, Data_Eleicao, Data_Posse, Data_Inicio_Primeiro_Mandato, Data_Nascimento |
FreCiaAbertaMembroComiteReader |
membro_comite |
21 | 4.538 | as mesmas 5 do anterior |
FreCiaAbertaRelacaoFamiliarReader |
relacao_familiar |
17 | 1.698 | Data_Referencia |
FreCiaAbertaRelacaoSubordinacaoReader |
relacao_subordinacao |
17 | 9.102 | Data_Referencia, Data_Inicio_Exercicio_Social, Data_Fim_Exercicio_Social |
FreCiaAbertaPosicaoAcionariaReader |
posicao_acionaria |
29 | 31.508 | Data_Referencia, Data_Composicao_Capital_Social, Data_Ultima_Alteracao |
FreCiaAbertaPosicaoAcionariaClasseAcaoReader |
posicao_acionaria_classe_acao |
9 | 2.092 | Data_Referencia |
Os 11 membros da fatia 3 — diversidade¶
Todos com uma coluna de data (Data_Referencia, 100% ISO) e uma de CNPJ (CNPJ_Companhia).
| reader | membro | cols | linhas (2025) | agrupa por |
|---|---|---|---|---|
FreCiaAbertaAdministradorPcdReader |
administrador_PCD |
10 | 3.495 | Orgao_Administracao |
FreCiaAbertaAdministradorDeclaracaoGeneroReader |
administrador_declaracao_genero |
12 | 3.470 | Orgao_Administracao |
FreCiaAbertaAdministradorDeclaracaoRacaReader |
administrador_declaracao_raca |
14 | 3.470 | Orgao_Administracao |
FreCiaAbertaEmpregadoPcdReader |
empregado_PCD |
10 | 1.082 | Codigo_Posicao + Posicao |
FreCiaAbertaEmpregadoLocalDeclaracaoGeneroReader |
empregado_local_declaracao_genero |
11 | 3.118 | Local |
FreCiaAbertaEmpregadoLocalDeclaracaoRacaReader |
empregado_local_declaracao_raca |
13 | 3.117 | Local |
FreCiaAbertaEmpregadoLocalFaixaEtariaReader |
empregado_local_faixa_etaria |
9 | 3.117 | Local |
FreCiaAbertaEmpregadoPosicaoDeclaracaoGeneroReader |
empregado_posicao_declaracao_genero |
11 | 1.038 | Posicao |
FreCiaAbertaEmpregadoPosicaoDeclaracaoRacaReader |
empregado_posicao_declaracao_raca |
13 | 1.038 | Posicao |
FreCiaAbertaEmpregadoPosicaoFaixaEtariaReader |
empregado_posicao_faixa_etaria |
9 | 1.040 | Posicao |
FreCiaAbertaEmpregadoPosicaoLocalReader |
empregado_posicao_local |
12 | 1.036 | Posicao × região |
Os 10 membros da fatia 4 — remuneração, valores mobiliários e transações¶
| reader | membro | cols | linhas (2025) | colunas de data |
|---|---|---|---|---|
FreCiaAbertaAcaoEntregueReader |
acao_entregue |
14 | 1.304 | Data_Referencia + as 2 do exercício social |
FreCiaAbertaRemuneracaoAcaoReader |
remuneracao_acao |
14 | 1.565 | idem |
FreCiaAbertaRemuneracaoMaximaMinimaMediaReader |
remuneracao_maxima_minima_media |
14 | 3.307 | idem |
FreCiaAbertaRemuneracaoTotalOrgaoReader |
remuneracao_total_orgao |
27 | 6.320 | idem |
FreCiaAbertaRemuneracaoVariavelReader |
remuneracao_variavel |
18 | 3.851 | idem |
FreCiaAbertaOutroValorMobiliarioReader |
outro_valor_mobiliario |
24 | 2.735 | Data_Referencia, Data_Emissao, Data_Vencimento |
FreCiaAbertaTitularValorMobiliarioReader |
titular_valor_mobiliario |
9 | 163 | Data_Referencia |
FreCiaAbertaTituloExteriorReader |
titulo_exterior |
21 | 122 | Data_Referencia, Data_Emissao, Data_Vencimento |
FreCiaAbertaParticipacaoSociedadeReader |
participacao_sociedade |
21 | 6.511 | Data_Referencia, Data_Valor_Mercado, Data_Valor_Contabil |
FreCiaAbertaTransacaoParteRelacionadaReader |
transacao_parte_relacionada |
22 | 11.238 | Data_Referencia, Data_Transacao |
⚠️ participacao_sociedade é o único membro da fatia com DUAS colunas de CNPJ —
CNPJ_Companhia (quem entrega) e CNPJ (a investida). 792 dos 6.511 valores de CNPJ em 2025
são o placeholder literal 00000000000000, que é o que a CVM publica para subsidiária no
exterior sem CNPJ brasileiro (AMERICANAS LUX, St. Marys Cement Inc.): nenhum malformado,
nenhum branco. Voltam como publicados, e a coluna segue declarada porque o contrato exige ao
menos um válido — a aresta (um arquivo só de placeholders levanta) é pinada por teste.
⚠️ transacao_parte_relacionada.Documento_Parte_Relacionada fica FORA de tuple_cnpj_cols
apesar de chegar 100% vazia em 2025. A irmã Tipo_Pessoa tem domínio PF/PJ na META: a
coluna guarda CPF ou CNPJ conforme a linha, como o Documento_Pessoa_Relacionada da fatia 2.
Declará-la passaria em todo ano vazio e quebraria no primeiro com dado.
⚠️ Coluna vazia é propriedade do ANO, não do schema. Doze colunas de participacao_sociedade e
três de outro_valor_mobiliario chegam 100% vazias em 2025 — entre elas Data_Valor_Mercado e
Data_Valor_Contabil, que a META tipa date e portanto seguem colunas de data (tudo
NaT). A asserção é sobre o dtype, nunca sobre isna().all(): branco vira NA sob str
também.
⚠️ Duracao_Transacao é texto livre, não data, embora 879 das 11.238 linhas pareçam
DD/MM/YYYY — a META a tipa varchar e a maioria dos valores é prosa ("indeterminado").
Particionado por ano — o date_ref seleciona o ano, e todos os readers do FRE baixam o
mesmo arquivo (um path_raw escrito por um serve os outros).
⚠️ O índice não segue a convenção dos próprios satélites¶
| índice | os 35 satélites | |
|---|---|---|
| CNPJ | CNPJ_CIA |
CNPJ_Companhia |
| data de referência | DT_REFER |
Data_Referencia |
| denominação | DENOM_CIA |
Nome_Empresarial |
O FCA faz igual; o CGVN não — o índice dele é
CamelCase. Não há regra entre datasets do DOC, só medição por dataset. A divergência é pinada
por teste nas duas direções, com o CGVN como contra-exemplo explícito.
⚠️ Ao longo dos 36 membros o FRE usa seis nomes de coluna de CNPJ — CNPJ, CNPJ_Auditor,
CNPJ_CIA, CNPJ_Companhia, CNPJ_Emissor, CNPJ_Emissor_Pessoa_Relacionada. Cada contrato
declara o seu; nada é herdado.
⚠️ Coluna de CNPJ é a que só guarda CNPJ — o nome não é o teste¶
Quase todo membro declara só o CNPJ_Companhia, mas três declaram mais, e quatro colunas que
parecem identificador ficam de fora. Cada caso foi decidido contando os valores reais de 2025:
| membro | declara | fica de fora | por quê |
|---|---|---|---|
auditor |
CNPJ_Companhia, CNPJ_Auditor |
CPF_Auditor |
CPF é dado pessoal |
relacao_familiar |
CNPJ_Companhia, CNPJ_Emissor, CNPJ_Emissor_Pessoa_Relacionada |
2 colunas de CPF | idem |
relacao_subordinacao |
CNPJ_Companhia |
Documento_Pessoa_Relacionada |
guarda CNPJ e CPF (8.462 × 34) |
posicao_acionaria |
CNPJ_Companhia |
as 3 CPF_CNPJ_* |
mistas por definição |
participacao_sociedade |
CNPJ_Companhia, CNPJ |
— | o CNPJ da investida, 5.719 válidos + 792 placeholders |
transacao_parte_relacionada |
CNPJ_Companhia |
Documento_Parte_Relacionada |
CPF ou CNPJ (Tipo_Pessoa é PF/PJ), mesmo 100% vazia em 2025 |
Documento_Pessoa_Relacionada é o caso que uma regra pelo nome erra: não diz nem CPF nem CNPJ, e
guarda os dois (tipados pela coluna irmã Tipo_Pessoa_Relacionada, PJ/PF). Uma coluna mista
declarada passaria no ano em que os valores fossem todos CNPJ e quebraria no primeiro CPF.
⚠️ O estilo de máscara não é uniforme nem dentro de um membro: em auditor, CNPJ_Companhia
vem pontuado (00.000.000/0001-91) e CNPJ_Auditor, na mesma linha, vem em dígitos crus
(49928567000111). Os dois são declarados — o validador normaliza a pontuação — e voltam como
publicados.
Tipagem¶
Todas as colunas de data chegam 100% ISO; branco vira NaT. Quatro chegam
inteiramente vazias em 2025 — auditor.Data_Fim_Contratacao (contrato em aberto não tem fim),
posicao_acionaria.Data_Composicao_Capital_Social e as duas de participacao_sociedade
(Data_Valor_Mercado, Data_Valor_Contabil) — e seguem sendo data por contrato: um ano vazio
não rebaixa a coluna para texto.
Todo o restante é texto exato da fonte, incluindo Valor_Capital (monetário), Quantidade_* e
Numero_* (contagens), Percentual_* e — na fatia 4, a mais monetária do dataset — Salario,
Bonus_*, Montante_*, Preco_* e Saldo_*.
Nunca um float binário: um float64 perde a escala publicada de forma irreversível e silenciosa, e
bin/check_dtypes.py barra o atalho. Converta para Decimal a jusante se precisar de aritmética.
⚠️ Dado pessoal (LGPD) — a fatia 2 concentra todo o CPF do FRE¶
Seis dos sete membros desta fatia carregam CPF, e vários carregam nome, profissão e data de nascimento de pessoa física. Tudo volta como publicado, sem mascarar e sem reformatar, mas:
- nenhuma coluna de CPF entra em
tuple_cnpj_cols— CPF não é identificador de empresa; - as fixtures de teste são só cabeçalho, sem uma linha de dado, para que nenhum CPF real entre no repositório.
posicao_acionaria_classe_acao é o único membro da fatia sem dado pessoal — identifica o
acionista só pelo ID_Acionista.
⚠️ posicao_acionaria grafa CPF_CNPJ_Representante_legal com legal minúsculo, ao contrário
das duas colunas irmãs. A grafia é preservada verbatim: "corrigir" faria a coluna não ser
encontrada no arquivo real.
⚠️ Os membros de diversidade (*_declaracao_raca, *_declaracao_genero, *_PCD,
*_faixa_etaria, fatia 3) não são dado pessoal sensível — são contagens agregadas por
companhia (Quantidade_Preto, Quantidade_Feminino). O nome do membro sugere o contrário; medir as
colunas desmentiu. Nenhum deles tem CPF, nome de pessoa, ou qualquer identificador além do CNPJ da
companhia — pinado por teste sobre as colunas, não sobre o nome.
⚠️ Cinco pares de mesma largura na fatia 3 — o risco de copiar o irmão¶
Os membros de diversidade diferem entre si por uma coluna de agrupamento e pelos baldes que carregam. Cinco pares têm exatamente a mesma contagem de colunas e listas diferentes:
| cols | par |
|---|---|
| 9 | empregado_local_faixa_etaria × empregado_posicao_faixa_etaria |
| 10 | administrador_PCD × empregado_PCD |
| 11 | empregado_local_declaracao_genero × empregado_posicao_declaracao_genero |
| 12 | administrador_declaracao_genero × empregado_posicao_local |
| 13 | empregado_local_declaracao_raca × empregado_posicao_declaracao_raca |
Um contract copiado do irmão bate na largura e só falha contra o header pinado — por isso cada
um é gerado do seu próprio header, e os 5 pares são pinados por teste. ⚠️ administrador_PCD e
empregado_PCD têm 10 colunas cada e compartilham 8 — divergem em exatamente 2 cada: o primeiro agrupa por
Orgao_Administracao e tem Nao_Aplicavel; o segundo agrupa por Codigo_Posicao + Posicao e não
tem.
⚠️ Em administrador_PCD as colunas Quantidade_* chegam parcialmente vazias (~1/5 das linhas
em 2025). Vazio não é zero — é declaração ausente, e volta vazio.
⚠️ Mais quatro pares de mesma largura na fatia 4 — e três deles com prefixo idêntico¶
| cols | par | o que compartilham |
|---|---|---|
| 14 | acao_entregue × remuneracao_acao |
as 10 primeiras colunas |
| 14 | acao_entregue × remuneracao_maxima_minima_media |
as 8 primeiras |
| 14 | remuneracao_acao × remuneracao_maxima_minima_media |
as 8 primeiras |
| 21 | titulo_exterior × participacao_sociedade |
quase nada — só a largura |
O trio de 14 colunas é a colisão mais apertada do dataset: compartilha largura, prefixo e todo teste de entrada gerada — só o header pinado discorda. Nove pares no total entre as fatias 3 e 4.
Uso¶
from datetime import date
from pathlib import Path
from filings_cvm.ingestion.cia_aberta import (
FreCiaAbertaCapitalSocialReader,
FreCiaAbertaPosicaoAcionariaReader,
FreCiaAbertaReader,
FreCiaAbertaRemuneracaoTotalOrgaoReader,
)
# O índice dos formulários entregues no ano:
df_indice = FreCiaAbertaReader(date_ref=date(2025, 6, 15)).read()
# O capital social, guardando o .zip cru (serve às outras fatias também):
df_capital = FreCiaAbertaCapitalSocialReader(
date_ref=date(2025, 6, 15),
path_raw=Path("/data/bronze/cvm/fre"),
).read()
# A base acionária — o maior membro da fatia 2 (31.508 linhas em 2025):
df_acionistas = FreCiaAbertaPosicaoAcionariaReader(date_ref=date(2025, 6, 15)).read()
# A remuneração por órgão — o membro mais largo da fatia 4 (27 colunas):
df_remuneracao = FreCiaAbertaRemuneracaoTotalOrgaoReader(date_ref=date(2025, 6, 15)).read()
# Aritmética a jusante — Decimal, nunca float:
from decimal import Decimal
total = sum(Decimal(v) for v in df_capital["Valor_Capital"] if v)
O frame devolvido carrega, além das colunas da fonte, as seis colunas de proveniência.
META¶
A especificação da CVM sai em MetaFreCiaAbertaReader (o 42º Meta reader) — veja
META.
⚠️ A URL é a forma padrão meta_fre_cia_aberta.zip; as outras 3 candidatas dão 404 —
inclusive fre_cia_aberta.zip sem prefixo, que é justamente a forma correta do
FCA.
⚠️ O arquivo traz 50 membros para 36 membros de dados, e a nomenclatura interna é mista: a
maioria tem o prefixo meta_fre_cia_aberta*, mas ao menos um
(fre_cia_aberta_empregado_local_faixa_etaria.txt) não tem. As seções a mais e o prefixo
inconsistente voltam como publicados — o parser rotula cada seção pelo nome do membro que
encontra, sem normalizar.