Google Gemini + dados financeiros da B3 em Python (2026)
Pedir ao Google Gemini a análise fundamentalista de uma ação brasileira só de memória é um convite à desatualização e à alucinação. A solução é o function calling: você escreve uma função Python que consulta dados reais da B3 pela API da bolsai, entrega essa função ao Gemini como ferramenta, e o modelo passa a buscar P/L, ROE e dividend yield de verdade antes de raciocinar. Este guia mostra o código completo, com a função da bolsai totalmente executável e a sintaxe atual do SDK google-genai.
Por que ancorar o Gemini em dados reais da B3
Um modelo de linguagem não tem acesso nativo a dados de mercado atualizados. Ao usar function calling do Gemini ligado à API bolsai, o modelo deixa de responder fundamentos brasileiros de memória e passa a chamar uma função Python que retorna P/L, ROE, dividend yield e outros indicadores calculados a partir de dados oficiais da CVM e da B3. O raciocínio do Gemini fica ancorado (grounded) em números verificáveis, não em suposições treinadas em uma data de corte antiga.
A limitação é estrutural. O Gemini, como qualquer LLM, foi treinado até uma data de corte e não tem conexão direta com o pregão da B3. Quando alguém pergunta "qual o P/L da PETR4?", o modelo sem ferramentas responde com o número mais plausível que memorizou, que pode estar meses ou anos defasado, ou simplesmente errado. Para dados financeiros brasileiros, o problema é agravado pela cobertura desigual: fundamentos da B3 aparecem com menos frequência e menos consistência nos corpora de treino do que os de empresas americanas.
Grounding resolve isso na raiz. Em vez de confiar na memória do modelo, você dá a ele uma ferramenta: uma função Python que, quando chamada, consulta a API bolsai e devolve os indicadores atuais. O Gemini decide sozinho quando chamar essa função, com quais argumentos, e usa a resposta estruturada em JSON como base factual. O resultado combina o raciocínio em linguagem natural do modelo com a precisão de dados calculados sobre balanços entregues à CVM. É o mesmo princípio por trás de um agente de IA para análise de ações, aplicado ao ecossistema do Google.
Vale registrar um limite honesto desde já: os dados da bolsai são de fechamento (end-of-day). Cotações e séries macro são atualizadas diariamente às 20:30 (horário de Brasília), depois do fechamento do pregão. Balanços, dividendos e cadastros de FIIs são atualizados semanalmente. Não há dado intradiário nem execução de ordens. O escopo é análise, não corretagem.
Como funciona o function calling do Gemini
Function calling é o mecanismo pelo qual o Gemini pede que o seu código execute uma função. O ciclo tem quatro etapas bem definidas:
- Declaração: você informa ao modelo quais funções existem, o que cada uma faz e quais parâmetros aceita. No SDK
google-genaiisso pode ser automático (a partir da assinatura e docstring da função) ou manual (viatypes.FunctionDeclaration). - Decisão: diante de um prompt, o modelo decide se precisa de uma ferramenta. Se sim, ele não executa nada: apenas devolve o nome da função e os argumentos que quer usar.
- Execução: o seu código (ou o próprio SDK, no modo automático) roda a função com esses argumentos. Aqui é onde a chamada HTTP à API bolsai acontece.
- Síntese: o resultado volta ao modelo, que o incorpora e produz a resposta final em texto para o usuário.
O SDK oferece dois caminhos. No automatic function calling, você passa a própria função Python na lista de ferramentas e o SDK cuida de tudo: gera o schema, executa a função quando o modelo pede e devolve o resultado, num único generate_content. No modo manual, você declara a ferramenta com types.FunctionDeclaration, lê a chamada em response.function_calls, executa por conta própria e devolve o resultado numa segunda rodada. O caminho automático é mais enxuto para começar; o manual dá controle fino sobre validação e tratamento de erro. Este guia mostra os dois.
Pré-requisitos e instalação
Você precisa de duas bibliotecas: o SDK oficial do Gemini e o cliente HTTP que fala com a bolsai. Não existe SDK oficial da bolsai em Python; as requisições são HTTP diretas com requests, autenticadas por uma chave de API.
# SDK oficial do Google Gemini + cliente HTTP para a bolsai
pip install google-genai requests
São necessárias duas chaves. A chave do Gemini sai do Google AI Studio. A chave da bolsai sai do dashboard em usebolsai.com/dashboard após o login com Google. O plano gratuito da bolsai libera 200 requisições por dia, sem cartão, e cada chamada de ferramenta feita pelo Gemini consome uma dessas requisições. Mantenha as duas chaves em variáveis de ambiente, nunca no código versionado.
Crie sua conta gratuita e pegue a chave da API bolsai: 200 requisições/dia, sem cartão de crédito.
Obter chave gratuitaA função-ferramenta: consultar fundamentos pela API bolsai
Este é o coração do projeto e a parte que precisa estar impecável, porque é ela que o Gemini vai executar. A função recebe um ticker, chama o endpoint /fundamentals/{ticker} da bolsai e devolve um dicionário com os indicadores. A docstring no estilo Google é importante: o SDK a usa para descrever a ferramenta ao modelo. Quanto mais clara a docstring, melhor o Gemini decide quando e como chamar a função.
import os
import requests
BASE = "https://api.usebolsai.com/api/v1"
BOLSAI_KEY = os.environ["BOLSAI_API_KEY"]
def get_fundamentals(ticker: str) -> dict:
"""Retorna indicadores fundamentalistas de uma ação da B3.
Consulta dados de fechamento calculados pela bolsai a partir de
balanços oficiais entregues à CVM. Use para responder perguntas
sobre valuation, rentabilidade, endividamento e dividendos de
empresas brasileiras listadas na B3.
Args:
ticker: Código do papel na B3, ex.: PETR4, VALE3, ITUB4.
"""
resp = requests.get(
f"{BASE}/fundamentals/{ticker}",
params={"api_key": BOLSAI_KEY},
timeout=15,
)
resp.raise_for_status()
d = resp.json()
# Devolve apenas os campos relevantes para a análise.
# Reduzir o payload economiza tokens e foca o modelo.
campos = [
"pl", "pvp", "ev_ebitda", "roe", "roic",
"net_margin", "dividend_yield",
"net_debt_ebitda", "market_cap",
"cagr_earnings_5y", "reference_date",
]
return {"ticker": ticker.upper(),
**{c: d.get(c) for c in campos}}
Todos os campos retornados existem no endpoint de fundamentos da bolsai e seguem a nomenclatura em snake_case com abreviações em português (pl, pvp, roe, net_margin, net_debt_ebitda). A lista completa de mais de 27 indicadores está documentada em /docs. Antes de acoplar ao Gemini, vale testar a função isolada para confirmar que a chave e a rede estão em ordem:
from pprint import pprint
pprint(get_fundamentals("PETR4"))
'pl': 8.4, # valores ilustrativos; a resposta real
'pvp': 1.2, # vem do endpoint no momento da chamada
'ev_ebitda': 3.7,
'roe': 19.5,
'roic': 14.8,
'net_margin': 21.3,
'dividend_yield': 11.2,
'net_debt_ebitda': 0.9,
'market_cap': 512000000000,
'cagr_earnings_5y': 8.1,
'reference_date': '2026-07-01'}
Os números acima são ilustrativos, apenas para mostrar o formato da resposta. Os valores reais chegam do endpoint no instante da chamada e refletem o último fechamento processado. Nunca fixe esses números no código nem os cite como verdade: a razão de existir da ferramenta é justamente entregar o dado corrente ao modelo.
Conectando a função ao Gemini (modo automático)
Com a função pronta, ligá-la ao Gemini é direto. No modo automático, você passa a própria função Python na lista de ferramentas dentro de types.GenerateContentConfig. O SDK gera o schema a partir da assinatura e da docstring, executa a função quando o modelo pede e devolve o resultado, tudo em uma única chamada a generate_content.
from google import genai
from google.genai import types
client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])
# Passe a função Python diretamente como ferramenta.
# O SDK gera o schema e executa a função automaticamente.
resposta = client.models.generate_content(
model="gemini-2.5-flash",
contents="O P/L da PETR4 está caro ou barato "
"considerando o ROE e o dividend yield atuais?",
config=types.GenerateContentConfig(
tools=[get_fundamentals],
),
)
print(resposta.text)
O modelo gemini-2.5-flash é uma escolha estável e econômica para tarefas com ferramentas. Os identificadores de modelo do Gemini mudam com frequência, então confirme o nome atual na página de modelos do Gemini antes de subir para produção; trocar de modelo aqui costuma ser só mudar essa string. Nos bastidores, o Gemini reconhece que a pergunta exige dados, chama get_fundamentals("PETR4"), recebe o JSON e escreve a análise ancorada nos números retornados:
- P/L de ~8,4x: abaixo da média histórica do setor de
petróleo e gás, o que sugere valuation descontado.
- ROE de ~19,5%: rentabilidade sobre patrimônio elevada,
reforçando que o P/L baixo não vem de operação fraca.
- Dividend yield de ~11,2%: retorno em proventos alto,
típico de estatais de commodities em ciclo favorável.
A combinação de P/L baixo com ROE alto e DY elevado indica
preço descontado frente à geração de caixa. Observe, porém,
o risco político e a ciclicidade do petróleo antes de
concluir. (Dados de fechamento; não é recomendação.)
Repare que o texto acima é o raciocínio do Gemini sobre os dados que a sua função devolveu, não valores memorizados. Se você rodar amanhã, os números vêm do fechamento mais recente. Esse é o ganho concreto do grounding: a análise acompanha o mercado sem retreino do modelo.
Explore todos os indicadores e endpoints disponíveis na documentação da API.
Ver a documentaçãoModo manual: declaração explícita da ferramenta
O modo automático é ótimo para prototipar, mas em produção muitos preferem controle total sobre a execução: validar o ticker antes de chamar a bolsai, tratar erros de rede com clareza, registrar cada chamada em log. Para isso, declara-se a ferramenta manualmente com types.FunctionDeclaration, lê-se a intenção do modelo em response.function_calls, executa-se por conta própria e devolve-se o resultado numa segunda rodada.
# 1. Declara a ferramenta explicitamente
fundamentals_decl = types.FunctionDeclaration(
name="get_fundamentals",
description=(
"Retorna indicadores fundamentalistas de uma "
"ação da B3 (P/L, ROE, dividend yield e outros) "
"a partir de dados oficiais da CVM."
),
parameters={
"type": "object",
"properties": {
"ticker": {
"type": "string",
"description": "Código na B3, ex.: PETR4",
}
},
"required": ["ticker"],
},
)
ferramenta = types.Tool(function_declarations=[fundamentals_decl])
# 2. Primeira rodada: o modelo decide chamar a função
resp = client.models.generate_content(
model="gemini-2.5-flash",
contents="Qual o ROE atual do ITUB4?",
config=types.GenerateContentConfig(tools=[ferramenta]),
)
# 3. Lê a chamada pedida pelo modelo e executa
chamada = resp.function_calls[0]
print(chamada.name, chamada.args) # get_fundamentals {'ticker': 'ITUB4'}
if chamada.name == "get_fundamentals":
dados = get_fundamentals(**chamada.args)
A chamada pedida pelo modelo fica em resp.function_calls[0], com .name (o nome da função) e .args (o dicionário de argumentos). Você executa a função de verdade e, na segunda rodada, devolve o resultado ao modelo junto com o histórico da conversa para que ele escreva a resposta final. A forma exata de empacotar o retorno como uma function response está na documentação oficial de function calling do Gemini, que é a fonte definitiva de sintaxe e vale consultar sempre que o SDK evoluir. O ponto que este guia garante correto e executável é a função get_fundamentals: é ela, afinal, que traz o dado real da B3.
Segunda ferramenta: screening de ações via API bolsai
Uma única ferramenta já resolve perguntas sobre um ticker. O passo seguinte é dar ao Gemini a capacidade de descobrir ações que atendem a critérios, e não só analisar papéis que o usuário já conhece. O endpoint /screener da bolsai aceita operadores (_gt, _gte, _lt, _lte) sobre qualquer campo fundamentalista, além de sort, order e limit. Envolvê-lo numa função-ferramenta abre a porta para screening conversacional.
def screen_stocks(
dividend_yield_min: float = 0.0,
roe_min: float = 0.0,
pl_max: float = 1000.0,
limit: int = 10,
) -> list:
"""Filtra ações da B3 por critérios fundamentalistas.
Retorna as ações que atendem a todos os filtros, ordenadas
por dividend yield decrescente. Use para descobrir empresas
a partir de critérios de valuation, rentabilidade e proventos.
Args:
dividend_yield_min: Dividend yield mínimo em %, ex.: 6.
roe_min: ROE mínimo em %, ex.: 10.
pl_max: P/L máximo, ex.: 15.
limit: Número máximo de resultados (padrão 10).
"""
params = {
"api_key": BOLSAI_KEY,
"dividend_yield_gte": dividend_yield_min,
"roe_gte": roe_min,
"pl_lte": pl_max,
"sort": "dividend_yield",
"order": "desc",
"limit": limit,
}
resp = requests.get(f"{BASE}/screener",
params=params, timeout=15)
resp.raise_for_status()
return resp.json()
Agora basta registrar as duas funções na mesma lista de ferramentas. O Gemini escolhe qual usar conforme a pergunta: screen_stocks para descobrir candidatos, get_fundamentals para aprofundar em um papel específico. Ele pode até encadear as duas em uma conversa.
resposta = client.models.generate_content(
model="gemini-2.5-flash",
contents="Liste ações da B3 com dividend yield acima "
"de 8%, ROE acima de 12% e P/L abaixo de 10. "
"Depois comente o perfil do grupo.",
config=types.GenerateContentConfig(
tools=[get_fundamentals, screen_stocks],
),
)
print(resposta.text)
O modelo traduz o pedido em linguagem natural nos parâmetros corretos (dividend_yield_gte=8, roe_gte=12, pl_lte=10), chama a ferramenta, recebe a lista e comenta o perfil dos resultados. Todo o critério de filtragem fica registrado na conversa, o que torna o screening reprodutível e auditável, ao contrário de um chute do modelo sobre "boas pagadoras de dividendos". Para um mergulho no endpoint de screening puro em Python, com todos os operadores e campos, vale ver o guia de como conectar assistentes de IA aos dados da B3.
Grounding contra alucinação: boas práticas
Dar ferramentas ao Gemini reduz a alucinação, mas não a elimina sozinho. Quatro práticas aumentam a confiabilidade da análise:
Instrua o modelo a não inventar números
Um system prompt explícito faz diferença. Uma instrução como "Responda perguntas sobre fundamentos de ações brasileiras apenas com dados obtidos pelas ferramentas. Se uma ferramenta não retornar o campo, diga que o dado não está disponível em vez de estimá-lo" fecha a porta para preenchimento por memória. Passe-o em config=types.GenerateContentConfig(system_instruction="...").
Trate erros da API dentro da função
Se o ticker não existe ou a rede falha, raise_for_status() levanta uma exceção. Em produção, capture-a e devolva um dicionário com uma mensagem de erro clara (por exemplo {"erro": "ticker não encontrado"}) em vez de deixar a exceção estourar. O Gemini lida bem com respostas de erro estruturadas: ele avisa o usuário em vez de inventar um número.
Explicite a data do dado
A função retorna reference_date. Peça ao modelo, no system prompt, para sempre mencionar que os dados são de fechamento e citar a data. Isso evita que o usuário interprete a resposta como cotação em tempo real, algo que a bolsai não fornece.
Controle o consumo de requisições
Cada chamada de ferramenta consome uma requisição da cota da bolsai. Uma conversa que analisa dez papéis gasta dez requisições. No plano gratuito (200/dia), isso cobre bastante uso individual; para agentes que rodam em lote, um cache simples com functools.lru_cache sobre get_fundamentals evita repetir chamadas ao mesmo ticker na mesma sessão, e o plano Pro (R$49/mês, 10.000/dia) dá folga para automações. O consumo pode ser conferido a qualquer momento no dashboard.
Gemini, Claude ou ChatGPT para dados da B3?
A abordagem deste guia (uma função Python que chama a bolsai, exposta ao modelo como ferramenta) é portável entre os principais provedores de LLM. O que muda é a sintaxe de declaração da ferramenta e o ecossistema em volta.
| Provedor | Mecanismo de ferramenta | Como acessar a bolsai |
|---|---|---|
| Google Gemini | function calling (google-genai) | função Python que chama a API via requests (este guia) |
| Anthropic Claude | MCP nativo / tool use | servidor bolsai-mcp com 10 ferramentas prontas |
| OpenAI ChatGPT | GPT Actions (OpenAPI) | schema OpenAPI publicado, GPT personalizado |
Para o Gemini, function calling é a via natural e é o que este guia cobre. Para o Claude, existe o servidor bolsai-mcp, que expõe dez ferramentas prontas via Model Context Protocol e dispensa escrever a função de acesso. Para o ChatGPT, a bolsai publica um schema OpenAPI que vira Actions em um GPT personalizado. Os três consomem os mesmos endpoints da mesma API: a fonte de dados é única, muda só a cola entre modelo e dados. Quem prefere linguagem natural sem escrever código encontra padrões prontos no guia de prompts para análise de ações com IA.
Limitações e escopo
Alguns limites merecem estar claros antes de colocar isso no fluxo de trabalho. Os dados da bolsai são de fechamento, atualizados diariamente às 20:30 (horário de Brasília) para preços e macro, e semanalmente para balanços, dividendos e FIIs; não há cotação intradiária. A cobertura é do mercado brasileiro (B3): não inclui BDRs a fundo, opções, mercado de balcão, cripto nem bolsas internacionais. O function calling do Gemini depende de o modelo decidir corretamente quando chamar a ferramenta; prompts ambíguos podem levá-lo a responder sem consultar dado, daí a importância do system prompt restritivo. E o mais importante: a saída é análise informativa, não recomendação de investimento. A bolsai não é corretora e não executa ordens. A metodologia de cálculo dos indicadores, incluindo as contas da CVM usadas para lucro e patrimônio, está descrita em /docs.
Perguntas frequentes
Por que o Gemini precisa de uma API de dados para analisar ações da B3?
Modelos de linguagem como o Gemini não têm acesso nativo a dados de mercado atualizados. Números fundamentalistas de empresas brasileiras respondidos apenas de memória são estáticos, podem estar desatualizados e correm risco de alucinação. Com function calling ligado à API bolsai, o modelo consulta P/L, ROE, dividend yield e demais indicadores calculados a partir de dados oficiais da CVM e da B3, e usa esses valores reais como base do raciocínio em vez de inventá-los.
Qual pacote Python é usado para function calling no Gemini?
O SDK oficial é o google-genai, instalado com pip install google-genai. Ele expõe genai.Client para criar o cliente e client.models.generate_content para gerar respostas. As ferramentas são passadas em config=types.GenerateContentConfig(tools=[...]). Para chamar a API bolsai, a função-ferramenta usa a biblioteca requests. Não existe SDK oficial da bolsai em Python: as requisições são HTTP diretas com uma chave de API.
Os dados da bolsai são em tempo real?
Não. A bolsai fornece dados de fechamento (end-of-day). Cotações e indicadores macro são atualizados diariamente às 20:30 (horário de Brasília), após o fechamento do pregão da B3. Cadastros de empresas, balanços, dividendos e FIIs são atualizados semanalmente. A bolsai não oferece dados intradiários nem execução de ordens: é uma fonte de dados analíticos, não uma corretora.
Preciso pagar para usar a API bolsai com o Gemini?
O plano gratuito da bolsai inclui 200 requisições por dia sem cartão de crédito, criado com login Google no dashboard em usebolsai.com. Cada chamada de ferramenta feita pelo Gemini consome uma requisição. O plano Pro (R$49/mês) amplia o limite para 10.000 requisições diárias e libera histórico completo. O custo dos tokens do Gemini é cobrado à parte pelo Google, conforme a tabela de preços do modelo escolhido.
Leia também
MCP Server para B3: conecte Claude aos dados da bolsa brasileira
TutorialAgente de IA para análise de ações com Claude e MCP
GuiaPrompts para análise de ações com ChatGPT e Claude
O conteúdo deste artigo tem caráter educacional e técnico. Os dados citados são ilustrativos e refletem apenas o formato das respostas da API; valores reais chegam do endpoint no momento da chamada e podem mudar. Nada aqui constitui recomendação de compra ou venda de ativos financeiros. Nomes de produtos e marcas pertencem aos respectivos titulares; Gemini e Google AI Studio são marcas da Google LLC. Por bolsai, 2 de julho de 2026.