Como Integrar a API da B3 com Python
Guia completo para buscar cotações de ações, ETFs e outros ativos da B3 usando Python e a biblioteca requests.
Por Que Python para Análise Financeira?
Python é a linguagem preferida para análise de dados e finanças por ser:
- Simples de aprender - Sintaxe clara e intuitiva
- Poderosa - Bibliotecas como Pandas, NumPy e Matplotlib
- Popular - Grande comunidade e recursos
- Versátil - Desde scripts até aplicações web
Instalação
pip install requests
Exemplo Básico
import requests
token = 'SEU_TOKEN'
ticker = 'PETR4'
url = f'https://brapi.dev/api/quote/{ticker}?token={token}'
response = requests.get(url)
data = response.json()
quote = data['results'][0]
print(f"{quote['symbol']}: R$ {quote['regularMarketPrice']:.2f}")
Classe Cliente Profissional
import requests
from typing import Dict, List, Optional
from dataclasses import dataclass
@dataclass
class Quote:
"""Representa uma cotação de ativo"""
symbol: str
short_name: str
regular_market_price: float
regular_market_change_percent: float
currency: str
@classmethod
def from_dict(cls, data: Dict) -> 'Quote':
return cls(
symbol=data['symbol'],
short_name=data['shortName'],
regular_market_price=data['regularMarketPrice'],
regular_market_change_percent=data['regularMarketChangePercent'],
currency=data['currency']
)
class BrapiClient:
"""Cliente para a API brapi.dev"""
BASE_URL = 'https://brapi.dev/api'
def __init__(self, token: str):
self.token = token
self.session = requests.Session()
self.session.headers.update({
'User-Agent': 'Python BrapiClient/1.0'
})
def get_quote(self, ticker: str) -> Optional[Quote]:
"""Busca cotação de um ativo"""
url = f'{self.BASE_URL}/quote/{ticker}'
params = {'token': self.token}
try:
response = self.session.get(url, params=params, timeout=10)
response.raise_for_status()
data = response.json()
if data.get('results'):
return Quote.from_dict(data['results'][0])
return None
except requests.exceptions.RequestException as e:
print(f'Erro ao buscar {ticker}: {e}')
return None
def get_multiple_quotes(self, tickers: List[str]) -> List[Quote]:
"""Busca cotações de múltiplos ativos"""
tickers_param = ','.join(tickers)
url = f'{self.BASE_URL}/quote/{tickers_param}'
params = {'token': self.token}
try:
response = self.session.get(url, params=params, timeout=10)
response.raise_for_status()
data = response.json()
return [Quote.from_dict(item) for item in data.get('results', [])]
except requests.exceptions.RequestException as e:
print(f'Erro ao buscar cotações: {e}')
return []
def __enter__(self):
return self
def __exit__(self, *args):
self.session.close()
# Uso
with BrapiClient('SEU_TOKEN') as client:
quote = client.get_quote('PETR4')
if quote:
print(f'{quote.symbol}: R$ {quote.regular_market_price:.2f}')
Integração com Pandas
import pandas as pd
def get_quotes_dataframe(tickers: List[str], token: str) -> pd.DataFrame:
"""Retorna cotações como DataFrame"""
with BrapiClient(token) as client:
quotes = client.get_multiple_quotes(tickers)
if not quotes:
return pd.DataFrame()
data = [{
'symbol': q.symbol,
'name': q.short_name,
'price': q.regular_market_price,
'change_percent': q.regular_market_change_percent,
'currency': q.currency
} for q in quotes]
return pd.DataFrame(data)
# Uso
df = get_quotes_dataframe(['PETR4', 'VALE3', 'ITUB4'], 'SEU_TOKEN')
print(df)
# Salvar em Excel
df.to_excel('cotacoes.xlsx', index=False)
# Salvar em CSV
df.to_csv('cotacoes.csv', index=False)
Análise de Dados
# Estatísticas básicas
print(df['price'].describe())
# Filtrar ações com variação positiva
df_positivas = df[df['change_percent'] > 0]
# Ordenar por variação
df_sorted = df.sort_values('change_percent', ascending=False)
# Calcular média de preços
media_preco = df['price'].mean()
Aplicação Flask
from flask import Flask, jsonify
import os
app = Flask(__name__)
BRAPI_TOKEN = os.environ.get('BRAPI_TOKEN')
@app.route('/api/quote/<ticker>')
def get_quote_api(ticker):
"""Endpoint para buscar cotação"""
with BrapiClient(BRAPI_TOKEN) as client:
quote = client.get_quote(ticker)
if not quote:
return jsonify({'error': 'Quote not found'}), 404
return jsonify({
'symbol': quote.symbol,
'name': quote.short_name,
'price': quote.regular_market_price,
'change_percent': quote.regular_market_change_percent
})
if __name__ == '__main__':
app.run(debug=True)
Script de Monitoramento
import time
from datetime import datetime
def monitor_stocks(tickers: List[str], token: str, interval: int = 60):
"""Monitora ações em tempo real"""
print(f"Monitorando {len(tickers)} ativos...")
while True:
with BrapiClient(token) as client:
quotes = client.get_multiple_quotes(tickers)
print(f"\n=== {datetime.now().strftime('%H:%M:%S')} ===")
for quote in quotes:
color = '\033[92m' if quote.regular_market_change_percent > 0 else '\033[91m'
reset = '\033[0m'
print(f"{quote.symbol}: R$ {quote.regular_market_price:.2f} "
f"{color}{quote.regular_market_change_percent:+.2f}%{reset}")
time.sleep(interval)
# Uso
monitor_stocks(['PETR4', 'VALE3', 'ITUB4'], 'SEU_TOKEN', interval=60)
Salvando Histórico em CSV
import csv
from datetime import datetime
def save_quotes_to_csv(tickers: List[str], token: str, filename: str):
"""Salva cotações em arquivo CSV"""
with BrapiClient(token) as client:
quotes = client.get_multiple_quotes(tickers)
if not quotes:
print('Nenhuma cotação obtida')
return
with open(filename, 'a', newline='', encoding='utf-8') as csvfile:
fieldnames = ['timestamp', 'symbol', 'name', 'price', 'change_percent']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
# Escreve cabeçalho se arquivo estiver vazio
if csvfile.tell() == 0:
writer.writeheader()
timestamp = datetime.now().isoformat()
for quote in quotes:
writer.writerow({
'timestamp': timestamp,
'symbol': quote.symbol,
'name': quote.short_name,
'price': quote.regular_market_price,
'change_percent': quote.regular_market_change_percent
})
print(f'Cotações salvas em {filename}')
# Uso - executa diariamente
save_quotes_to_csv(['PETR4', 'VALE3', 'ITUB4'], 'SEU_TOKEN', 'historico.csv')
Boas Práticas
1. Use Variáveis de Ambiente
import os
from dotenv import load_dotenv
load_dotenv() # Carrega .env
token = os.environ.get('BRAPI_TOKEN')
if not token:
raise ValueError('BRAPI_TOKEN não configurado')
Arquivo .env
:
BRAPI_TOKEN=seu_token_aqui
2. Implemente Tratamento de Erros
try:
quote = client.get_quote('PETR4')
except requests.exceptions.Timeout:
print('Timeout na requisição')
except requests.exceptions.ConnectionError:
print('Erro de conexão')
except Exception as e:
print(f'Erro inesperado: {e}')
3. Use Context Managers
with BrapiClient(token) as client:
# As conexões são fechadas automaticamente
quote = client.get_quote('PETR4')
Próximos Passos
Conclusão
Python é uma excelente escolha para trabalhar com dados da B3. Com requests e Pandas, você pode criar análises poderosas, automações e até aplicações web completas.
Comece agora: Copie o código acima e adapte para suas necessidades!