Polymarket Bot Tutorial · Kapitel 22 von 32
NegRisk multi-outcome bots auf Polymarket: sum-to-1 mechanics, leg arbitrage wenn YES legs nicht zu 1 summieren, Hedging über Legs hinweg und Execution-Pitfalls, die speziell für multi-outcome markets gelten.
Was dieses Kapitel abdeckt
Multi-outcome NegRisk markets sind mutually exclusive - genau eines wird als YES resolven. Dieses Kapitel ist die Strategy-Ebene auf Basis der Execution-Mechanics aus Kapitel 11: wie man über Legs hinweg hedged, wann sum-to-1 arb echt ist und welche Bugs die meisten NegRisk bots beim ersten Deploy erwischen.
- NegRisk vs binary recap
- Sum-to-1 invariant and arbitrage
- Leg-by-leg hedge construction
- Execution: neg_risk flag in orders
- Common bugs in NegRisk bots
- Code: snapshot all legs and detect under-1.00 sum
NegRisk vs binary recap
Binary: ein yes/no market, zwei tokens, sum zu 1.0. NegRisk: N mutually exclusive outcomes, N tokens, alle YES legs summieren sich über das Event hinweg zu ungefähr 1.0.
Auf der Execution-Seite erfordert NegRisk negRisk: true auf jedem order (Kapitel 11) und läuft über einen separaten exchange contract. Auf der Strategy-Seite bietet NegRisk zwei einzigartige Chancen, die binaries nicht haben: cross-leg arb, wenn die Summe von 1.0 abweicht, und hedge construction durch den Kauf mehrerer YES legs.
Kosten, die speziell für NegRisk gelten: mehr Legs = mehr spread tax (jeder gehandelte Leg kostet ungefähr 0,5-1c spread), größere sum-to-1-Abweichungen bei illiquiden Events (der arb ist häufiger verfügbar, aber kleiner).
Sum-to-1 invariant and arbitrage
Die Arb-Prämisse: Wenn der Kauf aller N YES legs weniger als $1.00 kostet, hast du einen garantierten Gewinn bei der Resolution abgesichert (ein Leg muss $1.00 auszahlen; die anderen fallen auf $0).
In der Praxis beträgt die arb-Lücke meist 0-3c, aufgefressen durch spread + fees auf jedem Leg, und sie verschwindet innerhalb von Minuten nach dem Opening. Die Kapazität wird durch die Liquidität des dünnsten Legs begrenzt.
Der Arb unterliegt außerdem spezifischen Failure Modes bei der Resolution: ein "none of the above"-Outcome, das ausdrücklich als YES resolvt, wenn kein benannter Kandidat qualifiziert ist. Wenn das Event ein solches Leg hat und du es nicht gekauft hast, verpasst dein "kompletter Hedge" die tatsächliche Auszahlung.
Leg-by-leg hedge construction
Wenn du eine Position auf einem NegRisk-Leg hältst, kannst du dich durch den Kauf von YES auf konkurrierenden Legs proportional absichern. Wenn du Trump-YES bei 0.50 hältst und dich gegen einen Trump-Verlust hedgen willst, kaufst du ein Portfolio der anderen benannten Legs.
Das Hedge-Gewicht pro Leg ≈ die aktuelle implizite Wahrscheinlichkeit des Legs bedingt darauf, dass Trump verliert. Näherung: weight_i = price_i / (1 - trump_price).
Der Hedge ist ungenau, weil die verwendeten Preise eine Momentaufnahme sind und sich die bedingten Wahrscheinlichkeiten mit neuen Nachrichten verschieben. Rebalanciere den Hedge wöchentlich oder bei wichtigen News. Überengineere das nicht; der Zweck des Hedge ist, Varianz zu reduzieren, nicht sie vollständig zu eliminieren.
Execution: neg_risk flag in orders
Der mit Abstand häufigste NegRisk-spezifische Bug: negRisk: true im order placement payload zu vergessen. Der order wird von der API akzeptiert, settled aber falsch, weil er zum standard CTF exchange statt zum NegRisk exchange geroutet wird.
// CORRECT for NegRisk markets:
await client.createAndPostOrder(
{ tokenID, price, size, side: Side.BUY },
{ tickSize: '0.01', negRisk: true }, // <-- REQUIRED
OrderType.FOK
);
Source of truth: market.negRisk aus der Gamma API. Lies es aus und reiche es durch. Setze den Flag niemals aufgrund von Vermutung hardcoded.
Common bugs in NegRisk bots
Aus production debug logs über mehrere bots hinweg.
- Missing negRisk flag: orders akzeptiert, settlement schlägt fehl. Lösung: den Flag in jedem Wrapper erzwingen.
- Hedging without the "Other" leg: bei Events mit einem "None of the above"-Outcome ist das Hedge-Portfolio ohne dieses Leg unvollständig. Lösung: beim Konstruieren von Hedges immer nach dem Other leg schauen.
- Sum-to-1 arb under-sizing: der arber erkennt den 1c-Edge, handelt aber nur 5 shares pro Leg; der Gesamtgewinn beträgt vor spread 5 cents, netto negativ. Lösung: den arb so dimensionieren, dass relevante absolute dollars herauskommen, nicht nur Überschriften-Prozente jagen.
- Stale leg pricing: bot ruft 3 leg prices ab, braucht insgesamt 200ms, und der Preis des letzten Legs hat sich währenddessen geändert. Lösung: alle Legs parallel abrufen + die Snapshot als eine Beobachtung behandeln.
Code: snapshot all legs and detect under-1.00 sum
Referenz: alle YES legs eines NegRisk-Events parallel snapshotten und arb erkennen.
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
Atomic execution aller Legs ist das schwierigere Problem und erfordert per-leg FOK + rollback bei partial fill (ähnliches Muster wie der stat-arb code aus Kapitel 16).





