Polymarket Bot Tutorial · Hoofdstuk 29 van 32
Bouw een Polymarket paper trading engine voordat je live gaat: simuleer orders tegen echte prijzen, track P&L, dwing de 30-trade gate af (>=55% win rate, +PnL) voor enig live kapitaal en code-skeleton.
Wat dit hoofdstuk behandelt
Paper trading is de niet-onderhandelbare stap tussen strategy-idee en live deployment. Dit hoofdstuk is de simpele paper engine die als gate heeft gediend voor elke live bot die we hebben geshipt — onder 200 regels Python, trackt elke trade in een JSONL diary, past dezelfde fees/slippage toe als het live-pad.
Dit is hoofdstuk 29 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.
- Waarom paper voor live (altijd)
- De 30-trade gate (geverifieerd +55% WR + positieve PnL)
- Een simpele paper engine bouwen
- Paper diary tracken naast live diary
- Wanneer paper divergeert van live (en waarom)
- Naar live afstuderen: kleine eerste deposit
- Code: minimale paper engine
Waarom paper voor live (altijd)
De 30-trade paper gate is de enkele discipline die de 7,6% winstgevende Polymarket-traders scheidt van de 84,1% die verliest. De meeste builders skippen het en betalen lesgeld. De eerlijke reden waarom het werkt: paper trading onthult de werkelijke win rate van de strategie over genoeg samples om signaal van geluk te onderscheiden.
Paper skippen kost meer dan het bespaart. Een strategie die er winstgevend uitziet in backtest maar eigenlijk een lancier van een munt is zal 200-500 $ aan live kapitaal verbranden voordat ze een 30-sample omvang van live data produceert. Dezelfde 30 trades paper-traden kost 0 $.
De paper engine hoeft niet geavanceerd te zijn. Hij moet eerlijk zijn — zelfde fees, zelfde slippage, zelfde fill-latency als het live-pad. Hoe simpeler hoe beter, want alles wat optioneel is wordt gesneden en de bot gaat eerder live dan zou moeten.
De 30-trade gate (geverifieerd +55% WR + positieve PnL)
De gate is binair: 30 gesloten paper trades, vooraf geschreven succescriteria (typisch WR ≥ 55% op een positieve-EV strategie) of geen live deployment.
30 is de minimum sample size waar het 95% confidence-interval op de werkelijke win rate smal genoeg is om signaal van ruis te onderscheiden. Onder 30 kan een 60% geobserveerde rate corresponderen met een werkelijke rate van 45-75%. Bij 30+ versmalt het interval tot ~50-70% — nog steeds breed, maar genoeg om "de strategie is een lancier van een munt" uit te sluiten.
De succescriteria moeten worden gezet VOORDAT de paper run start. Ze later zetten produceert post-hoc rationalisatie (je vindt een manier om elke 30 trades als "goed genoeg" te interpreteren).
Een simpele paper engine bouwen
De paper engine is in essentie de live trading code met de order-placement functie vervangen door een gesimuleerde fill. De simulatie:
- Lees live order book: zelfde call als de live bot zou maken.
- Simuleer fill: als je koopt op FOK met prijs ≥ best ask, fill de order op het volume-gewogen gemiddelde van geconsumeerde asks; registreer de fill in het paper diary.
- Pas fees toe: trek dezelfde fees af die het live-pad zou betalen.
- Track inventory: onderhoud een parallel paper-balance en paper-positions dictionary.
De hele engine past in 100-200 regels Python. De sleuteldiscipline: elke aanname die het live-pad maakt (fill rate, latency, fee) moet worden gereproduceerd in paper, zelfs als iets slechter dan realiteit — paper moet de vloer zijn, niet het plafond.
Paper diary tracken naast live diary
De paper trading run produceert een JSONL diary qua structuur niet te onderscheiden van het live diary dat de bot later zal schrijven. Zelfde velden: timestamp, action, market_slug, side, size, price, expected_fill_price, simulated_pnl_at_exit.
Twee redenen om hetzelfde formaat te gebruiken. Eerst, de analyse-tools die live trades lezen (PnL reports, win-rate calculators) werken op paper zonder modificatie. Ten tweede, paper later met live vergelijken vangt divergenties die bugs indiceren.
Productie-tip: laat de paper engine schrijven naar per_trade_paper.jsonl in dezelfde directory als de live per_trade.jsonl. Een enkel commando vergelijkt beide: diff -y <(jq -r .market_slug per_trade.jsonl) <(jq -r .market_slug per_trade_paper.jsonl).
Wanneer paper divergeert van live (en waarom)
Onvermijdelijke divergenties tussen paper en live. Drie gangbare.
- Slippage: paper fillt op de ask-snapshot; live wandelt het book en kan 1-2c slechter fillen op dunne markten. Oplossing: simuleer slippage in paper door per trade een penalty toe te voegen gelijk aan de helft van de spread.
- Fill-latency: paper fillt direct; live duurt 200-500ms waarin de prijs kan bewegen. Oplossing: simuleer door te wachten en het book opnieuw te lezen voor "filling" in paper.
- Adverse selection: paper neemt aan dat je de best ask krijgt; live concurreert met andere bots die die ask mogelijk al hebben gelift. Oplossing: moeilijker te simuleren; eerlijke disclosure aan jezelf dat paper overschat.
Wanneer paper +5%/maand zegt en live op -2%/maand draait, is de gap meestal een van deze. Audit ze één voor één in plaats van aan te nemen dat de strategie zelf fout was.
Naar live afstuderen: kleine eerste deposit
Paper passeert 30 trades. Live deployment-plan:
- Stort 25-50 $ als smoke-test kapitaal. Behandel als lesgeld; als je het verliest, was de les het waard.
- Draai de bot in live modus voor 5-10 trades met posities op minimum size (5 shares).
- Verifieer dat elke fill matched met paper-verwachtingen binnen 2c. Onderzoek elke grotere gap voordat je doorgaat.
- Als 5-10 live trades matchen met paper, stort 200-500 $ en draai met normal-size posities.
- Als ze niet matchen, halt, debug, fix, herstart vanaf stap 1.
De meest voorkomende live-paper gap bij first deployment is een ontbrekende fee of een slippage-misinschatting. Die fixen is rechttoe rechtaan; de discipline is het vangen van de gap voordat je kapitaal scaleert.
Code: minimale paper engine
Referentie: simpele paper engine die live book leest + FOK-fill simuleert.
import json, time
PAPER_BAL = 10_000.0 # USD starting
positions = {} # token_id -> shares
def paper_fok_buy(token_id, max_price, size):
book = fetch_book(token_id)
# Walk asks, fill what we can within max_price
filled = 0; cost = 0
for level in book.asks:
px = float(level["price"])
if px > max_price: break
avail = float(level["size"])
take = min(avail, size - filled)
filled += take
cost += take * px
if filled >= size: break
if filled < size:
return {"status":"rejected","filled":0} # FOK semantics
global PAPER_BAL
PAPER_BAL -= cost
positions[token_id] = positions.get(token_id, 0) + filled
log_paper({"ts": int(time.time()), "action":"buy",
"token": token_id, "size": filled, "price": cost/filled})
return {"status":"matched","filled":filled,"cost":cost}
Productie-toevoegingen: paper sell-functie (spiegel van buy), paper GTC-simulatie (post op book op prijs, simuleer fill wanneer mid de prijs bereikt), reconciliation tussen paper-diary en "would-have-been" live diary.











