Polymarket Bot Tutorial · Capitolo 22 di 32
NegRisk multi-outcome bots su Polymarket: mechanics sum-to-1, leg arbitrage quando le leg YES non sommano a 1, hedging tra le leg, e gli execution pitfall specifici dei mercati multi-outcome.
Cosa copre questo capitolo
I mercati multi-outcome NegRisk sono mutuamente esclusivi — esattamente uno si risolve YES. Questo capitolo è il livello strategico sopra le mechanics di execution del capitolo 11: come fare hedge tra le leg, quando l'arbitrage sum-to-1 è reale, e i bug che la maggior parte dei bot NegRisk incontra al primo deploy.
Questo è il capitolo 22 della nostra serie in 32 parti su come costruire un Polymarket trading bot. Trattiamo l'argomento in profondità nelle sezioni qui sotto. Il contenuto principale di ogni sezione viene scritto e rilasciato capitolo per capitolo; le risposte FAQ e i riferimenti sono già completi e riflettono l'esperienza di produzione maturata gestendo il nostro trader.
- Recap NegRisk vs binary
- Invariant sum-to-1 e arbitrage
- Costruzione dell'hedge leg-by-leg
- Execution: flag neg_risk negli ordini
- Bug comuni nei bot NegRisk
- Code: snapshot di tutte le leg e rilevazione della somma sotto 1.00
Recap NegRisk vs binary
Binary: un mercato yes/no, due token, somma a 1.0. NegRisk: N outcome mutuamente esclusivi, N token, tutte le leg YES sommano a ~1.0 sull'evento.
Dal punto di vista dell'execution, NegRisk richiede negRisk: true su ogni ordine (capitolo 11) e instrada attraverso un contratto di exchange separato. Dal punto di vista strategico, NegRisk offre due opportunità uniche che i binary non hanno: cross-leg arb quando la somma si allontana da 1.0, e costruzione di hedge comprando più leg YES.
Costi specifici di NegRisk: più leg = più spread tax (ogni leg che tradate costa circa 0.5-1c di spread), deviazioni sum-to-1 più ampie sugli eventi illiquidi (l'arb è più spesso disponibile ma più piccolo).
Invariant sum-to-1 e arbitrage
La premessa dell'arb: se comprare tutte le N leg YES costa meno di $1.00, avete bloccato un profitto garantito al settlement (una leg deve pagare $1.00; le altre vanno a $0).
In pratica, il gap di arb è di solito 0-3c, consumato da spread + fee su ogni leg, e scompare entro pochi minuti dall'apertura. La capacità è limitata dalla liquidity della leg più sottile.
L'arb è anche soggetto a failure mode specifici della resolution: un outcome "none of the above" che si risolve esplicitamente YES quando nessun candidato nominato è valido. Se l'evento ha una leg del genere e non l'avete comprata, il vostro "complete hedge" perde il payout reale.
Costruzione dell'hedge leg-by-leg
Detenendo una posizione su una leg NegRisk, potete fare hedge comprando YES sulle leg concorrenti in proporzione. Se siete long Trump-YES a 0.50 e volete coprirvi contro una sconfitta di Trump, comprate un portafoglio delle altre leg nominate.
Peso dell'hedge per leg ≈ probabilità implicita corrente della leg condizionata alla sconfitta di Trump. Approssimazione: weight_i = price_i / (1 - trump_price).
L'hedge è imperfetto perché i prezzi usati sono point-in-time e le probabilità condizionate cambiano quando arrivano news. Ribilanciate l'hedge ogni settimana o in caso di news importanti. Non sovra-ingegnerizzatelo; lo scopo dell'hedge è ridurre la varianza, non eliminarla.
Execution: flag neg_risk negli ordini
Il bug specifico di NegRisk più comune in assoluto: dimenticare negRisk: true nel payload di placement dell'ordine. L'ordine viene accettato dall'API ma si regola in modo errato perché viene instradato sul normale exchange CTF invece che sull'exchange NegRisk.
// 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 dalla Gamma API. Leggetelo; passatelo attraverso. Non hardcodate mai il flag basandovi su un'ipotesi.
Bug comuni nei bot NegRisk
Dai debug log di produzione su più bot.
- Flag negRisk mancante: ordini accettati, settlement fallisce. Cura: imponete il flag in ogni wrapper.
- Hedging senza la leg "Other": negli eventi con outcome "None of the above", il portafoglio di hedge che la esclude è incompleto. Cura: controllate sempre la leg Other quando costruite hedge.
- Under-sizing dell'arb sum-to-1: l'arber coglie il vantaggio di 1c ma tradate 5 share per leg; il profitto totale è di 5 cent prima dello spread, negativo netto. Cura: dimensionate l'arb per estrarre dollari assoluti significativi, non per inseguire percentuali in headline.
- Prezzi delle leg stale: il bot scarica 3 prezzi di leg, impiega 200ms totali, il prezzo dell'ultima leg cambia durante il fetch. Cura: fetch di tutte le leg in parallelo + trattate lo snapshot come un'unica osservazione.
Code: snapshot di tutte le leg e rilevazione della somma sotto 1.00
Reference: snapshot di tutte le leg YES di un evento NegRisk in parallelo, detection dell'arb.
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
L'execution atomica di tutte le leg è il problema più difficile e richiede FOK per singola leg + rollback su fill parziale (pattern simile al codice stat-arb del capitolo 16).











