Polymarket Bot Tutorial · 第11章 / 32章
PolymarketにおけるNegRiskの複数結果マーケットの仕組み:1に収束するメカニズム、CLOB注文におけるnegRiskフラグ、NegRisk間のYESレッグが相互に置き換え可能ではない理由、そして執行のベストプラクティス。
この章で扱う内容
NegRiskマーケットは、Polymarketにおける相互排他的な複数結果イベントの仕組みです。たとえば2024年選挙の候補者、プレミアリーグ優勝チーム、トーナメントの組み合わせ表などが該当します。多くのbotは、注文時に必要なフラグがあり、これが欠けると黙って無視されるため、最初の試行で正しく扱えません。この章では、そのメカニクスと本番コードの流れを解説します。
- NegRiskの意味(相互排他的なYESレッグ)
- YES合計が1 USD前後に保たれる理由
- 注文時のneg_riskパラメータ
- NegRiskレッグ間のヘッジ
- NegRiskアービトラージが成立する条件(しない条件)
- 決済時のエッジケース
- コード:NegRisk注文の出し方
NegRiskの意味(相互排他的なYESレッグ)
NegRisk("negative risk"の略)は、複数の相互排他的な結果を持つイベントに対するPolymarketの仕組みです。YESで決済できるのは1つだけです。2024年大統領選挙はNegRiskの1つのイベントであり、Trump-YESポジションとHarris-YESポジションが両方とも支払い対象になることはありません。
内部的には、1つのNegRiskイベントに1つの親question_idとN個の子マーケットがあり、それぞれにYES/NOがあります。取引所は決済時にYESレッグの合計が1になるように強制し、ちょうど1つが1.0、残りは0.0で決済されます。
botの視点では、各結果のYESレッグはそれぞれ独立したトークンとして取引され、独自の板と価格を持ちます。注文時のnegRiskフラグ(下記)は取引をNegRisk専用の取引所コントラクトに振り分けます。これが欠けると標準のCTF取引所に送られ、決済時に正しく精算されません。
YES合計が1 USD前後に保たれる理由
アービトラージャーは、すべてのNegRiskレッグのYES価格合計を継続的に≈1.0に保ちます。たとえばTrump-YESが0.55、Harris-YESが0.40で、他に競合候補がいない場合、不足している0.05は「それ以外の結果」の暗示確率にほぼ相当します。不足分が暗示される尾部確率を上回ると、アービトラージの機会が生まれます。すべてのYESレッグを比率に応じて買い、合計を1.0未満に抑え、その差額を固定します。
実際にはこのアービトラージは競争が激しく、表示上のディスカウントは流動性の高いイベントでも通常1〜2セント程度で、公開後数分以内に消えます。また、アービトラージは流動性に制約されます。たとえば1,000ドル分のディスカウントは固定できても、2万ドル分はできません。
ほとんどのbotはNegRiskアービトラージをしているわけではなく、個別レッグを売買しているだけです。そのため、執行の正しさのためにnegRiskフラグを守る必要があります。
注文時のneg_riskパラメータ
CLOB v2のSDKでは、注文時にbooleanのnegRiskを含むflagsオブジェクトを渡します。値はマーケットタイプと一致していなければなりません。
// 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
);
このフラグは、多くの本番botが使うdaemon opのシグネチャでもパラメータになっています。
{ op: 'buy', tokenID, price, size, neg_risk: true, order_type: 'FOK' }
信頼できる情報源はGamma APIのmarket.negRiskです。必ず読み取り、ハードコードしないでください。BTCの上昇/下落マーケットはnegRisk: false(binary)で、トーナメント優勝マーケットはnegRisk: true(multi-outcome)です。これを取り違えると注文が誤った取引所に送られ、決済時にtransfer failureを起こします。
NegRiskレッグ間のヘッジ
Trump-YESを0.50で保有していて、Trump下落に対してヘッジしたい場合、NegRisk内には2つの選択肢があります。
競合するNOレッグを買う(例:Harris-NOを0.45で買う)。これはHarrisが負けた場合に支払われ、その中にはTrump勝利も含まれます。非対称で、Trumpが勝てば利益が出ますが、Trumpが第三候補に負けた場合は価値がありません。
競合するYESレッグをすべて比率に応じて買う。ポートフォリオがNegRiskレッグ全体で完全にバランスしていれば、エクスポージャーはヘッジされます。必ず1つが支払われるからです。これは合成キャッシュ・ポジションです。
期待どおりに機能しないヘッジ手段は、既存マーケットのNOレッグです。Trump-NOは他のYESレッグと相関していますが、完全ではありません。もし決着が「Other」なら、Trump-YESもTrump-NOもどちらも0になります。NegRiskレッグは純粋な二値ではありません。
NegRiskアービトラージが成立する条件(しない条件)
「合計が1.0未満」というNegRiskアービトラージは、次の3条件が満たされるときに成立します。
- すべてのレッグに流動性がある:買う必要のある各レッグに、必要価格で少なくとも1,000ドル分の板の厚みがあること。アービトラージでは複数の板を同時に叩く必要があり、1つでも流動性が足りないレッグがあると取引全体が崩れます。
- スプレッドが十分に狭い:全レッグにかかる累積のスプレッドコストが、ディスカウントより小さくなければなりません。たとえば5レッグそれぞれに0.5セントのスプレッドがあると、合計コストは2.5セントです。ディスカウントが1.5セントなら、そのアービトラージはマイナスです。
- 決済まで保有できる:NegRiskアービトラージは決済アービトラージです。親イベントが決着したときに配当を受け取ります。もしそれが6か月先なら、資本は拘束されます。
botの95%にとって、NegRiskアービトラージは戦略ではありません。残りの戦略は個別レッグを取引しており、negRiskフラグは注文を正しくルーティングするためだけに存在します。
決済時のエッジケース
NegRiskポジションを決済まで保有する際に注意すべきエッジケースは2つあります。
「上記以外」結果:一部のNegRiskイベントには、明示的な「Other」または「None of the above」レッグがあります。実際の答えがいずれの名前付きレッグにも一致しない場合、これが勝者になります。明示的なOtherレッグをモデル化していないbotは、ときにこれを例外的なケースとして扱い、配当を取り逃がします。
異議申し立てされた決済:NegRiskの決済も、他のマーケットと同様にUMAを経由します。異議が出ると、マーケットは24〜72時間未決済のままになることがあります。この間、フロントエンドでは「resolved」と表示されていても、オンチェーンの支払いはまだ確定していない場合があります。確認する安全な方法は、CTFコントラクト上のpayoutNumeratorsを読むことだけです。
コード:NegRisk注文の出し方
NegRiskのYESレッグを買うNodeの完全な例です。
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);
新規実装者が最もよくやるバグは、NegRiskマーケットでnegRisk: trueを付け忘れることです。注文はCLOBで受理されますが、決済に失敗します。必ずGammaからmarket.negRiskを読み取り、そのまま渡してください。質問タイトルから推測してはいけません。
よくある質問
neg_risk: trueを含める必要があります(Python: OrderArgsに渡す、Node: CreateOrderOptionsに渡す)。このフラグを忘れると、注文が拒否されるか、さらに悪いことに誤った注文板に出されます。私たちは本番でこのバグを実際に踏みました - トレーダー履歴のcommit 06deaefです。









