Introdução ao API Trading com Python
Como começar a operar cripto via API com Python: autenticação, dados de mercado em tempo real (REST e WebSocket), colocação de ordens, monitoramento de posições e gestão de risco no código.
Quando os bots nativos das exchanges não são suficientes — quando você quer lógica customizada, múltiplas exchanges simultaneamente, ou integração com machine learning — você constrói seu próprio bot com Python e as APIs das exchanges.
Quando Usar API vs Bots Nativos
| Situação | Use Bot Nativo | Use API + Python |
|---|---|---|
| Estratégia simples (Grid, DCA) | ✓ | Desnecessário |
| Múltiplas exchanges simultâneas | ✗ | ✓ |
| Lógica condicional complexa | ✗ | ✓ |
| Machine learning / IA | ✗ | ✓ |
| Dados customizados (on-chain, sentiment) | ✗ | ✓ |
| Alta frequência (< 1 segundo) | ✗ | ✓ |
| Backtesting rigoroso | ✗ | ✓ |
Conceitos Fundamentais de API
REST API
Protocolo de requisição-resposta. Você faz uma chamada, recebe uma resposta.
- Ideal para: colocar ordens, consultar saldo, obter dados históricos
- Latência: 50ms a 500ms por chamada
- Autenticação: API Key + Secret (assinatura HMAC-SHA256)
WebSocket
Conexão persistente bidirecional. Os dados chegam em tempo real sem você precisar perguntar.
- Ideal para: dados de preço em tempo real, atualizações de ordens, book de ordens
- Latência: < 10ms
- Uso: subscribe a um canal, receba atualizações automaticamente
Setup do Ambiente Python
# Criar ambiente virtual
python -m venv cripto-bot
source cripto-bot/bin/activate # Linux/Mac
# ou
cripto-bot\Scripts\activate # Windows
# Instalar dependências
pip install pybit requests websocket-client python-dotenv pandas numpyGerenciando Credenciais com Segurança
Nunca coloque API keys diretamente no código. Use variáveis de ambiente:
# .env (adicione ao .gitignore!)
BYBIT_API_KEY=sua_chave_aqui
BYBIT_API_SECRET=seu_secret_aqui# config.py
from dotenv import load_dotenv
import os
load_dotenv()
API_KEY = os.getenv("BYBIT_API_KEY")
API_SECRET = os.getenv("BYBIT_API_SECRET")Bybit API com pybit
pybit é a biblioteca oficial Python da Bybit.
pip install pybitAutenticação e Conexão
from pybit.unified_trading import HTTP
session = HTTP(
testnet=False, # True para ambiente de testes
api_key=API_KEY,
api_secret=API_SECRET,
)Dados de Mercado (REST)
# Preço atual
ticker = session.get_tickers(category="spot", symbol="BTCUSDT")
preco_atual = float(ticker['result']['list'][0]['lastPrice'])
print(f"BTC: US${preco_atual:,.2f}")
# Dados OHLCV históricos (klines)
klines = session.get_kline(
category="spot",
symbol="BTCUSDT",
interval="60", # 1h em minutos; opções: 1, 5, 15, 60, 240, D, W, M
limit=200
)
# Converter para DataFrame
import pandas as pd
df = pd.DataFrame(klines['result']['list'],
columns=['timestamp','open','high','low','close','volume','turnover'])
df = df.astype({'open': float, 'high': float, 'low': float,
'close': float, 'volume': float})
df['timestamp'] = pd.to_datetime(df['timestamp'].astype(int), unit='ms')
df = df.sort_values('timestamp').reset_index(drop=True)
print(df.tail())Colocando Ordens
# Ordem Market (executa no preço atual)
ordem = session.place_order(
category="spot",
symbol="BTCUSDT",
side="Buy", # "Buy" ou "Sell"
orderType="Market",
qty="0.001", # Quantidade em BTC
)
print(f"Ordem: {ordem['result']['orderId']}")
# Ordem Limit (executa no preço especificado)
ordem_limit = session.place_order(
category="spot",
symbol="BTCUSDT",
side="Buy",
orderType="Limit",
qty="0.001",
price="78000", # Preço limite
timeInForce="GTC", # Good Till Cancel
)
# Ordem com Stop Loss e Take Profit (Futuros)
ordem_futures = session.place_order(
category="linear", # linear = futuros USDT-margined
symbol="BTCUSDT",
side="Buy",
orderType="Market",
qty="0.001",
stopLoss="76000",
takeProfit="85000",
slTriggerBy="MarkPrice",
tpTriggerBy="MarkPrice",
)Consultando Saldo e Posições
# Saldo da conta
saldo = session.get_wallet_balance(accountType="UNIFIED")
usdt = next(c for c in saldo['result']['list'][0]['coin'] if c['coin'] == 'USDT')
print(f"USDT disponível: {usdt['availableToWithdraw']}")
# Posições abertas em futuros
posicoes = session.get_positions(category="linear", symbol="BTCUSDT")
for p in posicoes['result']['list']:
if float(p['size']) > 0:
print(f"Posição: {p['side']} {p['size']} BTC @ {p['avgPrice']}")
print(f"PnL não realizado: {p['unrealisedPnl']}")OKX API v5
pip install okx-python-sdkfrom okx.Trade import TradeAPI
from okx.MarketData import MarketAPI
from okx.Account import AccountAPI
# Conexão
trade_api = TradeAPI(API_KEY, API_SECRET, PASSPHRASE, flag="0") # "1" = testnet
market_api = MarketAPI(API_KEY, API_SECRET, PASSPHRASE, flag="0")
account_api = AccountAPI(API_KEY, API_SECRET, PASSPHRASE, flag="0")
# Ticker
ticker = market_api.get_ticker(instId="BTC-USDT")
print(ticker['data'][0]['last'])
# Ordem Market
ordem = trade_api.place_order(
instId="BTC-USDT",
tdMode="cash", # "cash"=spot; "isolated"=futuros isolado; "cross"=cruzado
side="buy",
ordType="market",
sz="10", # Em USDT para ordens market spot
)WebSocket: Dados em Tempo Real
import json
from pybit.unified_trading import WebSocket
# Callback chamado a cada atualização de preço
def on_message(message):
data = message['data'][0]
print(f"BTC: {data['lastPrice']} | Vol 24h: {data['volume24h']}")
# Conectar ao canal de ticker
ws = WebSocket(
testnet=False,
channel_type="spot",
)
ws.ticker_stream(symbol="BTCUSDT", callback=on_message)
# O WebSocket roda em background
# Seu script pode continuar fazendo outras coisas
import time
while True:
time.sleep(1)Estrutura de um Bot Simples
import time
import pandas as pd
import numpy as np
from pybit.unified_trading import HTTP
from dotenv import load_dotenv
import os
load_dotenv()
class SimpleBotRSI:
def __init__(self):
self.session = HTTP(api_key=os.getenv("BYBIT_API_KEY"),
api_secret=os.getenv("BYBIT_API_SECRET"))
self.symbol = "BTCUSDT"
self.qty = "0.001"
self.em_posicao = False
def get_dados(self, limit=100):
klines = self.session.get_kline(
category="spot", symbol=self.symbol, interval="60", limit=limit
)
df = pd.DataFrame(klines['result']['list'],
columns=['ts','open','high','low','close','vol','turn'])
df['close'] = df['close'].astype(float)
return df.sort_values('ts').reset_index(drop=True)
def calcular_rsi(self, df, periodo=14):
delta = df['close'].diff()
ganho = delta.clip(lower=0).rolling(periodo).mean()
perda = (-delta.clip(upper=0)).rolling(periodo).mean()
rs = ganho / perda
return 100 - (100 / (1 + rs))
def verificar_sinal(self):
df = self.get_dados()
rsi = self.calcular_rsi(df)
rsi_atual = rsi.iloc[-1]
print(f"RSI atual: {rsi_atual:.2f}")
return rsi_atual
def executar(self):
while True:
try:
rsi = self.verificar_sinal()
if rsi < 30 and not self.em_posicao:
print("Sinal de COMPRA — RSI oversold")
self.session.place_order(
category="spot", symbol=self.symbol,
side="Buy", orderType="Market", qty=self.qty
)
self.em_posicao = True
elif rsi > 65 and self.em_posicao:
print("Sinal de VENDA — RSI overbought")
self.session.place_order(
category="spot", symbol=self.symbol,
side="Sell", orderType="Market", qty=self.qty
)
self.em_posicao = False
time.sleep(3600) # Verifica a cada 1 hora (gráfico 1h)
except Exception as e:
print(f"Erro: {e}")
time.sleep(60) # Aguarda 1 min em caso de erro
bot = SimpleBotRSI()
bot.executar()Rate Limits — Não Exceda
Exceder os limites da API resulta em bloqueio temporário.
| Exchange | Limite REST | Limite WebSocket |
|---|---|---|
| Bybit | 120 req/min (spot) | Sem limite de mensagens |
| OKX | 60 req/2s (por endpoint) | 240 mensagens/hora |
| Binance | 1.200 req/min | Sem limite declarado |
| Kraken | 60 req/min (futuros) | — |
Boas práticas:
- Adicione
time.sleep()entre chamadas em loops - Use WebSocket em vez de REST para dados de preço em tempo real
- Implemente retry com backoff exponencial para erros 429 (rate limit)
Hospedagem do Bot
Para operar 24/7, você precisa de um servidor que nunca desliga.
| Opção | Custo/mês | Indicado para |
|---|---|---|
| DigitalOcean Droplet | US$4-6 | Bots simples |
| AWS EC2 t3.micro | US$8-10 | Bots com mais recursos |
| Google Cloud e2-micro | US$6-8 | Free tier disponível |
| Raspberry Pi (local) | ~US$0 | Testes, sem garantia de uptime |
Setup básico em VPS (Ubuntu):
# Instalar dependências
sudo apt update && sudo apt install python3-pip python3-venv -y
# Rodar bot em background com nohup
nohup python3 bot.py > bot.log 2>&1 &
# Ou usar screen para sessão persistente
screen -S meubot
python3 bot.py
# Ctrl+A, D para desanexar
# Monitorar logs em tempo real
tail -f bot.logPróximos Passos
- Backtesting de Estratégias — validar a estratégia antes de colocar em produção
- Freqtrade: Bot Open-Source — framework completo com tudo pronto
- VectorBT: Backtesting Ultrarrápido
- Gestão de Risco em Bots — circuit breakers no código
Aviso Legal: Conteúdo educativo. Nunca exponha API keys com permissão de saque. Use sempre permissão mínima necessária. Não constitui recomendação de investimento.
Gestão de Risco em Sistemas Automatizados
Como proteger seu capital em trading automatizado: regra dos 1-2%, stop-loss com ATR, circuit breaker diário, alavancagem controlada, overfitting no backtesting e riscos específicos de bots.
Como Fazer Backtesting Rigoroso em Cripto
Guia completo de backtesting para estratégias de trading em cripto: metodologia, métricas essenciais, armadilhas de overfitting, walk-forward analysis e ferramentas (TradingView, VectorBT, Freqtrade, Backtrader).