Como criar um bot de trading para a Polymarket
A maioria dos tutoriais de bots para a Polymarket usa SDKs que não existem mais. Este é o caminho atual de ponta a ponta — o que instalar em 2026, como a autenticação realmente funciona, onde estão as lacunas de dados e os modos de falha que matam bots na primeira semana.
A maioria dos tutoriais de bots para a Polymarket está desatualizada
A Polymarket migrou para SDKs unificados — polymarket-client para Python e @polymarket/client para TypeScript. Eles substituem py-clob-client, @polymarket/clob-client-v2, @polymarket/builder-relayer-client e @polymarket/builder-signing-sdk. Se um guia manda você rodar pip install py-clob-client, ou se o seu assistente de IA gera esse import, ele está trabalhando com material desatualizado. Tudo abaixo usa os pacotes atuais.
Um bot para a Polymarket tem seis partes: descobrir mercados, ler preços, decidir, enviar ordens, gerenciar posições e continuar vivo. As duas primeiras são fáceis, a quarta é chata e a sexta é onde a maioria dos bots realmente morre. Este guia percorre o caminho todo com código verificado e é honesto sobre as partes que são de fato difíceis.
Passo 0: decida o que seu bot vai operar
Vale fazer isso antes de escrever uma linha, porque determina tudo o que vem depois. Os mercados da Polymarket se dividem em duas famílias que não têm quase nada em comum:
| Mercados de eventos | Mercados cripto Up/Down | |
|---|---|---|
| Exemplos | Eleições, esportes, premiações | btc-updown-5m, eth-updown-15m |
| Duração | Semanas a meses | 5 minutos a 24 horas |
| O que move o preço | Notícias, informação, sentimento | Microestrutura e fluxo de ordens |
| A vantagem vem de | Estar mais bem informado | Ser mais rápido ou precificar melhor |
| Operações por dia | Algumas | Centenas |
| Sensibilidade à latência | Baixa | Alta |
Se você está automatizando, quase certamente se interessa pela segunda família — alta frequência, contínua e mecânica o bastante para ser codificada. Ela é tratada em profundidade em Mercados Up/Down explicados.
Passo 1: instale o SDK atual
Os dois SDKs oferecem uma única interface de cliente para todas as APIs da Polymarket, modelos tipados, paginação consistente e assinatura embutida — um bom volume de trabalho chato que você não quer reimplementar.
pip install polymarket-client
# or: uv add polymarket-client / poetry add polymarket-clientHá quatro clientes Python, e escolher o certo importa mais do que parece:
| Cliente | Dados públicos | Trading | Tempo real |
|---|---|---|---|
AsyncPublicClient | Sim | Não | Sim |
AsyncSecureClient | Sim | Sim | Sim |
PublicClient | Sim | Não | Não |
SecureClient | Sim | Sim | Não |
subscribe(). Bots precisam das variantes assíncronas; as síncronas são para scripts e notebooks.Comece pelo cliente público
Você pode construir e testar a descoberta, a leitura de preços, a geração de sinais e todo o seu pipeline de dados com o AsyncPublicClient — sem chaves, sem carteira, sem risco. Só troque para o AsyncSecureClient quando estiver pronto para enviar uma ordem. A maioria dos bugs aparece bem antes disso.
Passo 2: encontre mercados
A descoberta pública de mercados não exige credenciais. O paginador do SDK é consistente em todos os métodos de listagem, então este padrão vale para todos.
import asyncio
from polymarket import AsyncPublicClient
async def main() -> None:
async with AsyncPublicClient() as client:
pages = client.list_markets(closed=False, page_size=50)
# Iterate items directly when page boundaries do not matter.
async for market in pages.iter_items():
if "updown" in (market.slug or ""):
print(market.slug, market.condition_id)
asyncio.run(main())Duas coisas para guardar aqui. Primeiro, page.next_cursor é um cursor opaco — guarde-o literalmente se quiser retomar uma varredura depois, e não tente fazer parsing nem montar um. Segundo, /markets tem o limite de requisições mais apertado da plataforma inteira, 300 req / 10s, então guarde os metadados dos mercados em cache em vez de listá-los de novo em um loop quente. Os números completos estão na referência de limites de requisições.
Passo 3: autentique-se
Para operar é preciso uma carteira. O SDK Python constrói o signer a partir de uma chave privada local:
import os
from polymarket import AsyncSecureClient
client = await AsyncSecureClient.create(
private_key=os.environ["POLYMARKET_PRIVATE_KEY"],
wallet=os.environ["POLYMARKET_WALLET_ADDRESS"],
)Por baixo, a Polymarket usa duas camadas de autenticação: L1 é uma assinatura de carteira EIP-712 que prova que você controla o endereço e permite criar ou derivar credenciais de API; L2 assina cada requisição privada com essas credenciais usando HMAC-SHA256. O SDK cuida das duas, e esse é o principal motivo para usá-lo.
As duas falhas de autenticação que você vai encontrar
Credenciais incompletas — a L2 precisa da chave, do secret e da passphrase. Duas das três produzem uma requisição bem formada com uma assinatura impossível de verificar. Desvio de relógio — a assinatura inclui um timestamp, então um contêiner com o relógio alguns segundos errado é rejeitado. As duas aparecem como o mesmo e pouco útil Unauthorized/Invalid api key. A explicação completa está na referência de erros.
Cuidado com a chave
Essa chave privada pode movimentar fundos. Guarde-a em variáveis de ambiente ou em um gerenciador de segredos — nunca no código-fonte, nunca em uma imagem de contêiner, nunca no repositório que você está prestes a fazer push. Use uma carteira dedicada, abastecida só com o que o bot tem permissão para perder, para que um bug fique limitado pelo saldo e não pelo seu julgamento às 3 da manhã.
Passo 4: obtenha preços em tempo real
O erro de arquitetura mais comum em um primeiro bot é fazer polling de /book com um timer. Isso queima seu orçamento de limite de requisições, adiciona latência e escala mal. Em vez disso, assine — o SDK junta vários feeds em um único stream de eventos.
from polymarket.streams import MarketSpec
async with await client.subscribe([MarketSpec(token_ids=[token_id])]) as stream:
async for event in stream:
# MarketBookEvent | MarketPriceChangeEvent | MarketLastTradePriceEvent
# | MarketTickSizeChangeEvent | MarketBestBidAskEvent
# | NewMarketEvent | MarketResolvedEvent
handle(event)Se você se conectar ao WebSocket cru em vez de usar o SDK, precisa enviar um PING a cada 10 segundos, ou a conexão cai, e precisa de custom_feature_enabled: true para receber os eventos best_bid_ask, new_market e market_resolved. Isso e os padrões de reconexão estão no guia de WebSocket. À parte, os preços de referência foram para o PolyBolt em 15 de setembro de 2026 — se o seu bot faz streaming de spot, veja o guia de migração.
Passo 5: envie uma ordem
Uma ordem a mercado é a coisa mais simples que funciona, e amount é expresso no valor em pUSD que você está disposto a gastar, e não em cotas:
market = await client.get_market(slug="<market-slug>")
token_id = market.outcomes.yes.token_id
assert token_id is not None
response = await client.place_market_order(
token_id=token_id,
side="BUY",
amount="10", # spend up to 10 pUSD
)
if not response.ok:
raise RuntimeError(response.message)
# Settlement is on-chain and asynchronous — this waits for it.
hashes = await client.wait_for_order_fill_settlement(response)Para ordens limitadas no livro, duas regras vão morder você antes de qualquer outra coisa. Os preços precisam estar na grade de ticks do mercado — chame GET /tick-size para cada mercado em vez de supor 0.01, porque o tick size varia e pode ficar menor à medida que o mercado amadurece. E ordens abaixo do tamanho mínimo do mercado são rejeitadas de cara. As duas voltam como 400 com mensagens específicas, listadas na referência de erros.
Um 200 em um lote não significa sucesso
Quando você envia várias ordens, as falhas de cada ordem voltam dentro do array da resposta 200, como campos errorMsg individuais. Percorra o array e verifique cada entrada. Bots que verificam só o status HTTP acreditam em silêncio que têm posições que não têm — uma classe de bug realmente perigosa.
Passo 6: saiba se a estratégia funciona
Tudo acima é encanamento, e o encanamento é a metade fácil. A pergunta difícil é se a sua estratégia dá dinheiro — e é aqui que criar bots para a Polymarket se afasta bastante de criar bots para cripto spot.
Não existe testnet. Nem sandbox, nem API de demonstração, nem endpoint de paper trading. Essas palavras não aparecem em nenhum lugar da documentação da Polymarket. Sua primeira ordem real é dinheiro real contra contrapartes reais. Veja a Polymarket tem uma testnet? para as quatro alternativas.
E não existe livro de ofertas histórico. Depois que um mercado é resolvido, o livro dele retorna 404. Ele guarda uma série de preços de cerca de um ponto por minuto, e só se você pedir com um início e um fim explícitos:
TOK=<token_id_of_a_resolved_market>
START=<epoch seconds the window opened>
END=$((START + 300))
curl -s "https://clob.polymarket.com/book?token_id=$TOK"
# {"error":"No orderbook exists for the requested token id"} HTTP 404
curl -s "https://clob.polymarket.com/prices-history?market=$TOK&startTs=$START&endTs=$END&fidelity=1"
# about 6 points for a 5-minute market; interval=max returns [] for older onesEntão você não consegue fazer backtest a partir da Polymarket. Você precisa de snapshots pontuais que alguém gravou enquanto os mercados estavam ativos. É isso que a PolyTest oferece para os mercados cripto Up/Down — mais de 240M de snapshots, 8 níveis de profundidade do livro por lado, timestamps abaixo de um segundo, mercados resolvidos mantidos:
import os, requests
BASE = "https://api.polytest.io/api/v1"
H = {"X-API-Key": os.environ["POLYTEST_KEY"]}
markets = requests.get(f"{BASE}/markets",
params={"coin": "btc", "market_type": "5m", "limit": 50},
headers=H).json()["markets"]
snaps = requests.get(f"{BASE}/markets/{markets[0]['id']}/snapshots",
params={"include_orderbook": "true"},
headers=H).json()["snapshots"]
def simulate_fill(levels, qty):
"""Walk the ladder. Mid-price is not a price you can trade at."""
filled = cost = 0.0
for lvl in levels:
take = min(lvl["size"], qty - filled)
cost += take * lvl["price"]
filled += take
if filled >= qty:
break
return cost / filled if filled >= qty else None
print(simulate_fill(snaps[0]["orderbook"]["asks"], 500))O erro que torna um backtest inútil
Se você faz backtest contra o preço médio, está testando uma identidade aritmética, não uma estratégia. Os spreads Up/Down costumam ficar entre 2 e 5 centavos em um contrato que liquida a $1 — frequentemente mais do que a vantagem alegada. Percorra o livro e use a execução que você realmente teria conseguido. Essa única mudança mata a maioria das estratégias, que é exatamente o que você quer que ela faça, de forma barata, antes de colocar dinheiro nelas.
Passo 7: sobreviva ao contato com a produção
Um bot que opera corretamente por uma hora e depois trava é pior do que nenhum bot. Estes são os modos de falha que realmente acontecem, mais ou menos na ordem de frequência:
| Falha | O que você vê | Como tratar |
|---|---|---|
| Limitado por taxa | Latência subindo, não erros | A Cloudflare atrasa em vez de rejeitar — observe o p99, não a taxa de erros |
| Reinício do motor de casamento | 425 Too Early | Tente de novo com backoff; não gere alerta para casos isolados |
| Exchange pausada | 503 | Pare de abrir posições. Cancele se for permitido |
| Modo somente cancelamento | 503 em novas ordens | O caminho de cancelamento precisa funcionar independentemente do caminho de entrada |
| Modo somente post-only | 503 + retry_after_seconds | Espere exatamente esse tempo e tente de novo |
| Divergência de signer | 400 de erro no signer da ordem | Credenciais antigas de outra carteira — derive de novo |
| Queda do WebSocket | Silêncio | Nenhum dado não é o mesmo que nenhuma mudança — acompanhe a idade da última mensagem |
| Desvio de relógio | 401 em um bot que funcionava ontem | Rode NTP; este é o que mais desperdiça tempo |
O silêncio é o estado perigoso
Um WebSocket que caiu não lança exceção — ele só para de entregar mensagens. Um bot com uma posição aberta e sem receber atualizações vai acreditar tranquilamente que o mercado está congelado no último preço que viu. Acompanhe a idade da última mensagem e trate a defasagem como condição de erro, não como calmaria.
- Teste o caminho de cancelamento antes do caminho de entrada. Não conseguir sair é muito pior do que não conseguir entrar.
- Limite a exposição no código, não na sua cabeça. Um limite rígido de posição transforma um bug de lógica em uma perda pequena, e não ilimitada.
- Construa um botão de emergência e teste-o de verdade. Um botão de emergência não testado é só um comentário.
- Adicione jitter ao trabalho agendado. Workers que acordam exatamente no mesmo segundo criam um pico sincronizado muito acima da sua taxa média.
- Registre em log todas as requisições e respostas na primeira semana. Você vai precisar delas, e não dá para reconstruí-las depois.
- Gere alertas por categoria, não por mensagem. A Polymarket inclui IDs de ordens e preços nas strings de erro, então alertas por string crua são puro ruído.
Uma ordem de construção realista
A sequência que desperdiça menos tempo e dinheiro:
- Integração somente leitura, cliente público, sem chaves. Prove a descoberta, o parsing, a paginação e o backoff. Um dia, grátis.
- Faça backtest da estratégia em livros históricos, com simulação honesta de execuções. A maioria das ideias morre aqui. É esse o objetivo.
- Paper trading ao vivo por pelo menos uma semana — registre em log as ordens pretendidas em vez de enviá-las. Prova a disponibilidade, as reconexões e o timing.
- Entre ao vivo com o tamanho mínimo, com um limite rígido de exposição e um botão de emergência testado.
- Só aumente o tamanho quando os números ao vivo baterem com os do paper trading. Se divergirem, seu modelo de execução estava errado — volte ao passo 2.
Os passos 1, 3 e 4 você constrói em poucos dias. O passo 2 precisa de dados que a Polymarket não guarda, e também é o passo que poupa dinheiro com mais confiabilidade. Comece um teste grátis na PolyTest — o suficiente para descobrir se a sua ideia sobrevive ao spread.
Perguntas frequentes
- Como crio um bot de trading para a Polymarket?
- Instale o SDK unificado atual — polymarket-client para Python ou @polymarket/client para TypeScript. Use o AsyncPublicClient para descobrir mercados e ler preços sem credenciais e depois o AsyncSecureClient com uma chave privada para operar. Assine o canal market do WebSocket em vez de fazer polling de preços, envie ordens com place_market_order e trate as respostas 425, 429 e 503 com backoff. Antes de entrar ao vivo, faça backtest com snapshots históricos do livro de ofertas e simulação realista de execuções, já que a Polymarket não tem testnet e não guarda histórico do livro de ofertas.
- Qual SDK devo usar para um bot da Polymarket em 2026?
- Use os SDKs unificados: polymarket-client para Python ou @polymarket/client para TypeScript. Eles substituem os pacotes antigos py-clob-client, @polymarket/clob-client-v2, @polymarket/builder-relayer-client e @polymarket/builder-signing-sdk. Um SDK unificado em Rust está em desenvolvimento. A maioria dos tutoriais e do código gerado por IA ainda faz referência aos pacotes descontinuados, então confira os imports antes de confiar em um trecho de código.
- Posso fazer paper trading na Polymarket antes de arriscar dinheiro real?
- Não pela Polymarket — não existe testnet, sandbox nem API de demonstração. Você mesmo pode construir uma camada de paper trading rodando o loop da sua estratégia ao vivo contra os dados de mercado de produção e registrando em log as ordens pretendidas, com o estado do livro naquele instante, em vez de enviá-las. Isso prova que seu bot é operacionalmente sólido, mas supõe as execuções, então não vai ensinar nada sobre posição na fila ou impacto no mercado.
- Como faço backtest de um bot de trading para a Polymarket?
- Você precisa de snapshots históricos do livro de ofertas de terceiros, porque a API da Polymarket retorna 404 para o livro de um mercado resolvido e guarda só cerca de um ponto por minuto de histórico de preços. Puxe snapshots pontuais com profundidade completa, reproduza-os em ordem cronológica sem olhar adiante e simule as execuções percorrendo os níveis do livro em vez de supor o preço médio. Spreads Up/Down de 2-5 centavos em um contrato de $1 costumam ser maiores do que a vantagem alegada, então backtests com preço médio enganam.
- Por que meu bot da Polymarket recebe Unauthorized/Invalid api key?
- Na maioria das vezes, por um de dois motivos. Ou o seu conjunto de credenciais está incompleto — a autenticação L2 precisa da chave de API, do secret e da passphrase juntos —, ou o relógio do seu sistema está desviado, já que a assinatura da requisição inclui um timestamp e alguns segundos de desvio a invalidam. Menos comum: você derivou as credenciais para uma carteira diferente daquela com que está operando.
- Preciso de WebSocket para um bot da Polymarket ou posso fazer polling?
- Use o WebSocket. Fazer polling de /book com um timer queima o orçamento de limite de requisições, adiciona latência e escala mal. Assine o canal market do CLOB para atualizações públicas do livro e de preços, e o canal user para atualizações das suas próprias ordens e negociações. Se você se conectar ao WebSocket cru em vez de usar um SDK, envie um PING a cada 10 segundos para manter a conexão viva.
Tenha os dados históricos que a Polymarket não guarda
A PolyTest registra os mercados cripto Up/Down da Polymarket enquanto estão ativos — mais de 240M de snapshots com 8 níveis de profundidade do livro de ofertas, timestamps abaixo de um segundo e mercados resolvidos preservados. Comece com um teste grátis de 3 dias.
Continue lendo
A vantagem do atraso do spot na Polymarket é real. E tem uns $100 de profundidade.
Compre o lado que o spot já confirmou, antes de a Polymarket reprecificar. Ao contrário da maioria das estratégias que as pessoas divulgam, esta sobrevive ao contato com os dados — com um z-score de 15. O motivo de ela não ter deixado todo mundo rico está no livro de ofertas.
WebSockets da Polymarket: dados em tempo real que não caem
Fazer polling do livro de ofertas é a forma mais comum de queimar o orçamento de limite de requisições sem ganhar nada. Veja os quatro streams, as opções de assinatura que ninguém documenta e o modo de falha em que seu bot recebe silêncio e acha que é calmaria.
O SDK Python da Polymarket em 2026 (e como sair do py-clob-client)
Se o seu código ainda importa ClobClient de py_clob_client, ele está construído sobre um pacote substituído — assim como a maior parte do código da Polymarket que um assistente de IA vai escrever para você. Veja o SDK atual e como migrar.