Guia · Backtest
Retorno total na B3 com o Dados B3: o que a base entrega e o que você ainda constrói
A base entrega o preço do pregão, os proventos e os eventos societários de cada papel, cada um com a sua fonte. O que não vem pronto é a série ajustada nem o retorno total: essa é uma conta sua. Este guia mostra a receita, os pontos em que ela pede uma decisão e a conferência que fecha o cálculo.
O que cada rota entrega
| Rota | O que traz | Ajustado? |
|---|---|---|
/empresas/{T}/precos | Série diária (abertura, máxima, mínima, fechamento, volume), numa chamada; de/ate e formato=csv | Não |
/empresas/{T}/eventos | Desdobramentos, grupamentos, bonificações e cisões: fonte, fator declarado, efeito líquido do dia, o que o preço disse | — |
/empresas/{T}/dividendos | Proventos com data-com e valor por ação, bruto de IR sobre JCP | Na base da época |
/empresas/{T}/multiplos | Múltiplos ponto-no-tempo, com o preço do 1º pregão depois da publicação do balanço | Não |
Todas pedem chave, exceto nos papéis abertos; a grátis serve (200 consultas por dia, sem cartão). A série inteira de um papel é uma consulta.
A receita, em cinco passos
import json, os, urllib.request
def get(rota):
req = urllib.request.Request("https://dadosb3.com" + rota,
headers={"X-API-Key": os.environ["DADOS_B3_API_KEY"]})
return json.load(urllib.request.urlopen(req))
T = "WEGE3"
precos = get(f"/empresas/{T}/precos")["serie"] # 1 chamada: a série inteira
eventos = get(f"/empresas/{T}/eventos")["eventos"]
proventos = get(f"/empresas/{T}/dividendos")["proventos"]
# 1) um fator por dia de evento: o efeito líquido já é o do grupo de eventos do dia
fatores = {}
for e in eventos:
if e["cisao"] or not e["aplicado_no_ajuste"] or e["efeito_liquido_do_dia"] is None:
continue
fatores[e["data_ex"]] = e["efeito_liquido_do_dia"]
def fator_depois(data):
"""produto dos eventos que ainda vão acontecer a partir deste dia (data_ex >= data)"""
f = 1.0
for d, x in fatores.items():
if d >= data:
f *= x
return f
# 2) fechamento ajustado: o preço de ANTES do evento é dividido pelo efeito líquido
datas = [p["data"] for p in precos]
fech = {p["data"]: p["fechamento"] / fator_depois(p["data"]) for p in precos}
# 3) provento: sai no pregão seguinte à data-com, no valor ajustado como o preço
ex = {}
for p in proventos:
if p["tipo_acao"] != "ON" or not p["data_com"]:
continue
seguinte = next((d for d in datas if d > p["data_com"]), None)
if seguinte:
ex[seguinte] = ex.get(seguinte, 0.0) + p["valor"] / fator_depois(p["data_com"])
# 4) retorno total diário e índice acumulado (base 1,0; proventos reinvestidos no fechamento do dia)
indice, anterior = {}, None
acum = 1.0
for d in datas:
if anterior:
acum *= (fech[d] + ex.get(d, 0.0)) / fech[anterior]
indice[d], anterior = acum, d
# 5) conferir: o maior salto diário que SOBROU depois do ajuste
saltos = sorted(((fech[b] / fech[a] - 1, b) for a, b in zip(datas, datas[1:])), key=lambda s: abs(s[0]))
print(saltos[-3:])
Passos 1 e 2: o preço de antes de um evento é dividido pelo efeito líquido dele, e o ajuste é acumulativo. Passo 3: o provento declarado antes de um desdobramento está na quantidade de ações da época, então recebe o mesmo ajuste do preço. Passo 4: o retorno do dia é o fechamento mais o provento que sai nesse dia, sobre o fechamento anterior. Passo 5 é a conferência, explicada mais abaixo.
Dois detalhes que mudam o número
A data do evento é o último dia COM direito. O campo data_ex traz o lastDatePrior da B3: o preço cai no pregão seguinte. Por isso o ajuste divide as linhas com data <= data_ex, como no código.
Eventos do mesmo dia são uma operação só. A B3 registra cada perna como linha separada. No TIMS3, em 02/07/2025, há um grupamento de 0,01× e um desdobramento de 100× aprovados em 02/06/2025: juntos valem 1,00× e o preço não saltou (fechou em 21,96 e 22,60 nos dois pregões em volta). Aplicar uma perna só criaria um salto de cem vezes. Por isso a rota traz efeito_liquido_do_dia, o produto do grupo, e o código acima usa esse campo.
O que fica como decisão sua
- JCP. O valor da base é bruto, antes do imposto retido sobre JCP. Descontar ou não, e quanto, é uma premissa do seu estudo: registre-a.
- Onde reinvestir. A receita reinveste no fechamento do dia em que o papel passa a ser negociado sem o provento. É uma convenção, não a única.
- Cisões. Quando o evento emite um ativo diferente do original, a rota marca
cisao: truee o ajuste por fator não se aplica: o código acima as pula. O que fazer com o ativo recebido é uma decisão sua. - Evento que só nós achamos. Os de
fonte: inferido_capital_e_preconão entram no ajuste automático (aplicado_no_ajuste: false): a quantidade de ações mudou e o preço saltou, mas a B3 não publica o evento. Decida caso a caso.
Conferir antes de confiar
Depois do ajuste, olhe o maior salto diário que sobrou. No WEGE3, o desdobramento de 28/04/2021 aparece como queda de 50,7% no preço bruto e some no ajustado; o maior salto que resta é de -20,6%, em 16/03/2020, uma queda real de mercado. Um salto que sobra sem explicação de mercado merece fonte primária. Exemplo na própria base: o ITUB4 caiu 18,0% em 04/10/2021 (de 29,67 para 24,34) e a base não tem nenhum evento dele em 2021. Uma queda desse tamanho sem evento registrado costuma indicar uma separação ou distribuição que a base não captura: o ajuste automático não a corrige, e o pesquisador precisa decidir como tratá-la.
Eventos com situação diferente de confirmado_pelo_preco também merecem olhar: divergente_do_preco quer dizer que o fator declarado não explica a queda observada, e a ação sai do cálculo naquele período.
O que a base não faz
- Intraday. Os preços são de fim de dia.
- Índices. O IBOV e outros índices não estão na base; baixe a série na B3. A composição histórica dos índices também não.
- Universo histórico. A base tem as companhias ativas hoje; quem saiu da bolsa tem só parte do histórico. O tamanho do viés está em /saiu-da-bolsa. Uma seleção histórica sobre este universo tem viés de sobrevivência.
Fontes: CVM (dados abertos, ODbL) e B3 (COTAHIST). Não afiliado à B3 nem à CVM. Não é recomendação de investimento.
Os números desta página são ao vivo. Versão do dado 2026-11-09-ancora-do-fre · página gerada em 2026-11-10 02:36 UTC. Se isto não bater com o /saude, você está lendo uma cópia em cache.