Polymarket Bot Tutorial · Capitolo 20 di 32
Traccia i wallet di balene su Polymarket e copia i top performer programmaticamente: identifica wallet profittevoli via leaderboard e analisi on-chain, replica i loro trade con regole di size e timing.
Cosa copre questo capitolo
Copiare wallet vincenti su Polymarket è un'idea popolare, ma le balene reali su Polymarket stanno per lo più facendo arbitraggio di fine finestra su mercati già risolti, non scommesse direzionali. Questo capitolo è la ricerca onesta dall'analisi on-chain: quali wallet copiare davvero, perché la maggior parte non vale la pena di copiare e la matematica del position sizing.
Questo è il capitolo 20 della nostra serie in 32 parti sulla costruzione di un trading bot per Polymarket. Trattiamo l'argomento in profondità nelle sezioni qui sotto. Il corpo di ogni sezione viene scritto e rilasciato capitolo dopo capitolo; le risposte FAQ e i riferimenti sono già completi e riflettono l'esperienza di produzione del nostro trader interno.
- Identificare wallet profittevoli
- Rilevamento dei trade on-chain
- Position sizing relativo alla balena
- Latenza: quanto tardi è troppo tardi
- Filtri: segui solo wallet con edge verificato
- Codice: rileva evento buy della balena, piazza copia dimensionata
Identificare wallet profittevoli
La premessa del whale-copying è che alcuni wallet sono consistentemente profittevoli e copiare le loro entry cattura parte del loro edge. L'analisi on-chain dei top wallet Polymarket nel 2025-26 ha prodotto un risultato sobering: la maggior parte delle balene visibili fa arbitraggio di fine finestra su mercati già risolti, non trading direzionale.
Profilo che abbiamo misurato su tre wallet balena candidati:
- "hhhhhh6" (98,5% di win rate, $n M di volume) — 88% delle entry a prezzi ≥0,95, mediana del timestamp di entry 226s su una finestra di 300s. Pure arb di tail-yield, non direzionale.
- "anonymous" (20% di win rate) — gambler degenerato. Copiarlo perde soldi.
- "Jkim123" (53,5% di win rate) — lancio di moneta. Non un segnale degno di copia.
0% dei trade di queste balene è avvenuto nei primi 120s di una finestra di 5 minuti. Il segnale predittivo (se esiste) verrebbe da entry GRANDI nella PARTE INIZIALE della finestra — ma quei wallet non sono quelli in cima alla leaderboard, perché sono difficili.
Rilevamento dei trade on-chain
Rilevare i trade di un wallet target richiede o polling della data-api di Polymarket o sottoscrizione agli eventi di transfer CTF on-chain. L'opzione data-api è più semplice.
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)
Il polling a 5 secondi è il pavimento pratico per la data-api. Sotto di quello colpirai i rate limit. Per rilevamento sub-secondo, sottoscriviti agli eventi on-chain ERC-1155 TransferSingle dal contratto CTF filtrati per il proxy address della balena.
Position sizing relativo alla balena
Se dimensioni la tua copia come frazione costante del trade della balena, erediti il suo profilo di rischio. Due alternative pratiche.
- Cap-based: dimensiona ogni copia a una cifra fissa in dollari (10-50 $) indipendentemente dalla size della balena. Lento a comporre ma perdita limitata per trade.
- Pesato sul win rate: dimensiona la copia come funzione del win rate recente della balena. 60%+ WR → copia full-size; 40-60% → mezza-size; sotto 40% → skip.
L'approccio cap-based è il primo deploy più sicuro. Passa al pesato-sul-win-rate solo dopo aver misurato il win rate effettivo della balena sulle TUE copie (che è di solito peggio del loro numero di testa perché arrivi tardi).
Latenza: quanto tardi è troppo tardi
Il trade della balena è pubblicamente visibile entro 1-2 secondi dall'esecuzione. Copiarlo richiede latenza più veloce di quella sul lato di lettura, più la latenza del tuo order placement.
End-to-end per un tipico copy bot: 5-10 secondi di polling + 200ms di order placement = 5-15 secondi totali. Quando la tua copia scatena, il segnale della balena è nel prezzo.
Per il 99% delle copie, è troppo tardi sui mercati stretti di Polymarket. L'entry della balena ha mosso il mid di 1-2 cent; paghi quel premio di 1-2 cent relativo a dove sono entrati loro. Se il loro edge era 3c, metà è già andata quando arrivi.
I copy bot che funzionano o (a) puntano a mercati a movimento lento dove 30s di latenza non contano, o (b) usano sottoscrizione a eventi on-chain per reagire in timeframe sub-secondo.
Filtri: segui solo wallet con edge verificato
Tre filtri prima di aggiungere qualsiasi wallet alla tua lista di copia.
- 30+ trade chiusi nella storia del wallet. Campioni più piccoli sono rumore.
- Win rate lifetime > 60%, O expected value positivo per trade basato sui prezzi di entry. O l'una o l'altra condizione; entrambe è meglio.
- Il pattern NON è arb di fine finestra. Controlla la mediana dei secondi-a-resolution all'entry; se è vicino a 0, il wallet sta facendo tail-yield arb che non puoi riprodurre.
La maggior parte delle balene candidate fallisce uno di questi tre. Il pool di wallet effettivamente copiabili è piccolo. Mantenere la lista richiede ricontrolli periodici — wallet che erano profittevoli il mese scorso potrebbero non esserlo questo mese.
Codice: rileva evento buy della balena, piazza copia dimensionata
Riferimento: rileva un evento CTF TransferSingle per una balena monitorata, scatena un buy di copia dimensionato.
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)
Distingui buy da sell controllando from (zero address = mint = la balena ha comprato) vs to (zero address = burn = venduto).











