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.

  1. Flag negRisk mancante: ordini accettati, settlement fallisce. Cura: imponete il flag in ogni wrapper.
  2. 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.
  3. 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.
  4. 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).

Domande frequenti

Qual è l'invariant sum-to-1 nei mercati NegRisk?
Su tutte le leg YES di un mercato multi-outcome NegRisk, la somma dei prezzi YES resta vicina a 1 USD perché esattamente un outcome vince. Se la somma scende sotto 1.00 al netto delle fee, comprare ogni leg in proporzione blocca un profitto di arbitrage. L'arb è raro e viene snipato in fretta - consideratelo una curiosità, non una strategia primaria.
In cosa il pricing NegRisk è diverso dal binary?
Binary: il prezzo YES è la vostra stima diretta di probabilità. NegRisk: il prezzo YES di una leg è la probabilità che quello specifico outcome vinca tra N alternative. Man mano che N cresce, i prezzi individuali si riducono (le probabilità sommano a 1). Fare trading su NegRisk richiede ragionare in probabilità relative, non in Yes/No assoluti.
Qual è il bug più comune di un bot NegRisk?
Dimenticare il flag neg_risk: true nel placement dell'ordine. L'ordine viene rifiutato oppure instradato sulla posizione CTF sbagliata. Ci siamo passati in produzione - il commit 06deaef nella history del nostro trader era proprio la correzione. Impostate sempre neg_risk=true (Python) o negRisk: true (Node) sugli ordini NegRisk.
Posso fare soldi su NegRisk facendo hedge delle leg?
In teoria sì (bloccare lo spread tra due leg). In pratica le fee consumano il vantaggio dell'hedge per la maggior parte dei bot retail. L'hedging funziona per mantenere l'inventory neutral mentre fate market making, non come strategia standalone.
Come trovo i mercati NegRisk?
Filtrate gamma /events per eventi con markets count > 2 e flag negRisk impostato. Categorie comuni: championship winners (NBA Finals MVP), election fields (next Speaker), tournament brackets. Ogni evento gamma include il suo array child markets.
I mercati NegRisk sono più o meno liquidi dei binary?
Meno per leg, di più in aggregate. Un evento NBA Champion da 30 team può avere 50K di volume totale nelle 24h ma ogni mercato team ha solo 1.6K - rendendo il trading per leg più difficile. La liquidity aggregata è reale, è solo frammentata.