Kaique Mitsuo Silva Yamamoto
CriptoTrading automatizado

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çãoUse Bot NativoUse 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 numpy

Gerenciando 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 pybit

Autenticaçã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-sdk
from 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.

ExchangeLimite RESTLimite WebSocket
Bybit120 req/min (spot)Sem limite de mensagens
OKX60 req/2s (por endpoint)240 mensagens/hora
Binance1.200 req/minSem limite declarado
Kraken60 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çãoCusto/mêsIndicado para
DigitalOcean DropletUS$4-6Bots simples
AWS EC2 t3.microUS$8-10Bots com mais recursos
Google Cloud e2-microUS$6-8Free tier disponível
Raspberry Pi (local)~US$0Testes, 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.log

Próximos Passos


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.

On this page