Polymarket Bot Tutorial · Hoofdstuk 20 van 32
Track Polymarket whale-wallets en copy-trade top performers programmatisch: identificeer winstgevende wallets via leaderboard en on-chain analyse, spiegel hun trades met size- en timing-regels.
Wat dit hoofdstuk behandelt
Winnende Polymarket-wallets kopiëren is een populair idee, maar de werkelijke whales op Polymarket doen meestal late-window arb op afgehandelde markten, geen directionele bets. Dit hoofdstuk is het eerlijke onderzoek uit on-chain analyse: welke wallets daadwerkelijk te kopiëren, waarom de meeste niet de moeite waard zijn om te kopiëren en de position-sizing math.
Dit is hoofdstuk 20 van onze 32-delige serie over het bouwen van een Polymarket trading bot. We behandelen het onderwerp in detail in de secties hieronder. De body content voor elke sectie wordt geschreven en hoofdstuk-per-hoofdstuk uitgerold; FAQ-antwoorden en referenties zijn al compleet en weerspiegelen production-ervaring van het draaien van onze eigen trader.
- Winstgevende wallets identificeren
- On-chain trade-detectie
- Position-sizing relatief aan de whale
- Latency: hoe laat is te laat
- Filters: volg alleen wallets met geverifieerde edge
- Code: detecteer whale buy-event, plaats gedimensioneerde copy
Winstgevende wallets identificeren
De premise van whale-copying is dat sommige wallets consistent winstgevend zijn en kopiëren van hun entries een deel van hun edge vangt. On-chain analyse van Polymarkets top-wallets in 2025-26 produceerde een sobering resultaat: de meeste zichtbare whales doen late-window arbitrage op afgehandelde markten, geen directionele trading.
Profiel dat we maten op drie kandidaat-whale wallets:
- "hhhhhh6" (98,5% win rate, $n M volume) — 88% van entries op prijzen ≥0,95, mediaan entry-timestamp 226s van een 300s venster. Pure tail-yield arb, geen directioneel.
- "anonymous" (20% win rate) — degenerate gambler. Kopiëren verliest geld.
- "Jkim123" (53,5% win rate) — coin-flip. Geen signaal de moeite waard om te kopiëren.
0% van deze whales' trades vond plaats in de eerste 120s van een 5-minuten venster. Voorspellend signaal (indien aanwezig) zou komen van EARLY-window grote entries — maar die wallets zijn niet degene aan de top van het leaderboard, omdat ze moeilijk zijn.
On-chain trade-detectie
Het detecteren van trades van een target-wallet vereist of Polymarkets data-api pollen of abonneren op on-chain CTF transfer-events. De data-api optie is simpeler.
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)
Vijf-seconden polling is de praktische vloer voor de data-api. Lager dan dat raak je rate limits. Voor sub-seconde detectie, abonneer op on-chain ERC-1155 TransferSingle events van het CTF-contract gefilterd op het proxy-adres van de whale.
Position-sizing relatief aan de whale
Als je je copy dimensioneert als een constante fractie van de trade van de whale, erf je hun risicoprofiel. Twee praktische alternatieven.
- Cap-based: dimensioneer elke copy naar een vast dollar-cijfer (10-50 $) ongeacht whale-grootte. Traag om te compounden maar begrensd verlies per trade.
- Win-rate-weighted: dimensioneer copy als functie van de recente win-rate van de whale. 60%+ WR → full-size copy; 40-60% → halve size; onder 40% → skip.
De cap-based aanpak is de veiligere eerste deploy. Verhuis naar win-rate-weighted alleen nadat je de werkelijke win rate van de whale op JOUW copies hebt gemeten (wat meestal slechter is dan hun headline-getal omdat je laat aankomt).
Latency: hoe laat is te laat
De trade van de whale is publiekelijk zichtbaar binnen 1-2 seconden van executie. Hem kopiëren vereist snellere latency dan dat op de read-side, plus je eigen order-placement latency.
End-to-end voor een typische copy-bot: 5-10 seconden polling + 200ms order-placement = 5-15 seconden totaal. Tegen de tijd dat je copy vuurt, zit het signaal van de whale in de prijs.
Voor 99% van copies is dit te laat op Polymarkets smalle markten. De entry van de whale bewoog de mid 1-2 cent; je betaalt die 1-2 cent premium relatief tot waar zij ingingen. Als hun edge 3c was, is de helft al weg tegen de tijd dat je aankomt.
Copy-bots die werken targeten of (a) traag-bewegende markten waar 30s latency niet telt, of (b) gebruiken on-chain event-subscription om in sub-seconde timeframes te reageren.
Filters: volg alleen wallets met geverifieerde edge
Drie filters voor het toevoegen van enig wallet aan je copy-lijst.
- 30+ gesloten trades in de historie van de wallet. Kleinere samples zijn ruis.
- Lifetime win rate > 60%, OF positieve expected value per trade gebaseerd op entry-prijzen. Of de ene of de andere conditie; beide is beter.
- Patroon is GEEN late-window arb. Check de mediane seconds-to-resolution bij entry; als het bijna 0 is, doet de wallet tail-yield arb die je niet kunt reproduceren.
De meeste kandidaat-whales falen één van deze drie. De pool van daadwerkelijk-kopieerbare wallets is klein. Onderhoud van de lijst vereist periodieke recheck — wallets die vorige maand winstgevend waren zijn dat misschien deze maand niet.
Code: detecteer whale buy-event, plaats gedimensioneerde copy
Referentie: detecteer een CTF TransferSingle event voor een bewaakte whale, vuur een gedimensioneerde copy buy.
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)
Onderscheid buy van sell door from (zero address = mint = de whale kocht) vs to (zero address = burn = verkocht) te checken.











