Polymarket Bot Tutorial · Chapter 11 of 32
How NegRisk multi-outcome markets work on Polymarket: sum-to-1 mechanics, the negRisk flag in CLOB orders, why YES legs across NegRisk are not interchangeable, and execution best practices.
What this chapter covers
NegRisk markets are Polymarket's mechanism for mutually exclusive multi-outcome events - the 2024 election candidates, the Premier League winner, tournament brackets. Most bots fail to handle them correctly on the first try because the order placement requires a flag that is silently dropped if missing. This chapter covers the mechanics and the production code path.
- What NegRisk means (mutually exclusive Yes legs)
- Why YES totals stay near 1 USD
- The neg_risk parameter in order placement
- Hedging across NegRisk legs
- When NegRisk arb works (and when it does not)
- Resolution edge cases
- Code: place a NegRisk order
What NegRisk means (mutually exclusive Yes legs)
NegRisk (short for "negative risk") is Polymarket's mechanism for events with multiple mutually exclusive outcomes - only one can resolve YES. The 2024 Presidential Election was one event with NegRisk: a Trump-YES position and a Harris-YES position cannot both pay out.
Under the hood: a single NegRisk event has one parent question_id and N child markets, each with its own YES/NO. The exchange enforces sum-to-1 across the YES legs at resolution - exactly one resolves to 1.0 and the rest to 0.0.
From a bot's perspective, the YES leg of each outcome trades as its own token, with its own book and price. The negRisk flag in order placement (below) routes the trade to the NegRisk-specific exchange contract; missing it sends to the standard CTF exchange and silently fails to settle correctly.
Why YES totals stay near 1 USD
Arbitrageurs continuously hold the sum of YES prices across all NegRisk legs to ≈ 1.0. If Trump-YES is 0.55 and Harris-YES is 0.40 and there are no other competitive candidates, the missing 0.05 is approximately the implied probability of "any other outcome." When the missing slice exceeds the implied tail probability, an arb opportunity exists: buy all YES legs proportionally, sum to less than 1.0, lock in the difference.
In practice the arb is competitive - the visible discount is usually 1-2 cents on liquid events, gone within minutes of opening. The arb is also liquidity-bound: you can lock in $1k of discount but not $20k.
Most bots are not doing NegRisk arb; they are trading individual legs and need to respect the negRisk flag for execution correctness.
The neg_risk parameter in order placement
In CLOB v2 SDKs, order placement takes a flags object with a boolean negRisk. The value must match the market type:
// Node (CLOB v2)
await client.createAndPostOrder(
{ tokenID, price: 0.45, size: 10, side: Side.BUY },
{ tickSize: '0.01', negRisk: true }, // <-- TRUE for NegRisk
OrderType.FOK
);
The flag is also a parameter in the daemon op signature most production bots use:
{ op: 'buy', tokenID, price, size, neg_risk: true, order_type: 'FOK' }
Source of truth: market.negRisk from the Gamma API. Always read it; never hardcode. A BTC-up/down market is negRisk: false (binary); a tournament-winner market is negRisk: true (multi-outcome). Crossing the wires sends orders to the wrong exchange and produces transfer failures at settlement.
Hedging across NegRisk legs
If you hold Trump-YES at 0.50 and want to hedge against a Trump loss, two options exist within NegRisk.
Buy a competing NO leg (e.g. Harris-NO at 0.45). This pays out if Harris loses, which includes Trump winning. Asymmetric - payoff if Trump wins but worthless if Trump loses to a third candidate.
Buy all competing YES legs in proportion. If your portfolio is fully balanced across the NegRisk legs, your exposure is hedged: exactly one will pay out. This is the synthetic-cash position.
The hedging instrument that does NOT work as expected: a NO leg on your existing market. Trump-NO is correlated with the other YES legs but not perfectly - if the resolution is "Other" your Trump-YES and your Trump-NO both go to 0. NegRisk legs are not pure binaries.
When NegRisk arb works (and when it does not)
The NegRisk arb of "sum to less than 1.0" works when three conditions hold.
- All legs liquid: each leg you need to buy has at least $1k of depth at the price you need. Arb requires hitting multiple books simultaneously; one illiquid leg breaks the whole trade.
- Spread tight enough: the cumulative spread-tax across all legs must be less than the discount. Five legs at 0.5c spread each is 2.5c of cost; if the discount is 1.5c, the arb is negative.
- You can hold to resolution: NegRisk arb is settlement arb. You receive payout when the parent event resolves; if that is 6 months out, your capital is locked.
For 95% of bots, NegRisk arb is not the strategy. The remaining strategies trade individual legs and the negRisk flag exists only to ensure the order routes correctly.
Resolution edge cases
Two edge cases to be aware of when holding NegRisk positions through resolution.
"None of the above" outcomes: some NegRisk events include an explicit "Other" or "None of the above" leg. If the actual answer doesn't match any named leg, this is the winner. Bots that don't model the explicit Other leg sometimes treat it as a degenerate case and miss the payout.
Disputed resolutions: NegRisk resolution goes through UMA like any other market. If disputed, the market may sit unresolved for 24-72 hours. During this window, the front-end may show "resolved" while the on-chain payouts are not yet set. Reading payoutNumerators on the CTF contract is the only safe way to confirm.
Code: place a NegRisk order
Full Node example placing a NegRisk YES leg buy.
import { ClobClient, Side, OrderType } from "@polymarket/clob-client-v2";
import { Wallet } from "ethers";
const c = new ClobClient({
host: "https://clob.polymarket.com", chain: 137,
signer: new Wallet(process.env.PRIVATE_KEY),
creds: { key: K, secret: S, passphrase: P },
signatureType: 2,
funderAddress: process.env.POLY_FUNDER,
});
// market.negRisk === true (verified via Gamma earlier)
const resp = await c.createAndPostOrder(
{ tokenID: "<YES_TOKEN_ID>", price: 0.42, size: 25, side: Side.BUY },
{ tickSize: "0.01", negRisk: true },
OrderType.FOK
);
console.log(resp.status, resp.orderID);
The single most common bug for new builders: omitting negRisk: true on a NegRisk market. The order is accepted by the CLOB but settlement fails. Always read market.negRisk from Gamma and pass it through; never rely on guessing from the question title.










