Polymarket Bot Tutorial · 32 bölümün 29'u

Canlıya geçmeden önce bir Polymarket paper trading engine oluşturun: emirleri gerçek fiyatlara karşı simüle edin, P&L takibi yapın, herhangi bir live capital kullanmadan önce 30-trade gate'i (>=55% win rate, +PnL) uygulayın ve code skeleton hazırlayın.

Bu bölüm neleri kapsıyor

Paper trading, strategy idea ile live deployment arasındaki pazarlık kabul etmez adımdır. Bu bölüm, canlıya çıkardığımız her botu kapıdan geçiren basit paper engine'dir - 200 satırın altında Python, her trade'i bir JSONL diary'de takip eder, live path ile aynı fees/slippage uygular.

  • Neden live öncesi paper (her zaman)
  • 30-trade gate (doğrulanmış +55% WR + pozitif PnL)
  • Basit bir paper engine oluşturma
  • Paper diary'yi live diary ile birlikte takip etme
  • Paper live'dan ne zaman sapar (ve neden)
  • Live'a geçiş: ilk küçük deposit
  • Code: minimal paper engine

Neden live öncesi paper (her zaman)

30-trade paper gate, kârlı Polymarket traders'ın %7.6'sını kaybeden %84.1'den ayıran tek disiplindir. Çoğu builder bunu atlar ve tuition öder. İşe yaradığına dair dürüst neden şu: paper trading, signal ile luck'ı ayırt edecek kadar yeterli örneklem üzerinde strategy'nin gerçek win rate'ini ortaya çıkarır.

Paper'ı atlamak, sağladığından daha fazlasına mal olur. Backtest'te kârlı görünen ama aslında coin flip olan bir strategy, 30 örneklem büyüklüğünde live data üretmeden önce $200-500 live capital yakar. Aynı 30 trade'i paper'da yapmak $0'a mal olur.

Paper engine'in sofistike olması gerekmez. Dürüst olması gerekir - aynı fees, aynı slippage, live path ile aynı fill latency. Ne kadar basitse o kadar iyi, çünkü opsiyonel olan her şey kesilir ve bot olması gerekenden daha erken live'a çıkar.

30-trade gate (doğrulanmış +55% WR + pozitif PnL)

Gate binary'dir: 30 closed paper trade, önceden yazılmış başarı kriterleri (genellikle positive-EV bir strategy için WR ≥ 55%), ya da live deployment yok.

30, gerçek win rate için %95 confidence interval'ın sinyali gürültüden ayıracak kadar dar olduğu minimum örneklem büyüklüğüdür. 30'un altında, gözlenen %60 oranı gerçek %45-75 aralığına karşılık gelebilir. 30+ seviyesinde interval yaklaşık %50-70'e daralır - hâlâ geniş, ama "strategy coin flip" değil demek için yeterli.

Başarı kriterleri paper run başlamadan ÖNCE belirlenmelidir. Sonradan belirlemek post-hoc rationalization üretir (her 30 trade'i "yeterince iyi" diye yorumlamanın bir yolunu bulursunuz).

Basit bir paper engine oluşturma

Paper engine, aslında order-placement function'ın simulated fill ile değiştirildiği live trading code'dur. Simülasyon:

  • Live order book oku: live bot'un yapacağı aynı çağrı.
  • Fill'i simüle et: FOK ile alım yaparken fiyat best ask'ten büyük/eşitse, emir ask'lerin tüketilen volume-weighted average'ında doldurulur; fill paper diary'ye kaydedilir.
  • Fees uygula: live path'in ödeyeceği aynı fees düşülür.
  • Inventory takip et: paralel bir paper-balance ve paper-positions dictionary tutulur.

Tüm engine 100-200 satır Python'a sığar. Temel disiplin şudur: live path'in yaptığı her varsayım (fill rate, latency, fee) paper'da da yeniden üretilmelidir, gerçeklikten biraz daha kötü olsa bile - paper floor olmalı, ceiling değil.

Paper diary'yi live diary ile birlikte takip etme

Paper trading run, bot'un daha sonra yazacağı live diary ile yapı olarak ayırt edilemez bir JSONL diary üretir. Aynı alanlar: timestamp, action, market_slug, side, size, price, expected_fill_price, simulated_pnl_at_exit.

Aynı formatı kullanmak için iki neden var. Birincisi, live trade'leri okuyan analysis tools (PnL reports, win-rate calculators) paper üzerinde değişiklik yapmadan çalışır. İkincisi, ileride paper ile live'ı karşılaştırmak bug'lara işaret eden sapmaları yakalar.

Production ipucu: paper engine'in per_trade_paper.jsonl dosyasına, live per_trade.jsonl ile aynı dizinde yazmasını sağlayın. Tek komutla ikisini karşılaştırın: diff -y <(jq -r .market_slug per_trade.jsonl) <(jq -r .market_slug per_trade_paper.jsonl).

Paper live'dan ne zaman sapar (ve neden)

Paper ile live arasında kaçınılmaz sapmalar olur. Üç yaygın olanı:

  • Slippage: paper, ask snapshot'ında fill olur; live book boyunca yürür ve ince markets'ta 1-2c daha kötü fill alabilir. Çözüm: paper'da slippage'ı spread'in yarısına eşit trade başı ceza ekleyerek simüle edin.
  • Fill latency: paper anında fill olur; live ise 200-500ms sürer ve bu sırada price hareket edebilir. Çözüm: paper'da "fill" etmeden önce bekleyip book'u yeniden okuyarak simüle edin.
  • Adverse selection: paper en iyi ask'i aldığınızı varsayar; live ise o ask'i çoktan kaldırmış olabilecek diğer bot'larla yarışır. Çözüm: bunu simüle etmek daha zordur; paper'ın fazla iyimser olduğunu kendinize dürüstçe kabul edin.

Paper +5%/month derken live -2%/month çalışıyorsa, fark genellikle bunlardan biridir. Strategy'nin kendisinin yanlış olduğunu varsaymak yerine, bunları tek tek audit edin.

Live'a geçiş: ilk küçük deposit

Paper 30 trade geçti. Live deployment planı:

  1. Smoke-test capital olarak $25-50 deposit edin. Bunu tuition olarak görün; kaybederseniz, ders buna değmiştir.
  2. Bot'u live mode'da 5-10 trade boyunca minimum size (5 share) ile çalıştırın.
  3. Her fill'in paper beklentileriyle 2c içinde eşleştiğini doğrulayın. Devam etmeden önce daha büyük herhangi bir farkı inceleyin.
  4. 5-10 live trade paper ile eşleşiyorsa, $200-500 deposit edin ve normal boyutlu position'larla çalıştırın.
  5. Eşleşmiyorsa durdurun, debug edin, düzeltin, 1. adımdan yeniden başlayın.

İlk deployment'ta en yaygın live-paper farkı eksik bir fee veya yanlış slippage tahminidir. Bunları düzeltmek basittir; disiplin, capital ölçeklemeden önce farkı yakalamaktır.

Code: minimal paper engine

Reference: live book'u okuyup FOK fill'i simüle eden basit paper engine.

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}

Production additions: paper sell function (buy'ın aynası), paper GTC simulation (fiyatta book'a post et, mid price o fiyata geldiğinde fill'i simüle et), paper diary ile "would-have-been" live diary arasında reconciliation.

Sıkça sorulan sorular

30-trade gate nedir?
Paper'dan live'a geçmek için iç gating kuralımız: en az 30 closed paper trade, win rate >= 55% ve slippage sonrası net PnL pozitif olmalı. Bunlardan herhangi biri başarısızsa paper'da kalırsınız. Bu kuralı, 2025'te birkaç erken go-live girişiminin hesapları boşaltmasından sonra geliştirdik.
Neden 30 trade, 100 değil?
İstatistiksel power. 30 trade ile %55 win rate, gerçek edge'in (noise değil) yaklaşık %70 olasılıkla var olduğunu gösterir. 100 trade ile bu güven %90+'a çıkar. 30'u minimum bar olarak seçtik çünkü daha uzun paper dönemleri çoğu zaman overfitting yaratır - traders strategy'yi test etmek yerine çok uzun süre ayarlar.
Eminsem paper trading'i atlayabilir miyim?
Tam da emin olduğunuz anda atlamamalısınız. Polymarket'te en iyi performansı gösteren bot'lar, daha önce yanılmış kişiler tarafından işletilir. 30-trade gate, doğru görünen ama olmayan strategy'leri yakalamak için vardır. Kendi strategy'lerimizin çoğu ilk paper aşamasında başarısız oldu - değeri budur.
Paper sonuçları live sonuçlarla eşleşir mi?
Yavaş hareket eden strategy'ler (politics, weather) için genellikle evet, hızlı olanlar (5-min crypto, sports microstructure) için hayır. Fark şudur: "paper trading slippage ödemez" - gerçek fill'ler gördüğünüz fiyattan daha kötüdür. Özellikle hızlı strategy'lerde live'a inanmadan önce paper returns'i %30-50 düşürürüz.
Python'da paper engine'i nasıl uygularım?
Trade ettiğiniz markets için gerçek CLOB WebSocket'e subscribe olun. Strategy'niz "bir emir yerleştir" dediğinde, bunu JSONL dosyasına, olması beklenen fill price ile kaydedin (buy için current bid, sell için current ask). Positions'ı sanal olarak takip edin. Live price'a karşı mark-to-market yapın. Tüm engine yaklaşık 200 satır Python'dur.
Live'a geçmeden önce ne kadar süre paper trade yapmalıyım?
30-trade gate karşılanana kadar ya da 2-4 hafta, hangisi daha uzunsa. Gate'e çok hızlı ulaşıyorsanız overfitting yapıyorsunuzdur; yavaşlayın ve win rate'in küçük parameter değişikliklerine karşı sağlam olduğunu doğrulayın. Aylar sonra hâlâ gate'e ulaşamıyorsanız, strategy muhtemelen edge taşımıyordur ve onu bırakmalısınız.