Aula 15
Construir um Bot de Trading com Python e a CLOB API
Aula 15: Bot de Trading Completo
Esta aula junta autenticação, REST e WebSocket num bot funcional que faz scan de mercados, calcula EV e executa trades automaticamente.
Arquitetura: O bot corre em loop: (1) busca mercados de futebol abertos via REST, (2) filtra por liquidez mínima, (3) calcula EV estimado, (4) se EV > threshold, executa ordem limit no book.
import time
import requests
import json
import os
from dotenv import load_dotenv
load_dotenv()
HOST = "https://clob.polymarket.com"
MIN_LIQUIDITY = 1000 # USDC
MIN_EV = 0.05 # 5% de EV mínimo
MAX_STAKE = 50 # USDC por trade
def get_creds():
"""Carregar credenciais de ambiente"""
return {
"key": os.getenv("POLY_API_KEY"),
"secret": os.getenv("POLY_API_SECRET"),
"passphrase": os.getenv("POLY_API_PASSPHRASE"),
}
def fetch_markets():
"""Buscar mercados de futebol abertos"""
resp = requests.get(
f"{HOST}/markets",
params={"limit": 50, "tag": "soccer", "closed": False},
timeout=10,
)
resp.raise_for_status()
return resp.json()["data"]
def estimate_probability(market):
"""
Placeholder: aqui deves integrar o teu modelo.
Exemplo: modelo Poisson, Elo, ou regressão logística.
"""
return 0.55
def calculate_ev(market_price, estimated_prob):
"""Calcular valor esperado por token"""
return (estimated_prob * (1 - market_price)) - ((1 - estimated_prob) * market_price)
def get_best_ask(market_id):
"""Obter melhor preço de venda do book"""
resp = requests.get(f"{HOST}/book", params={"token_id": market_id}, timeout=10)
resp.raise_for_status()
book = resp.json()
if book["asks"]:
return float(book["asks"][0]["price"])
return None
# Loop principal
while True:
try:
markets = fetch_markets()
print(f"Scan: {len(markets)} mercados encontrados")
for market in markets:
liquidity = float(market.get("liquidity", 0))
if liquidity < MIN_LIQUIDITY:
continue
market_price = get_best_ask(market["condition_id"])
if market_price is None:
continue
estimated_prob = estimate_probability(market)
ev = calculate_ev(market_price, estimated_prob)
print(f"{market['question'][:50]:50s} | Preço: {market_price:.4f} | EV: {ev:.4f}")
if ev > MIN_EV:
print(f"OPORTUNIDADE: {market['question']}")
print(f" Preço: {market_price:.4f}, EV: {ev:.4f}")
print(f" Stake sugerido: {min(MAX_STAKE, 100 * ev):.2f} USDC")
# Aqui integrarias a ordem real:
# client.create_order(token_id=..., price=market_price, size=..., side=Side.BUY)
except Exception as e:
print(f"Erro no ciclo: {e}")
time.sleep(300) # 5 minutos entre scans
Modo de falha
Modo de Falha Crítico
“O bot está a comprar automaticamente sem supervisão.”
Nunca deixes um bot operar sem limites. No código acima, faltam proteções: stop loss global, limite de drawdown diário, whitelist de mercados, e validação humana para trades acima de X USDC. Um bug no teu modelo de probabilidade pode queimar a banca em minutos. Começa com modo simulado (só print) e só depois ativa ordens reais com limites apertados.
Aprofundamento operacional
Um bot nao e uma estrategia; e uma estrategia transformada em codigo. Se a regra humana e vaga, o bot apenas automatiza a confusao. Antes de permitir qualquer ordem real, o bot precisa provar tres coisas: entende o mercado correto, calcula o risco corretamente e sabe parar.
A versao inicial deve operar em dry-run. Ela registra o que teria feito, por qual preco, com qual tamanho, qual spread, qual liquidez e qual motivo. Depois voce compara as decisoes simuladas com o mercado real. So entao faz sentido liberar pequenos tamanhos.
Protecoes obrigatorias
- Whitelist de categorias e mercados permitidos.
- Stake maximo por ordem e por dia.
- Limite de perdas e drawdown.
- Bloqueio se spread ultrapassar o limite.
- Bloqueio se liquidez cair abaixo do minimo.
- Modo dry-run por padrao.
- Logs auditaveis de todas as decisoes.
Exercicio pratico
Antes de escrever qualquer funcao de envio de ordem, escreva a funcao should_trade() retornando tambem uma lista de motivos. Se a lista de motivos for vazia ou generica, o bot ainda nao tem processo suficiente.
Auditoria aplicada
Esta aula deve terminar com uma pequena auditoria escrita. O objetivo nao e produzir uma nota bonita, mas transformar “Construir um Bot de Trading com Python e a CLOB API” em uma decisao verificavel. Use os conceitos centrais da aula (os conceitos principais da aula) para construir um registro que possa ser revisado depois, quando o mercado ja tiver se movido ou o evento ja tiver sido resolvido.
Comece pela pergunta operacional: o que eu consigo observar agora que muda minha decisao? Depois separe evidencia, inferencia e decisao. Evidencia e dado verificavel: preco, spread, profundidade, regra de resolucao, horario, volume, estado do book, endpoint consultado ou custo calculado. Inferencia e a leitura que voce faz a partir desses dados. Decisao e o que voce faz com a leitura: estudar mais, descartar, entrar com ordem limit, esperar liquidez, reduzir stake, usar API apenas para leitura ou classificar como No Bet.
Protocolo de revisao
- Escreva a tese em uma frase curta.
- Liste os tres dados que sustentam a tese.
- Liste o principal dado que poderia invalidar a tese.
- Defina o custo de estar errado: perda financeira, slippage, fee, tempo preso, erro de resolucao ou risco operacional.
- Defina o gatilho de pausa. Se esse gatilho acontecer, a decisao deve ser reavaliada antes de qualquer nova ordem.
Perguntas de controle
- O mercado esta suficientemente liquido para o tamanho que eu quero usar?
- O preco atual ainda paga o risco depois de spread, fees e slippage?
- A regra de resolucao esta clara o suficiente para eu aceitar exposicao?
- Se eu estivesse explicando este trade para outra pessoa, conseguiria separar dado de opiniao?
- Existe um caminho simples de saida se a leitura estiver errada?
Saida esperada
No fim da aula, salve uma nota de cinco linhas: mercado observado, preco observado, risco principal, decisao tomada e motivo para revisar depois. Esse habito cria memoria operacional. Sem memoria, o operador repete erros com mais confianca. Com memoria, cada aula vira uma parte do sistema de pesquisa.