Séries do Banco Central: baixe pelo código, com data e unidade, e confira depois
Como achar a série certa no SGS do Banco Central, baixar pela API com código, data e unidade, e evitar misturar Selic anual com diária ou mensal com acumulado.
A planilha de reajuste do contrato diz "Selic: 0,05". O analista que a montou saiu da empresa. Ninguém sabe se aquilo é a taxa diária, a meta anual dividida por alguma coisa ou um valor digitado de um print. O reajuste de um contrato de R$ 2 milhões depende desse número, e ele não tem origem.
A resposta curta: um número do Banco Central só tem sentido com o código da série, a data e a unidade. O Banco Central publica milhares de séries no SGS (Sistema Gerenciador de Séries Temporais), muitas com nomes parecidos e unidades diferentes. Escolha a série pelo código, baixe pela API oficial e grave o código ao lado de cada valor. Assim qualquer pessoa confere depois.
Por que "a Selic" ou "o dólar" não é um número só
Pense na Selic. Existe a meta definida pelo Copom, expressa em percentual ao ano. Existe a taxa efetiva diária, expressa em percentual ao dia. Existem acumulados mensais e anualizados. Todas são "a Selic", e misturar duas delas na mesma conta gera erro de ordem de grandeza, não de centavos.
Com o câmbio acontece o mesmo: há taxa de compra e de venda, taxa livre diária, PTAX, médias mensais. Com inflação, há variação mensal, acumulado em 12 meses e número-índice. Cada uma é uma série separada, com código próprio, periodicidade (diária, mensal, anual) e unidade.
Algumas séries muito usadas, para você reconhecer o padrão:
- 432: meta Selic definida pelo Copom, em % ao ano.
- 11: taxa Selic diária, em % ao dia.
- 12: taxa DI (CDI) diária, em % ao dia.
- 433: IPCA, variação mensal em %.
- 1: dólar americano, taxa de câmbio livre, venda, diária.
Antes de usar qualquer código, abra a ficha da série no SGS e confira nome, unidade, periodicidade e fonte. A ficha é a documentação. O código é a chave.
Como achar e baixar a série certa
- Procure no SGS pelo assunto (juros, câmbio, preços) ou por palavra do nome.
- Abra a ficha da série e anote código, unidade, periodicidade e data de início.
- Baixe pela API em vez de copiar da tela. O endereço segue o padrão
https://api.bcb.gov.br/dados/serie/bcdata.sgs.CODIGO/dados?formato=json, com os parâmetrosdataInicialedataFinalno formato dd/MM/aaaa. - Peça períodos delimitados. Para séries diárias, a API limita o tamanho do período por consulta. Baixe em janelas e junte.
- Grave código, data, valor e o momento do download em cada linha.
- Decida o tratamento de dias sem valor antes de calcular: fim de semana e feriado não têm cotação.
Script que baixa e grava com o código ao lado
O exemplo usa Node.js 18 ou superior, que já tem fetch. A API devolve uma lista de objetos com data e valor, e o valor vem como texto com ponto decimal.
// baixar-series.mjs
import { writeFile } from 'node:fs/promises';
const SERIES = {
432: 'Selic meta (% a.a.)',
433: 'IPCA (% no mes)'
};
async function baixarSerie(codigo, dataInicial, dataFinal) {
const url = 'https://api.bcb.gov.br/dados/serie/bcdata.sgs.' + codigo +
'/dados?formato=json&dataInicial=' + dataInicial +
'&dataFinal=' + dataFinal;
const resp = await fetch(url, { signal: AbortSignal.timeout(15000) });
if (!resp.ok) {
throw new Error('Serie ' + codigo + ': HTTP ' + resp.status);
}
const dados = await resp.json();
if (!Array.isArray(dados)) {
throw new Error('Serie ' + codigo + ': resposta inesperada');
}
return dados.map((p) => ({
codigo: Number(codigo),
data: p.data, // dd/MM/aaaa
valor: Number(p.valor) // texto com ponto decimal
}));
}
try {
const baixadoEm = new Date().toISOString();
const linhas = ['codigo;descricao;data;valor;baixado_em'];
for (const [codigo, descricao] of Object.entries(SERIES)) {
const pontos = await baixarSerie(codigo, '01/01/2025', '31/12/2025');
if (pontos.length === 0) {
throw new Error('Serie ' + codigo + ' sem dados no periodo');
}
for (const p of pontos) {
linhas.push([p.codigo, descricao, p.data, p.valor, baixadoEm].join(';'));
}
}
await writeFile('series-bcb.csv', linhas.join('\n') + '\n', 'utf8');
console.log('Gravadas ' + (linhas.length - 1) + ' linhas em series-bcb.csv');
} catch (err) {
console.error('Falha ao baixar series:', err.message);
process.exitCode = 1;
}
Três detalhes de produção estão ali de propósito. O AbortSignal.timeout impede que o script fique pendurado se a API não responder, assunto do post sobre timeout antes do infinito. A resposta é validada antes de virar dado. E o erro encerra o processo com código diferente de zero, para que um agendador perceba a falha em vez de gravar um arquivo vazio.
O CSV sai com ponto decimal. Se for abrir no Excel em português, importe indicando o separador decimal, em vez de dar duplo clique, ou os valores podem virar texto ou datas.
Exemplo trabalhado: IPCA acumulado sem somar porcentagens
A série 433 dá a variação mensal do IPCA. Para o acumulado de um período, você não soma as variações: multiplica os fatores. Se três meses tiveram 0,50%, 0,40% e 0,30%, a soma dá 1,20%, mas o acumulado correto é (1,005 × 1,004 × 1,003) − 1 = 1,2047%. Em 12 meses, a diferença entre somar e multiplicar cresce e aparece no reajuste do contrato.
// variações mensais em %, na ordem dos meses
function acumulado(variacoes) {
const fator = variacoes.reduce((acc, v) => acc * (1 + v / 100), 1);
return (fator - 1) * 100;
}
console.log(acumulado([0.50, 0.40, 0.30]).toFixed(4)); // 1.2047
Para valores de contrato, arredonde só no final e guarde os fatores com todas as casas. Se o resultado vira dinheiro no sistema, siga a lógica de dinheiro em centavos para não perder precisão no caminho.
Dias sem cotação
Uma série diária de câmbio não tem valor em sábado, domingo e feriado. Se o contrato pede "a cotação do dia 1º" e o dia 1º foi domingo, alguém precisa decidir: usa o último dia útil anterior, o próximo, ou o que o contrato manda? Escreva a regra e aplique sempre a mesma. Preencher o buraco sem regra é como inventar o dado.
Erros comuns
- Usar a série 11 achando que é a meta. A taxa diária, em % ao dia, aplicada como se fosse anual, gera um reajuste centenas de vezes menor.
- Somar variações mensais. O acumulado fica abaixo do real, e o erro cresce com o número de meses.
- Copiar valor de print ou de notícia. Sem código e data, ninguém consegue conferir depois, nem você.
- Misturar periodicidades. Uma série diária e outra mensal na mesma conta, sem agregar de propósito, dão resultado sem significado.
- Ignorar revisões. Algumas séries são revisadas depois da primeira divulgação. Guardar a data do download mostra qual versão você usou.
- Preencher feriado com zero. Uma cotação zero no meio da série derruba médias e quebra cálculos de variação.
Checklist
- Cada valor na planilha ou no banco tem o código da série ao lado.
- Unidade e periodicidade conferidas na ficha da série no SGS.
- Download feito pela API, com data do download registrada.
- Script com timeout e falha visível quando a API não responde.
- Acumulados calculados por multiplicação de fatores.
- Regra escrita para dias sem cotação.
- Arredondamento só no resultado final.
Este texto trata de como obter e guardar dados públicos e não é análise de investimento nem previsão de juros, câmbio ou inflação. Em contrato com índice de reajuste, a regra que vale é a do contrato. A pergunta para hoje está na sua planilha: o número de juros ou inflação que ela usa tem um código de série ao lado, ou daqui a um mês ninguém vai saber o que ele era?
Referência: https://www3.bcb.gov.br/sgspub/localizarseries/localizarSeries.do?method=prepararTelaLocalizarSeries