Uma desenvolvedora partilhou como criar um bot de negociação para Polymarket, capturando as oscilações de preço no mercado de BTC a cada 15 minutos, transformando 1.000 dólares em 1.869 dólares em poucos dias, com um retorno de 86% na backtest. O artigo detalha a lógica de construção do bot, o método de backtest e suas limitações.
(Prévia: O líder do mercado de previsões Polymarket anunciou a construção de uma L2 própria, a carta de Polygon perdeu o seu trunfo?)
(Complemento de contexto: Como obter um retorno anualizado de 40% através de arbitragem na Polymarket?)
Índice do artigo
Há algumas semanas, decidi construir meu próprio bot para Polymarket. A versão completa levou várias semanas para ficar pronta.
Estou disposto a dedicar esse esforço porque há de fato vulnerabilidades de eficiência na Polymarket. Embora já existam alguns bots aproveitando essas ineficiências para lucrar, ainda estão longe de cobrir o mercado, que oferece muitas oportunidades em relação ao número de bots existentes.
A lógica do bot baseia-se numa estratégia que executei manualmente no passado. Para aumentar a eficiência, automatizei o processo. O bot opera no mercado de “BTC 15 minutos UP/DOWN”.
O bot roda um programa de monitoramento em tempo real, que consegue trocar automaticamente para a rodada atual de BTC a cada 15 minutos, transmitindo as melhores ofertas de compra/venda via WebSocket, exibindo uma interface de terminal fixa, e permitindo controle total por comandos de texto.
No modo manual, você pode fazer ordens diretamente.
buy up / buy down : compra uma quantia específica em dólares.
buyshares up / buyshares down : compra uma quantidade exata de ações, usando ordens LIMIT (limitadas) + GTC (válidas até serem canceladas), a serem executadas ao melhor preço de venda (best ask) atual.
No modo automático, roda um ciclo de duas etapas (two-leg).
Na primeira etapa, observa a volatilidade de preço durante os minutos windowMin após o início de cada rodada. Se qualquer lado cair rápido o suficiente (com uma queda de pelo menos movePct em cerca de 3 segundos), dispara a “Primeira perna (Leg 1)”, comprando o lado que caiu mais.
Após completar a Leg 1, o bot nunca mais compra na mesma direção. Espera pela “Segunda perna (Leg 2, ou hedge)”, que só é disparada se a seguinte condição for satisfeita: leg1EntryPrice + oppositeAsk <= sumTarget.
Quando essa condição é atendida, compra-se o lado oposto. Após completar a Leg 2, o ciclo termina, e o bot volta ao estado de observação, aguardando o próximo sinal de queda com os mesmos parâmetros.
Se durante o ciclo a rodada mudar, o ciclo atual é abandonado, e na próxima rodada o bot reinicia com as mesmas configurações.
Os parâmetros do modo automático são: auto on [sum=0.95] [move=0.15] [windowMin=2]
A lógica do bot é simples: aguarda uma queda violenta, compra o lado que caiu, espera o preço se estabilizar e faz hedge comprando o lado oposto, garantindo que: priceUP + priceDOWN < 1.
Mas essa lógica precisa ser testada. Ela funciona de fato a longo prazo? Mais importante, o bot tem muitos parâmetros (quantidade de ações, soma, porcentagem de movimento, minutos de janela, etc). Qual combinação de parâmetros é a mais eficiente para maximizar o lucro?
Minha primeira ideia foi deixar o bot rodar na conta real por uma semana e observar os resultados. O problema é que isso leva muito tempo e só permite testar uma combinação de cada vez, enquanto preciso testar muitas.
Minha segunda ideia foi usar dados históricos online da API CLOB da Polymarket para backtestar. Infelizmente, para o mercado de BTC 15 minutos UP/DOWN, o endpoint de dados históricos sempre retorna um conjunto vazio. Sem ticks de preços históricos, não é possível detectar quedas de aproximadamente 3 segundos, não há como disparar a Leg 1, independentemente dos parâmetros, resultando em ciclos zero e ROI de 0%.
Após investigação adicional, descobri que outros usuários também enfrentaram o mesmo problema ao obter dados históricos de certos mercados. Testei mercados que retornam dados históricos e concluí que, para esse mercado específico, os dados históricos simplesmente não são mantidos.
Devido a essa limitação, a única forma confiável de backtestar essa estratégia é, durante a execução do bot, registrar instantaneamente o best-ask em tempo real para criar meu próprio conjunto de dados históricos.
O registrador faz snapshots no disco, contendo:
Depois, o “recorded backtest” reproduz esses snapshots, aplicando de forma determinística a mesma lógica automática. Isso garante acesso a dados de alta frequência necessários para detectar quedas e condições de hedge.
Em 4 dias, coletei 6 GB de dados. Poderia ter coletado mais, mas acho que isso é suficiente para testar diferentes combinações de parâmetros.
Comecei a testar essa configuração:
Também apliquei uma taxa fixa de 0,5% e uma margem de 2% para manter um cenário conservador.
O backtest mostrou um ROI de 86%, e em poucos dias, $1.000 virou $1.869.
Depois, testei uma configuração mais agressiva:
Resultado: após 2 dias, retorno de -50%.
Isso mostra claramente que a escolha dos parâmetros é fundamental. Pode fazer você ganhar muito dinheiro ou sofrer perdas significativas.
Mesmo considerando custos e spreads, o backtest tem suas limitações.
Para ser cauteloso, apliquei uma regra: se a Leg 2 não for executada antes do mercado fechar, a Leg 1 é considerada perda total.
Isso é deliberadamente conservador, mas nem sempre reflete a realidade:
Embora a perda possa estar superestimada, isso fornece uma visão de cenário “pior caso” útil.
Mais importante, o backtest não consegue simular o impacto de uma grande ordem no livro de ordens ou a atração de outros traders que possam tentar explorar sua posição. Na prática, suas ordens podem:
O backtest assume que você é um mero tomador de liquidez (price taker), sem impacto no mercado.
Por fim, não simula limites de frequência (rate limits), erros de API, ordens rejeitadas, pausas, timeouts, reconexões, ou a possibilidade de o bot perder sinais por estar ocupado.
Embora o backtest seja extremamente útil para identificar boas faixas de parâmetros, ele não garante 100%, pois alguns efeitos do mundo real não podem ser modelados.
Pretendo rodar o bot em um Raspberry Pi, para evitar consumir recursos do meu computador principal e garantir operação 24/7.
Ainda assim, há melhorias possíveis:
Certamente há outras otimizações que ainda não descobri. Atualmente, estou aprendendo Rust, pois ela está se tornando uma linguagem indispensável no desenvolvimento Web3.
#####