Boletim Diário do Pregão (BDI)¶
A seção filings_b3.daily_bulletin lê os conjuntos de dados do Boletim Diário do Pregão da B3,
servidos a partir de arquivos.b3.com.br/bdi. Cada conjunto é uma tabela JSON paginada; um reader
transforma um pregão em um pandas.DataFrame tipado, validado por contrato e com proveniência.
O serviço é uma API de POST: a consulta inteira viaja no caminho da URL e o corpo é um objeto
JSON vazio ({}). Um GET na mesma URL devolve 405 Method Not Allowed — com ou sem cookies
e cabeçalhos de navegador, então é o método, não bloqueio de robô. Os readers desta seção já
fazem isso; quem chama não precisa saber.
Duas irregularidades do formato que os readers absorvem:
- Linhas mais largas que o cabeçalho. A
DailyAverageStocksdeclara 4 colunas e envia 5 posições por linha, a quinta sempre nula, enquanto aEconomicIndicatorsbate exato. Como o payload é posicional, o excedente não tem nome: ele é descartado apenas quando está vazio. Um valor de verdade sem coluna correspondente faz o reader falhar alto, porque descartá-lo em silêncio é exatamente como uma coluna da fonte deixa de chegar sem nada ficar vermelho. - Janela de disponibilidade. A resposta declara um
limitDatepor tabela ("D-21"naEconomicIndicators, por exemplo): o serviço só devolve os últimos dias. Um pedido fora da janela não é erro de código.
Veja também: Visão geral da API · Uso · Exemplos
Padrões implementados¶
- Posições em aberto de empréstimo de ativos —
BdiBtbLendingOpenPositionsReader: o retrato de fim de pregão do empréstimo de ativos (banco de títulos, "BTB"; tabelaBTBLendingOpenPosition). Uma linha por instrumento ainda em aberto, com a quantidade emprestada, o preço médio de empréstimo e o saldo financeiro. Contrato de coluna completa (as 10 colunas da fonte, em ordem), verificado contra uma resposta ao vivo e o glossário oficial da B3. - Histórico de taxas de câmbio (Res. BCB nº 120) —
BdiHistoricalExchangeReader: as taxas de câmbio oficiais determinadas pelo Banco Central (tabelaHistoricalExchange), que a B3 usa para precificar contratos futuros e de opções referenciados em moeda. Histórico de cinco anos completos mais o ano corrente, ao contrário dos demais datasets da seção. O reader desfaz uma troca de nomes da API, publicando o ativo emASSTe o instrumento emTCKR_SYMBcomo manda o glossário. - Resumo diário do mercado à vista de ações —
BdiStocksSummaryReader: o resumo por pregão do mercado à vista (tabelaDailyAverageStocks). Uma linha por instrumento com a quantidade de negócios e o volume financeiro negociado do dia.
Cada padrão ganha a sua própria página, com Descrição e Exemplos. Ao migrar um novo dataset
BDI (#5–#42), acrescente uma página nesta pasta e registre-a no nav: do mkdocs.yml no mesmo
commit.
Forma de um leitor¶
Todo reader desta seção tem a mesma forma — construído sobre a base _base_bdi_reader (privada):
Reader(date_ref: datetime.date, path_raw: pathlib.Path | None = None) -> Reader
Reader.read() -> pandas.DataFrame
| Parâmetro | Tipo | Significado |
|---|---|---|
date_ref |
datetime.date |
Pregão a ler. Obrigatório, sem padrão — o endpoint do BDI é endereçado por data, então não existe um "mais recente". Precisa do dia útil anterior? Calcule-o e passe explicitamente. |
path_raw |
pathlib.Path, opcional |
Diretório onde manter cada página JSON bruta baixada (a camada bronze de um datalake). None (padrão) usa um diretório temporário removido ao final. |
read() retorna um DataFrame cujas colunas são as da própria fonte, em UPPER_SNAKE_CASE
(TckrSymb → TCKR_SYMB), tipadas explicitamente — nunca a inferência do pandas.
Colunas de proveniência¶
Todo DataFrame devolvido carrega, ao lado das colunas de origem, seis colunas de
proveniência, para que a camada bronze de um datalake seja autodescritiva e rastreável:
| Coluna | Conteúdo |
|---|---|
url |
URL exata de onde o dado foi baixado. |
updated_at |
Timestamp de coleta (quando esta leitura buscou o dado), UTC, tz-aware. |
source_key |
Identificador do dataset (do contrato) — distingue readers que compartilham a mesma url. |
package_version |
Versão do pacote que produziu a linha (para re-ingestão após correção de bug). |
ingestion_run_id |
UUID gerado uma vez por read(), comum a todas as linhas daquela leitura. |
content_hash |
sha256 dos bytes do artefato baixado — detecta se a fonte mudou desde a última coleta. |
A proveniência é anexada depois da validação de contrato — ela não faz parte do artefato de
origem, então não precisa satisfazer o contrato da fonte. updated_at permanece tz-aware: um
destino SQL que precise de naive normaliza no carregamento do warehouse, nunca aqui.
Artefato bruto — path_raw¶
None(padrão) — cada página é baixada num diretório temporário, lida e descartada na saída. Nada persiste; a leitura devolve apenas oDataFrame.- Um caminho — cada página JSON bruta e intacta é gravada ali e mantida, antes de qualquer parsing. O diretório é criado junto com os pais.
Guardar o artefato bruto é o que torna a camada bronze autoritativa: quando a B3 muda o contrato dos dados e a transformação quebra, os bytes exatos que causaram a falha continuam reproduzíveis em disco, em vez de perdidos num novo download de uma fonte já alterada.
Validação por contrato¶
Cada reader declara um FileContract (privado, em _internal/config/contracts/daily_bulletin/)
que fixa as colunas obrigatórias. Uma fonte que viola o contrato levanta ContractError — uma
coluna obrigatória ausente falha de forma barulhenta, em vez de silenciosa. Colunas monetárias
são decimal.Decimal exato, nunca float binário.