Tutorial de Bot da Polymarket · Capítulo 20 de 32
Acompanhe wallets de baleias da Polymarket e faça copy-trade dos melhores desempenhos programaticamente: identifique wallets lucrativas via leaderboard e análise on-chain, replique suas operações com regras de tamanho e timing.
O que este capítulo aborda
Copiar wallets vencedoras da Polymarket é uma ideia popular, mas as baleias reais da Polymarket estão, em sua maioria, fazendo arbitragem no final da janela em mercados resolvidos, não apostas direcionais. Este capítulo traz a pesquisa honesta da análise on-chain: quais wallets realmente copiar, por que a maioria não vale a pena copiar e a matemática de position sizing.
- Identificando wallets lucrativas
- Detecção de trades on-chain
- Position sizing em relação à baleia
- Latency: quão tarde é tarde demais
- Filtros: siga apenas wallets com edge verificado
- Código: detectar evento de compra da baleia, executar copy com size ajustado
Identificando wallets lucrativas
A premissa do whale-copying é que algumas wallets são consistentemente lucrativas e copiar suas entradas captura parte do seu edge. A análise on-chain das top wallets da Polymarket em 2025-26 produziu um resultado desanimador: a maioria das baleias visíveis está fazendo arbitragem no final da janela em mercados resolvidos, não trading direcional.
Perfil que medimos em três wallets de baleia candidatas:
- "hhhhhh6" (98,5% win rate, $n M volume) - 88% das entradas em preços ≥0,95, timestamp mediano de entrada em 226s de uma janela de 300s. Arbitragem pura de cauda, não direcional.
- "anonymous" (20% win rate) - jogador degenerado. Copiar perde dinheiro.
- "Jkim123" (53,5% win rate) - cara ou coroa. Não é um sinal que vale a pena copiar.
0% dos trades dessas baleias ocorreram nos primeiros 120s de qualquer janela de 5 minutos. O sinal preditivo (se existir) viria de grandes entradas no INÍCIO da janela - mas essas wallets não são as que estão no topo do leaderboard, porque isso é difícil.
Detecção de trades on-chain
Detectar os trades de uma wallet-alvo exige fazer polling da data-api da Polymarket ou se inscrever em eventos de transferência on-chain da CTF. A opção da data-api é mais simples.
def watch_wallet(wallet_addr, last_seen_ts=0):
while True:
url = f"https://data-api.polymarket.com/activity?user={wallet_addr}&limit=100"
events = requests.get(url).json()
for ev in events:
ts = int(ev.get("timestamp", 0))
if ts <= last_seen_ts: continue
if ev["type"] == "TRADE":
process_whale_trade(ev)
last_seen_ts = max(last_seen_ts, ts)
time.sleep(5)
Polling de cinco segundos é o piso prático para a data-api. Abaixo disso, você vai bater em rate limits. Para detecção em subsegundos, assine eventos ERC-1155 TransferSingle on-chain do contrato CTF filtrados pelo endereço proxy da baleia.
Position sizing em relação à baleia
Se você dimensiona sua cópia como uma fração constante do trade da baleia, você herda o perfil de risco dela. Duas alternativas práticas.
- Baseado em cap: dimensione cada cópia para um valor fixo em dólar ($10-50), independentemente do tamanho da baleia. Mais lento para compor, mas com perda limitada por trade.
- Weighted por win rate: dimensione a cópia como função do win rate recente da baleia. WR acima de 60% → cópia em tamanho cheio; 40-60% → metade do tamanho; abaixo de 40% → pule.
A abordagem baseada em cap é a opção mais segura para a primeira versão. Mude para weighted por win rate somente depois de medir o win rate real da baleia nas SUAS cópias (que normalmente é pior do que o número divulgado, porque você chega tarde).
Latency: quão tarde é tarde demais
O trade da baleia fica visível publicamente em 1-2 segundos após a execução. Copiá-lo exige uma latency de leitura mais rápida do que isso, além da sua própria latency de envio da ordem.
End-to-end para um copy bot típico: polling de 5-10 segundos + 200ms para envio da ordem = 5-15 segundos no total. Quando sua cópia dispara, o sinal da baleia já está no preço.
Para 99% das cópias, isso é tarde demais nos mercados apertados da Polymarket. A entrada da baleia mexeu o mid em 1-2 cents; você paga esse prêmio de 1-2 cents em relação ao ponto em que ela entrou. Se o edge dela era de 3c, metade já foi embora quando você chega.
Copy bots que funcionam ou (a) miram mercados de movimento lento, onde 30s de latency não importam, ou (b) usam inscrição em eventos on-chain para reagir em timeframes de subsegundo.
Filtros: siga apenas wallets com edge verificado
Três filtros antes de adicionar qualquer wallet à sua lista de cópia.
- 30+ trades fechados no histórico da wallet. Amostras menores são ruído.
- Win rate vitalício > 60%, OU valor esperado positivo por trade com base nos preços de entrada. Qualquer uma das condições; as duas é melhor.
- O padrão NÃO é arbitragem no final da janela. Verifique os segundos medianos até a resolução na entrada; se estiver perto de 0, a wallet está fazendo tail-yield arb que você não consegue reproduzir.
A maioria das wallets candidatas falha em um desses três critérios. O grupo de wallets realmente copiáveis é pequeno. Manter a lista exige rechecagem periódica - wallets lucrativas no mês passado podem não ser neste mês.
Código: detectar evento de compra da baleia, executar copy com size ajustado
Referência: detecte um evento CTF TransferSingle para uma baleia monitorada e dispare uma compra em cópia com size ajustado.
from web3 import Web3
w3 = Web3(Web3.WebsocketProvider(POLYGON_WSS))
ctf = w3.eth.contract(address=CTF_ADDR, abi=CTF_ABI)
WHALES = {"0xabc...": {"fraction": 0.05, "cap": 50}}
def on_transfer(event):
to = event.args["to"].lower()
if to not in WHALES: return
cfg = WHALES[to]
token_id = event.args.id
whale_size = event.args.value / 1e6
copy_size = min(cfg["cap"], whale_size * cfg["fraction"])
if copy_size < 5: return # not worth fees
book = fetch_book(str(token_id))
if book.best_ask:
place_fok(str(token_id), "BUY", book.best_ask + 0.01, copy_size)
# subscribe to ERC-1155 TransferSingle events from CTF
filt = ctf.events.TransferSingle.create_filter(fromBlock="latest")
while True:
for ev in filt.get_new_entries(): on_transfer(ev)
time.sleep(0.5)
Distinga compra de venda verificando from (endereço zero = mint = a baleia comprou) vs to (endereço zero = burn = vendeu).





