Polymarket Bot Tutorial · 第32章中の22章

PolymarketのNegRiskマルチアウトカムbot: sum-to-1の仕組み、YESレッグの合計が1にならないときのレッグ裁定、レッグ間ヘッジ、そしてマルチアウトカム市場特有の実行上の落とし穴。

この章で扱う内容

マルチアウトカムのNegRisk市場は相互排他的です。つまり、ちょうど1つだけがYESで決済されます。この章は、11章の実行メカニクスの上にある戦略レイヤーです。レッグ間でどうヘッジするか、sum-to-1の裁定が本当に成立するのはいつか、そしてNegRisk botが初回デプロイで最もハマりやすいバグを解説します。

  • NegRiskとbinaryの復習
  • sum-to-1の不変条件と裁定
  • レッグごとのヘッジ構築
  • 実行: 注文におけるneg_riskフラグ
  • NegRisk botでよくあるバグ
  • コード: 全レッグをスナップショットして1.00未満の合計を検知する

NegRiskとbinaryの復習

Binary: 1つのyes/no市場、2つのトークン、合計は1.0。NegRisk: 相互排他的なN個の結果、N個のトークン、すべてのYESレッグの合計はイベント全体でおよそ1.0になります。

実行面では、NegRiskではすべての注文にnegRisk: trueが必要で(11章参照)、別のexchange contractを経由します。戦略面では、NegRiskにはbinaryにはない2つの独自機会があります。合計が1.0からずれたときのレッグ間裁定と、複数のYESレッグを買うことによるヘッジ構築です。

NegRisk固有のコスト: レッグが多いほどスプレッド税も増える(取引する各レッグで約0.5〜1cのスプレッドコスト)、流動性の低いイベントではsum-to-1の乖離が大きくなりやすい(裁定機会は見つけやすいが、規模は小さい)。

sum-to-1の不変条件と裁定

裁定の前提: すべてのN個のYESレッグを買うのに$1.00未満しかかからないなら、決済時に保証された利益をロックできます(1つのレッグは必ず$1.00を払い、他は$0になります)。

実際には、裁定ギャップは通常0〜3cで、各レッグのスプレッドと手数料に食われます。また、公開後数分で消えることがほとんどです。取り切れる量は、最も薄いレッグの流動性に制限されます。

この裁定は、特有の決済失敗モードにも影響されます。たとえば、どの候補も条件を満たさない場合に明示的にYESで決済される「none of the above」の結果です。イベントにそのレッグがあり、あなたがそれを買っていなければ、「完全ヘッジ」は実際のペイアウトを取り逃がします。

レッグごとのヘッジ構築

あるNegRiskレッグでポジションを持っている場合、競合するレッグのYESを比率に応じて買うことでヘッジできます。Trump-YESを0.50で保有していてTrump敗北に対するヘッジをしたいなら、他の候補レッグのポートフォリオを買います。

レッグごとのヘッジ比率 ≈ そのレッグの現在の暗示確率を、Trump敗北を条件にした値。近似式: weight_i = price_i / (1 - trump_price)

このヘッジは不完全です。使う価格はある時点のスナップショットであり、ニュース到来に応じて条件付き確率が変わるからです。ヘッジは週次、または大きなニュースのたびにリバランスしてください。やりすぎないこと。ヘッジの目的は分散を減らすことであり、完全に消すことではありません。

実行: 注文におけるneg_riskフラグ

NegRisk固有で最もよくあるバグは、注文送信ペイロードにnegRisk: trueを入れ忘れることです。注文自体はAPIで受理されますが、NegRisk exchangeではなく標準のCTF exchangeにルーティングされるため、決済が正しく行われません。

// CORRECT for NegRisk markets:
await client.createAndPostOrder(
  { tokenID, price, size, side: Side.BUY },
  { tickSize: '0.01', negRisk: true },   // <-- REQUIRED
  OrderType.FOK
);

真のソースはGamma APIのmarket.negRiskです。必ず読み、それをそのまま渡してください。推測でフラグをハードコードしてはいけません。

NegRisk botでよくあるバグ

複数のbotにわたる本番デバッグログから。

  1. negRiskフラグの未設定: 注文は受理されるが、決済に失敗する。対策: すべてのラッパーでフラグを強制する。
  2. 「Other」レッグを使わないヘッジ: 「none of the above」の結果があるイベントでは、それを除外したヘッジポートフォリオは不完全です。対策: ヘッジ構築時は必ずOtherレッグを確認する。
  3. sum-to-1裁定のサイズ不足: 裁定機会の1cのエッジは見つけたが、各レッグ5株しか取らない。総利益は手数料前で5セント、ネットではマイナス。対策: 見出しのパーセンテージを追うのではなく、意味のある絶対ドル額を取れるサイズにする。
  4. 古いレッグ価格: botが3つのレッグ価格を取得するのに合計200msかかり、取得中に最後のレッグ価格が変わっていた。対策: すべてのレッグを並列取得し、スナップショットを1つの観測値として扱う。

コード: 全レッグをスナップショットして1.00未満の合計を検知する

参考: NegRiskイベントのすべてのYESレッグを並列でスナップショットし、裁定を検知します。

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

すべてのレッグを原子的に実行するのはさらに難しく、レッグごとのFOKと部分約定時のロールバックが必要です(chapter 16のstat-arbコードと同様のパターンです)。

よくある質問

NegRisk市場におけるsum-to-1の不変条件とは何ですか?
NegRiskのマルチアウトカム市場では、すべてのYESレッグの合計は1ドル前後に保たれます。なぜなら、勝者はちょうど1つだからです。手数料を差し引いて合計が1.00を下回るなら、各レッグを比率に応じて買うことで裁定利益をロックできます。裁定は稀で、すぐに刈り取られます。主要戦略というより、面白い現象として扱ってください。
NegRiskの価格付けはbinaryとどう違いますか?
Binaryでは、YES価格はそのまま確率推定です。NegRiskでは、あるレッグのYES価格は、N個の候補の中でその特定の結果が勝つ確率です。Nが増えると個別価格は下がります(確率の合計は1になります)。NegRiskの取引では、Yes/Noの絶対値ではなく相対確率で考える必要があります。
NegRisk botで最も一般的なバグは何ですか?
注文送信時にneg_risk: trueフラグを忘れることです。注文が拒否されるか、誤ったCTFポジションにルーティングされます。これは本番で実際に起きました。私たちのtrader履歴ではcommit 06deaefがまさにその修正です。NegRisk注文では常にneg_risk=true(Python)またはnegRisk: true(Node)を設定してください。
レッグをヘッジしてNegRiskで儲けられますか?
理論上は可能です(2つのレッグ間のスプレッドをロックする)。ただし実際には、手数料がほとんどの個人botにとってヘッジのエッジを食ってしまいます。ヘッジはマーケットメイク中に在庫をニュートラルに保つためには有効ですが、単独戦略としては向いていません。
NegRisk市場はどうやって見つけますか?
gamma /events をフィルタして、market数が2を超え、negRiskフラグが立っているイベントを探します。よくあるカテゴリは、チャンピオン決定(NBA Finals MVP)、選挙関連(next Speaker)、トーナメントの組み合わせです。各gammaイベントには子market配列が含まれます。
NegRisk市場はbinary市場より流動性が高いですか、低いですか?
レッグ単位では低く、合算では高いです。30チームのNBA Championイベントでは24時間の総出来高が5万ドルでも、各チーム市場は1,600ドルしかないことがあり、レッグごとの取引は難しくなります。合計流動性は確かに存在しますが、断片化されています。