Polymarket Bot Tutorial · 32 bölümün 22.si
Polymarket'te NegRisk multi-outcome botlar: sum-to-1 mechanics, YES leg'ler 1'e toplamlanmadığında leg arbitrage, leg'ler arasında hedging ve multi-outcome market'lere özgü execution tuzakları.
Bu bölüm neleri kapsıyor
Multi-outcome NegRisk market'ler birbirini dışlar - tam olarak biri YES olarak resolve olur. Bu bölüm, 11. bölümün execution mechanics'inin üstündeki strategy layer'dır: leg'ler arasında nasıl hedge yapılır, sum-to-1 arb ne zaman gerçekten vardır ve ilk deploy'da çoğu NegRisk bot'un takıldığı bug'lar nelerdir.
- NegRisk vs binary özeti
- Sum-to-1 invariant ve arbitrage
- Leg bazında hedge oluşturma
- Execution: order'larda neg_risk flag'i
- NegRisk bot'lardaki yaygın bug'lar
- Code: tüm leg'leri snapshot'la ve 1.00'ın altındaki toplamı tespit et
NegRisk vs binary özeti
Binary: bir yes/no market, iki token, toplam 1.0. NegRisk: N adet birbirini dışlayan outcome, N token, event boyunca tüm YES leg'leri toplamı yaklaşık 1.0.
Execution açısından NegRisk, her order'da negRisk: true gerektirir (11. bölüm) ve ayrı bir exchange contract üzerinden yönlendirilir. Strategy açısından NegRisk, binary'lerin sunmadığı iki benzersiz fırsat sağlar: toplam 1.0'dan saptığında cross-leg arb ve birden fazla YES leg satın alarak hedge oluşturma.
NegRisk'e özgü maliyetler: daha çok leg = daha fazla spread vergisi (trade ettiğiniz her leg yaklaşık ~0.5-1c spread maliyeti yaratır), likiditesi düşük event'lerde daha geniş sum-to-1 sapmaları (arb daha sık bulunur ama daha küçüktür).
Sum-to-1 invariant ve arbitrage
Arb mantığı: tüm N YES leg'i satın almak $1.00'dan daha az tutuyorsa, resolve anında garantili kâr kilitlemiş olursunuz (bir leg kesin olarak $1.00 öder; diğerleri $0'a gider).
Pratikte arb gap çoğunlukla 0-3c civarındadır, her leg'deki spread + fees tarafından yenir ve açılıştan sonraki dakikalar içinde kaybolur. Kapasite, en sığ leg'in likiditesiyle sınırlıdır.
Arb ayrıca belirli resolution failure mode'larına tabidir: hiçbir adayın qualify olmadığı durumda açıkça YES olarak resolve olan bir "none of the above" outcome'u. Event'te böyle bir leg varsa ve siz onu almadıysanız, "tam hedge" gerçek payout'u kaçırır.
Leg bazında hedge oluşturma
Bir NegRisk leg'inde pozisyon tutuyorsanız, rakip leg'leri orantılı şekilde satın alarak hedge edebilirsiniz. Trump-YES'i 0.50'de tutuyorsanız ve Trump kaybına karşı korunmak istiyorsanız, diğer isimlendirilmiş leg'lerden bir portföy alırsınız.
Leg başına hedge ağırlığı ≈ leg'in Trump kaybetmesi koşulu altındaki mevcut implied probability'si. Yaklaşım: weight_i = price_i / (1 - trump_price).
Hedge kusursuz değildir çünkü kullanılan fiyatlar point-in-time'dır ve news geldikçe conditional probability'ler değişir. Hedge'i haftalık ya da büyük news'lerde yeniden dengeleyin. Bunu aşırı mühendislik yapmayın; hedge'in amacı varyansı azaltmaktır, yok etmek değil.
Execution: order'larda neg_risk flag'i
NegRisk'e özgü en yaygın bug: order placement payload'ında negRisk: true eklemeyi unutmak. Order API tarafından kabul edilir ama standard CTF exchange yerine NegRisk exchange'e yönlenmediği için settlement yanlış olur.
// CORRECT for NegRisk markets:
await client.createAndPostOrder(
{ tokenID, price, size, side: Side.BUY },
{ tickSize: '0.01', negRisk: true }, // <-- REQUIRED
OrderType.FOK
);
Source of truth: Gamma API'den gelen market.negRisk. Onu okuyun; aynen iletin. Flag'i asla tahmine dayalı olarak hardcode etmeyin.
NegRisk bot'lardaki yaygın bug'lar
Birden fazla bot'tan alınan production debug log'larına göre.
- negRisk flag'inin eksik olması: order kabul edilir, settlement başarısız olur. Çözüm: her wrapper'da flag'i zorunlu kılın.
- "Other" leg'i olmadan hedge etmek: "None of the above" outcome'u olan event'lerde, onu hariç tutan hedge portföyü eksiktir. Çözüm: hedge oluştururken her zaman Other leg'i kontrol edin.
- Sum-to-1 arb'i küçük boyutlu almak: arber 1c edge'i görür ama her leg'de 5 share işlem yapar; toplam kâr spread'den önce 5 senttir, net negatif olur. Çözüm: arb'i manşet yüzdelerin peşinden koşmak için değil, anlamlı mutlak dolar elde edecek şekilde boyutlandırın.
- Bayat leg pricing: bot 3 leg fiyatı çeker, toplam 200ms sürer, son leg'in fiyatı fetch sırasında değişir. Çözüm: tüm leg'leri paralel çekin + snapshot'ı tek bir observation olarak değerlendirin.
Code: tüm leg'leri snapshot'la ve 1.00'ın altındaki toplamı tespit et
Reference: bir NegRisk event'inin tüm YES leg'lerini paralel snapshot'layın, arb'yi tespit edin.
import asyncio, aiohttp
async def fetch_leg_ask(session, token_id):
async with session.get(f"https://clob.polymarket.com/book?token_id={token_id}") as r:
d = await r.json()
asks = d.get("asks", [])
return float(asks[0]["price"]) if asks else None
async def check_arb(event_slug):
event = await fetch_event(event_slug)
if not event["markets"][0]["negRisk"]: return None
legs = []
for m in event["markets"]:
toks = json.loads(m["clobTokenIds"])
yes_token = toks[0]
legs.append(yes_token)
async with aiohttp.ClientSession() as s:
asks = await asyncio.gather(*[fetch_leg_ask(s, t) for t in legs])
if any(a is None for a in asks): return None
total = sum(asks)
if total < 0.97:
return {"edge": 1 - total, "legs": list(zip(legs, asks))}
return None
Tüm leg'lerin atomic execution'ı daha zor problemdir ve partial fill durumunda her leg için FOK + rollback gerektirir (chapter 16'nın stat-arb code'unda benzer bir pattern vardır).





