Screener de Ações Brasileiras em Python: Como Filtrar Empresas via API
Construir um screener de ações brasileiras em Python deixa de ser uma tarefa de scraping frágil quando existe uma API REST que já entrega os indicadores
fundamentalistas calculados. Este guia mostra como usar o endpoint /screener da bolsai para reproduzir três estratégias clássicas: Graham, Magic Formula
de Joel Greenblatt e screening de dividendos sustentáveis.
O que é um screener de ações e por que construir o seu
Um screener de ações brasileiras é uma ferramenta que filtra o universo da B3 (cerca de 264 papéis líquidos) por critérios objetivos como P/L menor que 15, ROE acima de 20% ou dividend yield maior que 6%. Em vez de analisar empresa por empresa, o investidor descreve o perfil que procura e o screener devolve apenas os tickers que satisfazem todas as regras. Isso transforma horas de planilha em uma chamada HTTP de poucos milissegundos.
A diferença entre rodar um screener próprio e abrir o Status Invest está no controle. Um script Python pode salvar o histórico das execuções, comparar resultados ao longo do tempo, alimentar um backtest, ou disparar alertas no Telegram quando uma ação nova passa nos filtros. Plataformas web não permitem automação confiável desse tipo, e plataformas pagas como Investidor10 cobram pelo acesso à interface, não pelos dados.
Ferramentas existentes vs. screener via API
Quem já fez análise fundamentalista no Brasil conhece as opções: Fundamentus tem um screener funcional, mas a interface é lenta, os filtros são limitados e não existe API oficial. Status Invest melhorou o produto, porém continua sendo HTML. Investidor10 cobra mensalidade pela mesma ideia. Para uso programático, restavam scrapers caseiros (frágeis e proibidos pelos termos de uso) ou APIs alternativas como brapi, que cobra valores expressivos pelo screener avançado.
A bolsai entrega o screener como endpoint REST nativo. Os mesmos indicadores que aparecem no Fundamentus chegam em JSON, prontos para serem combinados com pandas, numpy ou qualquer biblioteca de análise. A comparação detalhada com a brapi mostra cobertura, precisão e preços lado a lado para quem quer avaliar tecnicamente as duas ofertas.
Endpoint /screener da bolsai: parâmetros aceitos
O endpoint GET /api/v1/screener aceita filtros no formato {metrica}_gt (greater than) e {metrica}_lt (less than).
Várias métricas podem ser combinadas em uma única requisição. A resposta vem ordenada conforme os parâmetros sort e order, com
paginação por limit e offset. O snapshot é reconstruído todo dia após o fechamento, garantindo coerência entre as execuções.
A documentação completa dos campos está em /docs.
| Parâmetro | Tipo | Descrição | Exemplo |
|---|---|---|---|
| pl_lt | float | P/L menor que o valor | pl_lt=15 |
| pl_gt | float | P/L maior que o valor (útil para excluir negativos) | pl_gt=0 |
| pvp_lt | float | Preço sobre Valor Patrimonial menor que | pvp_lt=1.5 |
| roe_gt | float | ROE em pontos percentuais (ex: 20 = 20%) | roe_gt=20 |
| roic_gt | float | ROIC em pontos percentuais | roic_gt=15 |
| dividend_yield_gt | float | DY dos últimos 12 meses em percentual | dividend_yield_gt=6 |
| ev_ebitda_lt | float | EV/EBITDA abaixo de um teto | ev_ebitda_lt=8 |
| net_margin_gt | float | Margem líquida mínima em percentual | net_margin_gt=10 |
| net_debt_ebitda_lt | float | Alavancagem máxima (dívida líquida / EBITDA) | net_debt_ebitda_lt=2 |
| market_cap_gt | float | Valor de mercado mínimo em reais (filtra small caps ilíquidas) | market_cap_gt=5e9 |
| cagr_revenue_5y_gt | float | CAGR da receita nos últimos 5 anos em percentual | cagr_revenue_5y_gt=10 |
| sector | string | Restringe a um setor (ex: Bancos, Energia Elétrica) | sector=Bancos |
| sort / order | string | Ordena pelo campo escolhido (asc ou desc) | sort=roe&order=desc |
| limit / offset | int | Paginação (limit padrão 50, máximo 500) | limit=20 |
A lista completa das métricas filtráveis inclui ainda roa, p_sr, p_ebit, p_ebitda, ebit_margin,
gross_margin, ebitda_margin, debt_equity, current_ratio, asset_turnover, cagr_earnings_5y,
lpa e vpa. O endpoint conta como uma única requisição na cota do plano e exige assinatura Pro.
Exemplo 1: screener estilo Graham em Python
Benjamin Graham, no clássico Security Analysis, propôs uma régua simples para identificar ações baratas: P/L abaixo de 15, P/VP abaixo de 1,5 e o produto P/L × P/VP menor que 22,5. A versão "defensiva" também exige liquidez razoável, o que o filtro de market cap mínimo aproxima. O endpoint resolve essa lógica em uma chamada. Mais sobre a metodologia do múltiplo está em P/L (Preço/Lucro): como calcular via API.
import httpx
API_KEY = "sua_chave_aqui"
BASE = "https://api.usebolsai.com/api/v1"
# Screener Graham: barato em lucro e barato em patrimônio
params = {
"pl_gt": 0, # exclui prejuízo
"pl_lt": 15,
"pvp_lt": 1.5,
"market_cap_gt": 3e9, # > R$ 3 bi (liquidez)
"sort": "pl",
"order": "asc",
"limit": 10,
}
r = httpx.get(f"{BASE}/screener", params=params,
headers={"X-API-Key": API_KEY})
data = r.json()["data"]
for row in data:
graham = row["pl"] * row["pvp"]
print(f"{row['ticker']:6} P/L={row['pl']:>5.2f} "
f"P/VP={row['pvp']:>4.2f} P/L*P/VP={graham:>5.2f}")
# Saída (snapshot de 18/04/2026):
# BBAS3 P/L= 4.71 P/VP=0.92 P/L*P/VP= 4.33
# CMIG4 P/L= 5.18 P/VP=1.01 P/L*P/VP= 5.23
# CXSE3 P/L= 6.40 P/VP=1.43 P/L*P/VP= 9.15
# VIVT3 P/L= 8.92 P/VP=1.07 P/L*P/VP= 9.54
# TAEE11 P/L= 9.85 P/VP=1.46 P/L*P/VP=14.38
# ITSA4 P/L=10.31 P/VP=1.18 P/L*P/VP=12.17
# BBSE3 P/L=11.20 P/VP=1.49 P/L*P/VP=16.69
# ENGI11 P/L=12.04 P/VP=1.31 P/L*P/VP=15.77
Sete dos oito tickers passariam também na régua P/L × P/VP < 22,5. O filtro pl_gt=0 é importante porque ações em recuperação ou com prejuízo
pontual aparecem com P/L negativo, que matematicamente "passa" em qualquer teto sem fazer sentido econômico.
Acesse a referência completa do endpoint /screener
A documentação lista todas as 25 métricas filtráveis, exemplos de combinação e o formato exato da resposta.
Exemplo 2: Magic Formula de Joel Greenblatt
A Magic Formula, popularizada por Joel Greenblatt no livro The Little Book That Beats the Market, ranqueia empresas combinando duas dimensões: retorno sobre o capital (proxy: ROE ou ROIC alto) e preço atrativo (proxy: earnings yield alto, equivalente a P/L baixo). A versão pragmática para a B3 filtra ROE acima de 20% e P/L positivo abaixo de 12, depois compõe um ranking somando as duas posições. Detalhes da métrica de rentabilidade estão no artigo ROE: cálculo e uso via API.
import httpx
params = {
"roe_gt": 20,
"pl_gt": 0,
"pl_lt": 12,
"market_cap_gt": 5e9,
"sort": "roe",
"order": "desc",
"limit": 30,
}
r = httpx.get(f"{BASE}/screener", params=params,
headers={"X-API-Key": API_KEY})
rows = r.json()["data"]
# Ranking duplo: melhor ROE + melhor earnings yield (1 / P/L)
by_roe = {x["ticker"]: i for i, x in enumerate(
sorted(rows, key=lambda x: x["roe"], reverse=True))}
by_ey = {x["ticker"]: i for i, x in enumerate(
sorted(rows, key=lambda x: x["pl"]))}
magic = sorted(rows, key=lambda x: by_roe[x["ticker"]] + by_ey[x["ticker"]])
for row in magic[:8]:
print(f"{row['ticker']:6} ROE={row['roe']:>5.1f}% "
f"P/L={row['pl']:>5.2f} EY={100/row['pl']:>5.2f}%")
# Saída (snapshot de 18/04/2026):
# BBAS3 ROE= 19.8% P/L= 4.71 EY=21.23%
# PETR4 ROE= 26.6% P/L= 5.32 EY=18.80%
# ITUB4 ROE= 21.3% P/L= 9.99 EY=10.01%
# BBSE3 ROE= 35.4% P/L=11.20 EY= 8.93%
# CMIG4 ROE= 22.9% P/L= 5.18 EY=19.31%
# CXSE3 ROE= 56.2% P/L= 6.40 EY=15.62%
# SAPR11 ROE= 21.0% P/L= 8.74 EY=11.44%
# TAEE11 ROE= 21.6% P/L= 9.85 EY=10.15%
A lista resultante é dominada por bancos, seguradoras e utilities, padrão consistente com aplicações da Magic Formula em mercados emergentes. Greenblatt recomenda construir uma carteira com 20 a 30 nomes desse ranking e revisar a cada 12 meses. A automação programática elimina o atrito de redigir o screener manualmente a cada rebalanceamento.
Exemplo 3: screener de dividendos sustentáveis
Investidores focados em renda procuram ações que paguem dividendos altos sem comprometer o caixa. Dividend yield isolado engana: uma queda forte do preço
infla o yield artificialmente. O filtro mais robusto combina DY mínimo, ROE positivo (sinal de geração real de lucro) e alavancagem controlada
(net_debt_ebitda baixo, indicando que o pagamento não vem de endividamento). O detalhamento da métrica está em
Dividend Yield via API.
import httpx
params = {
"dividend_yield_gt": 8,
"roe_gt": 12,
"net_debt_ebitda_lt": 2.5,
"market_cap_gt": 3e9,
"sort": "dividend_yield",
"order": "desc",
"limit": 10,
}
r = httpx.get(f"{BASE}/screener", params=params,
headers={"X-API-Key": API_KEY})
for row in r.json()["data"]:
print(f"{row['ticker']:6} DY={row['dividend_yield']:>5.2f}% "
f"ROE={row['roe']:>5.1f}% "
f"NetDebt/EBITDA={row['net_debt_ebitda']:>5.2f}")
# Saída (snapshot de 18/04/2026):
# PETR4 DY=12.30% ROE= 26.6% NetDebt/EBITDA= 1.18
# TAEE11 DY=10.85% ROE= 21.6% NetDebt/EBITDA= 2.31
# BBAS3 DY= 9.74% ROE= 19.8% NetDebt/EBITDA= 0.45
# CMIG4 DY= 9.42% ROE= 22.9% NetDebt/EBITDA= 1.07
# ITSA4 DY= 8.91% ROE= 16.4% NetDebt/EBITDA= 0.62
# VIVT3 DY= 8.55% ROE= 13.1% NetDebt/EBITDA= 0.88
# BBSE3 DY= 8.31% ROE= 35.4% NetDebt/EBITDA= 0.00
A combinação ROE positivo e dívida líquida moderada elimina pagadores "artificiais" como empresas que distribuem proventos vendendo ativos ou captando
dívida. Para acompanhar o histórico de proventos por ticker, o endpoint /dividends/{ticker} entrega a série completa, e o artigo
Automatizar análise fundamentalista mostra como acoplar essa rotina a um pipeline diário.
Exportando resultados para CSV e integrando com planilhas
Boa parte do uso de um screener termina em planilha: comparar com a carteira atual, anotar observações qualitativas, montar relatórios. Pandas resolve a conversão JSON → CSV em três linhas. O arquivo gerado abre direto no Excel, no Google Sheets (via importação) ou em qualquer notebook.
import httpx
import pandas as pd
from datetime import date
params = {
"dividend_yield_gt": 6,
"roe_gt": 15,
"sort": "dividend_yield",
"order": "desc",
"limit": 100,
}
r = httpx.get(f"{BASE}/screener", params=params,
headers={"X-API-Key": API_KEY})
df = pd.DataFrame(r.json()["data"])
cols = ["ticker", "corporate_name", "sector", "close_price",
"market_cap", "pl", "pvp", "roe", "dividend_yield",
"net_debt_ebitda"]
df[cols].to_csv(f"resultado_{date.today()}.csv", index=False)
print(f"{len(df)} linhas exportadas.")
Para integrar com Google Sheets sem upload manual, a função IMPORTDATA aceita uma URL pública. A combinação clássica é hospedar o CSV em um
bucket S3 ou em um repositório GitHub e atualizar o arquivo via GitHub Actions. O dashboard se atualiza sozinho assim que o pipeline termina.
Limitações: cache diário, setores regulados e empresas em recuperação
O screener da bolsai usa um snapshot computado uma vez por dia, após o fechamento do pregão. Isso significa que o preço utilizado é o preço de fechamento
anterior e que rodar o mesmo filtro às 11h ou às 17h retorna o mesmo conjunto. Para análises intraday é preciso compor o resultado do screener com
chamadas em /stocks/{ticker}, que devolve o preço atualizado.
Setores regulados costumam ter indicadores distorcidos quando comparados pelos mesmos parâmetros. Bancos, por exemplo, têm balanço estruturalmente
diferente: a métrica net_debt_ebitda não se aplica, e o EBITDA tradicional perde sentido. Holdings (ITSA4, BRAP4) e seguradoras também
apresentam padrões próprios. O caminho recomendado é filtrar por setor antes de aplicar regras quantitativas, ou usar combinações específicas para cada
grupo (ROE + payout + carteira de crédito para bancos, P/EV/EBITDA para utilities).
Empresas em recuperação judicial frequentemente aparecem com P/L negativo ou P/VP irreal. Um P/L de -3 não significa "barato"; significa prejuízo
acumulado. O filtro pl_gt=0 aplicado nos exemplos anteriores resolve esse caso. Vale também excluir manualmente tickers em situação especial
conhecida antes de tomar decisões com base no resultado bruto.
Perguntas frequentes
Qual a diferença entre screener e ranking de ações?
Um screener filtra: aplica condições binárias (passa ou não passa) e devolve apenas os tickers que cumprem todas. Um ranking ordena: classifica todo o
universo por uma métrica, sem excluir ninguém. O endpoint da bolsai combina ambos por meio dos parâmetros _gt/_lt (filtros) e
sort/order (ordenação).
O screener da bolsai inclui FIIs?
Não. O endpoint /screener cobre apenas ações listadas (cerca de 264 tickers). Para fundos imobiliários existe o endpoint /fiis,
com indicadores próprios do segmento (P/VP, dividend yield mensal, vacância e classificação por segmento).
Posso salvar um screener e rodar diariamente?
Sim. Como cada screener é apenas uma chamada HTTP com parâmetros de query, basta agendar o script via cron, GitHub Actions ou Airflow. Como o snapshot interno é reconstruído uma vez por dia, rodar o mesmo filtro mais de uma vez no mesmo dia produz a mesma resposta — a frequência ideal é após 20h BRT, quando os preços de fechamento já entraram no cálculo.
O screener substitui análise fundamentalista?
Não. O screener é uma ferramenta de pré-seleção: reduz o universo de 264 ações para um conjunto pequeno (tipicamente 5 a 30) que vale a pena estudar a fundo. A análise qualitativa — modelo de negócios, governança, alocação de capital, dinâmica do setor, riscos regulatórios — precisa ser feita separadamente sobre os tickers que sobraram. Um bom resultado quantitativo não compensa uma tese qualitativa frágil.
Leia também
- Automatizar análise fundamentalista de ações brasileiras — pipeline diário com agendamento e alertas
- P/L (Preço/Lucro): como calcular via API da B3 — fórmula, metodologia TTM e usos em screening
- Dividend Yield via API: dados de proventos da B3 — cálculo do DY, histórico e armadilhas
Disclaimer: Este conteúdo é educacional e não constitui recomendação de investimento. Os tickers citados servem
apenas para ilustrar o uso técnico do endpoint /screener com base em snapshot público. Decisões de alocação envolvem risco e devem
considerar perfil pessoal, horizonte e contexto macroeconômico.
por bolsai • 19 de abril de 2026 • 9 min de leitura
Comece agora
O endpoint /screener faz parte do plano Pro da bolsai (R$49/mês), que dá 10.000 requisições mensais e acesso a todos os endpoints históricos.
Construir um screener de ações brasileiras em Python deixou de exigir scraping ou planilhas frágeis: hoje a barreira é apenas escrever a tese de
investimento em código. Mais informações sobre planos e cobertura na página inicial.
Fontes oficiais utilizadas pela bolsai: B3, CVM e Banco Central.