Polymarket Bot Tutorial · Chapter 22 of 32

NegRisk multi-outcome bots on Polymarket: sum-to-1 mechanics, leg arbitrage when YES legs dont sum to 1, hedging across legs, and execution pitfalls specific to multi-outcome markets.

What this chapter covers

Multi-outcome NegRisk markets are mutually exclusive - exactly one resolves YES. This chapter is the strategy layer on top of chapter 11's execution mechanics: how to hedge across legs, when sum-to-1 arb is real, and the bugs most NegRisk bots hit on first deploy.

  • 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: one yes/no market, two tokens, sum to 1.0. NegRisk: N mutually exclusive outcomes, N tokens, all YES legs sum to ~1.0 across the event.

Execution-wise, NegRisk requires negRisk: true on every order (chapter 11) and routes through a separate exchange contract. Strategy-wise, NegRisk offers two unique opportunities binaries don't: cross-leg arb when the sum drifts away from 1.0, and hedge construction by buying multiple YES legs.

The conversion mechanic - the capital-efficiency edge. Because the legs are linked, a No share in any one outcome can be converted into one Yes share in every other outcome, through the Neg Risk Adapter. So holding No on the favourite is economically a Yes basket across the whole field: you can build the same exposure two ways and take whichever is cheaper, or convert instead of buying each leg separately and save the per-leg spread. (Augmented neg-risk events also carry placeholder outcomes for not-yet-named candidates - ignore them until they are named or the event resolves.)

Costs unique to NegRisk: more legs = more spread tax (each leg you trade costs ~0.5-1c spread), wider sum-to-1 deviations on illiquid events (the arb is more often available but smaller).

Sum-to-1 invariant and arbitrage

The arb premise: if buying all N YES legs costs less than $1.00, you have locked in a guaranteed profit at resolution (one leg must pay $1.00; the others go to $0).

In practice, the arb gap is usually 0-3c, eaten by spread + fees on each leg, and disappears within minutes of opening. Capacity is limited by the thinnest leg's liquidity.

The arb is also subject to specific resolution failure modes: a "none of the above" outcome that explicitly resolves YES when no named candidate qualifies. If the event has such a leg and you didn't buy it, your "complete hedge" misses the actual payout.

Leg-by-leg hedge construction

Holding a position on one NegRisk leg, you can hedge by buying YES on competing legs in proportion. If you hold Trump-YES at 0.50 and want to hedge against a Trump loss, you buy a portfolio of the other named legs.

Hedge weight per leg ≈ leg's current implied probability conditional on Trump losing. Approximation: weight_i = price_i / (1 - trump_price).

The hedge is imperfect because the prices used are point-in-time and the conditional probabilities shift as news arrives. Rebalance the hedge weekly or on major news. Don't over-engineer it; the hedge's purpose is reducing variance, not eliminating it.

Execution: neg_risk flag in orders

The single most common NegRisk-specific bug: forgetting negRisk: true in the order placement payload. The order is accepted by the API but settles incorrectly because it routes to the standard CTF exchange instead of the NegRisk exchange.

// 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 from Gamma API. Read it; pass it through. Never hardcode the flag based on guessing.

Common bugs in NegRisk bots

From production debug logs across multiple bots.

  1. Missing negRisk flag: orders accepted, settlement fails. Cure: enforce the flag in every wrapper.
  2. Hedging without the "Other" leg: in events with a "None of the above" outcome, the hedge portfolio that excludes it is incomplete. Cure: always check for the Other leg when constructing hedges.
  3. Sum-to-1 arb under-sizing: arber realizes the 1c edge but trades 5 shares per leg; total profit is 5 cents before spread, negative net. Cure: size the arb to extract meaningful absolute dollars, not chase headline percentages.
  4. Stale leg pricing: bot fetches 3 leg prices, takes 200ms total, last leg's price changed during the fetch. Cure: fetch all legs in parallel + treat the snapshot as one observation.

Code: snapshot all legs and detect under-1.00 sum

Reference: snapshot all YES legs of a NegRisk event in parallel, detect 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

Atomic execution of all legs is the harder problem and requires per-leg FOK + rollback on partial fill (similar pattern to chapter 16's stat-arb code).

Frequently asked questions

What is the sum-to-1 invariant in NegRisk markets?
Across all YES legs of a NegRisk multi-outcome market, the sum of YES prices stays near 1 USD because exactly one outcome wins. If the sum drops below 1.00 net of fees, buying every leg in proportion locks in arbitrage profit. The arb is rare and gets sniped fast - treat as a curiosity, not a primary strategy.
How is NegRisk pricing different from binary?
Binary: YES price is your direct probability estimate. NegRisk: YES price for one leg is the probability of that specific outcome winning across N alternatives. As N grows, individual prices shrink (probabilities sum to 1). Trading NegRisk requires thinking in relative probabilities, not absolute Yes/No.
What is the most common NegRisk bot bug?
Forgetting the neg_risk: true flag in order placement. The order either rejects or routes to the wrong CTF position. We hit this in production - commit 06deaef in our trader history was specifically the fix. Always set neg_risk=true (Python) or negRisk: true (Node) on NegRisk orders.
Can I make money on NegRisk by hedging legs?
In theory yes (lock in spread between two legs). In practice the fees eat the hedge edge for most retail bots. Hedging works for keeping inventory neutral while market making, not as a standalone strategy.
How do I find NegRisk markets?
Filter gamma /events for events with markets count > 2 and the negRisk flag set. Common categories: championship winners (NBA Finals MVP), election fields (next Speaker), tournament brackets. Each gamma event includes its child markets array.
Are NegRisk markets more or less liquid than binary?
Less per leg, more in aggregate. A 30-team NBA Champion event might have 50K total 24h volume but each team market has only 1.6K - making per-leg trading harder. The aggregate liquidity is real, just fragmented.