Polymarket Bot Tutorial · 第32章中7章目

Polymarket Gamma APIの徹底解説:/events と /markets エンドポイント、ページネーション、タグID(864 Tennis、745 NBA など)、24h volumeによるフィルタリング、rate limits、そしてPythonとNodeのコードサンプル。

この章で扱う内容

GammaはPolymarketのカタログAPIです。あらゆるイベント、あらゆるマーケット、タグ、画像、そしてフロントエンドに表示される確定済み結果を一覧できます。CLOB APIは取引を担い、Gammaは「何が取引可能か」を示します。ボットの検出レイヤーで起きるバグの多くは、この2つを混同するか、ページネーションの契約を見落とすことが原因です。この章は、本番のフェッチ処理が依存している正確なパラメータ挙動を含め、Gammaの主要エンドポイントの実践的なリファレンスです。

  • Gamma vs CLOB: どちらをいつ使うか
  • /events エンドポイントの構成
  • /markets エンドポイントの構成
  • タグとtag ID(検証済みリスト)
  • フィルタリング:active、closed、volume24hr順
  • ページネーションと制限
  • rate limitsとキャッシュ
  • コード:24h volume上位のマーケットを取得

Gamma vs CLOB: どちらをいつ使うか

2つの異なるサービスは、2つの異なる役割のためにあります。

Gammagamma-api.polymarket.com):カタログ。イベント、マーケット、タグ、説明、画像、確定済み結果、24時間出来高、総出来高、終了日時を一覧します。読み取り専用のHTTPです。多くの読み取りでは認証不要です。継続的に更新されますが、最終的整合性です。たとえば、ちょうどクローズしたマーケットが数秒間はclosed: falseのまま表示されることがあります。

CLOBclob.polymarket.com):取引 + order book。現在の最良bid/ask、top-Nの板厚、直近の約定を一覧します。書き込み系エンドポイント(注文発行、キャンセル)では認証が必要です。板更新用のリアルタイムWebSocketチャンネルも利用できます。

目安としては、Gammaで何を取引するかを探し、CLOBで実際に取引します。Gammaから価格を読んでいるボットは古いデータを使っています。Gammaの価格フィールドは、CLOBのorder bookほど頻繁には更新されません。CLOBからマーケットメタデータを読むボットは、不要なリクエストを増やしています。

/events エンドポイントの構成

GET /events はイベント単位のデータを返します。イベントとはPolymarketのページ1つで、1つのイベントに複数のマーケットが含まれることがあります(たとえば、2024年米大統領選挙イベントには候補者ごとに1マーケットずつあります)。

主なフィールド:

  • slug: URL安全な識別子。イベントの存続期間中は安定しています。
  • title, description: 人間向けの表示。
  • endDate(ISO 8601): イベントが終了する時刻。
  • active, closed: 真偽値。ライブイベントには?active=true&closed=falseでクエリに組み合わせます。
  • volume, volume24hr: USD建ての合計値。
  • tags: タグオブジェクトの配列(下のタグセクション参照)。
  • markets: 子マーケットオブジェクトの配列(/marketsの構成参照)。

最もよく使う発見パターンは、GET /events?active=true&closed=false&order=volume24hr&ascending=false&limit=100 です。これは、現在ライブのイベントのうち、出来高上位100件を返します。

/markets エンドポイントの構成

GET /markets はマーケット単位のデータを返します。マーケットとは、Yes/Noまたは複数結果の契約1つで、イベントの中に存在します。

主なフィールド:

  • slug: URL安全な識別子。
  • question: 取引ページに表示されるタイトル(例:"Will Trump be president on January 1, 2027?")。
  • outcomes: 結果名のJSON文字列。例:'["Yes","No"]'。binaryでは常に2要素、NegRiskではそれ以上になります。
  • outcomePrices: 現在価格の小数表現を含むJSON文字列。例:'["0.62","0.38"]'。両側の合計はスプレッドを除いておよそ1.0になります。
  • clobTokenIds: 結果に対応したERC-1155トークンIDのJSON文字列。実際に売買するのはこれらのトークンです。
  • negRisk: 真偽値。結果の合計が1になる複数結果マーケットではtrue。注文発行(第11章)に関係します。

outcomes / outcomePrices / clobTokenIds の各フィールドは、パース済み配列ではなくJSON文字列として返されます。使う前にJSONデコードしてください。

タグとtag ID(検証済みリスト)

タグはカテゴリラベルです(Sports、Crypto、Tennis、NBA など)。最もよく使われるカテゴリについて、本番環境で検証済みのtag IDは以下のとおりです。

TagIDTagID
Sports1NBA745
Crypto21NFL450
Politics2Tennis864
Bitcoin100196Esports702
Ethereum100383Soccer1059
Election3EPL739
Middle East1432UCL2186

特定のタグで絞り込むには?tag_id=745を使うか、slugを使って?tag_slug=nbaで指定します。slugベースのフィルタリングはコード上では読みやすいものの、少し遅くなります。IDベースが本番のデフォルトです。

フィルタリング:active、closed、volume24hr順

95%の場面で使う4つのフィルタ軸です。

  • active=true|false: true にすると、PolymarketチームがUIから非表示にしたマーケットを除外します。
  • closed=true|false: false にすると、確定済みマーケットを除外します。active=true&closed=false の組み合わせが、最も一般的なライブフィルタです。
  • order=volume24hr, order=volume, order=endDate: ソートキーです。現在アクティブなマーケットを探すなら、最も有用なのはvolume24hrです。
  • ascending=true|false: 多くのエンドポイントでデフォルトはtrueです。出来高順ではほぼ常にfalseを使います。

注意点として、tag_idでのフィルタリングにorder=volume24hrascending=falseを組み合わせると、そのタグにライブマーケットが極端に少ない場合、空のページが返ることがあります。常に多めに取得し(表示数より多くリクエストし)、後段で再フィルタしてください。

ページネーションと制限

limit パラメータは1回あたり1〜500を受け付けます。未指定時のデフォルトは100です。500を超えるとサーバー側で静かに上限がかかり、500件だけ返りますが、それ以上あることを示す表示はありません。

ページネーションはoffsetベースです。2ページ目は?limit=500&offset=500です。cursorベースのページネーションはないため、並行してデータが追加されると、呼び出し間でページ境界がずれることがあります。多くのボットの探索用途では問題ありません。アーカイブのスクレイプでは、安定したフィールド(endDate または createdAt)でソートし、slugで重複を検出してください。

「ライブマーケットをすべて取る」実用パターンは、limit=500&order=volume24hr&ascending=false で取得することです。これで、出来高上位500件、つまり実質的に大きな動きがあるマーケットはほぼ網羅できます。2ページ目以降に進むのは、ほとんどの場合あまり意味がありません。出来高分布の末端にあるマーケットは、定義上、動きの中心ではないからです。

rate limitsとキャッシュ

GammaはCloudflareの背後にあり、IPごとにソフトなrate limitsがあります。本番負荷で観測された経験則のしきい値は以下のとおりです。

  • 1つのIPから継続的に秒間約30リクエストまで:問題なし。
  • 秒間100リクエスト超のバースト:ときどき429が出るが、リトライは成功する。
  • 継続的に秒間約500リクエスト:rate limitページまたは一時ブロック(10〜60秒)。

公開されるレスポンスヘッダーには、多くのエンドポイントでCache-Controlの値として30〜60秒が含まれます。これに従ってください。1分の間に同じイベントを10回再取得しても、メリットはありません。本番でのキャッシュパターンは、完全なURLをキーにしたプロセス内LRU + TTLで、TTLは30秒です。リクエスト数を節約し、レイテンシを下げられます。

高頻度戦略では、単一のフェッチャープロセスで更新するローカルストアにGammaデータをミラーリングし、複数のコンシューマーはそのストアを読みます。1つのフェッチャー × 多数のコンシューマー は、多数のフェッチャー × Gamma より優れています。

コード:24h volume上位のマーケットを取得

3つの言語での参照用フェッチャーです。24時間出来高上位50件のライブマーケットを返します。

Python:

import requests
r = requests.get("https://gamma-api.polymarket.com/events",
                 params={"active":"true","closed":"false",
                         "order":"volume24hr","ascending":"false","limit":50},
                 timeout=10)
for ev in r.json()[:50]:
    print(ev["slug"], ev.get("volume24hr"))

Node:

const url = "https://gamma-api.polymarket.com/events?active=true&closed=false" +
            "&order=volume24hr&ascending=false&limit=50";
const events = await fetch(url).then(r => r.json());
for (const ev of events) console.log(ev.slug, ev.volume24hr);

Curl:

curl -s "https://gamma-api.polymarket.com/events?active=true&closed=false&order=volume24hr&ascending=false&limit=50" \
  | jq '.[].slug'

Polymarket gammaの/eventsエンドポイントは、自由記述の検索パラメータをサポートしていません?q=foo?search=foo を追加しても、黙ってデフォルト順のまま返ります。代わりに、slugまたはtagで絞り込んでください。

よくある質問

Polymarket Gamma APIとは何ですか?
GammaはPolymarketのメタデータと探索用APIです。イベント/マーケットの一覧、タイトル、説明、終了日時、タグ、集計出来高を提供します。リアルタイムのorder bookデータは提供しません。それはCLOB API側にあります。多くの探索・分析ユースケースでは、Gammaから始めます。
Polymarketにおけるイベントとマーケットの違いは何ですか?
イベントは、同じ質問テーマを共有する1つ以上のマーケットをまとめたものです。マーケットは、独自のorder bookとtoken IDを持つ特定のYes/No結果です。「2026 NBA Champion」イベントには30のマーケット(各チームごとに1つ)が含まれます。binaryのYes/Noイベントでは、イベントの下に1つのマーケットがあります。
Polymarketのtag IDはどうやって見つけますか?
タグはgammaの /tags エンドポイントで公開されています。本番で使っている検証済みIDは、864 Tennis、745 NBAです。URL内のtag slug(?tag_slug=tennis)や自由記述クエリ(?q=tennis)は信頼性が低いため、数値のtag_idのみを使ってください。slugを頼る前に /tags を確認してください。
Polymarketのイベントを24h volumeで並べ替えるには?
/events?order=volume24hr&ascending=false です。これは多くの「trending markets」ウィジェットの基盤になっています。active=true&closed=false を組み合わせると、期限切れや一時停止中のマーケットを除外できます。limit のデフォルトは25で、1回あたりの最大は500です。
Gammaにページネーションの制限はありますか?
はい。/events と /markets エンドポイントは、ページネーション用に limit(1回あたり最大500)と offset を受け付けます。多くのライブラリは自動でページネーションしないため、全件が必要なら、結果数が `limit` 未満になるページが返るまで offset を増やしてループしてください。
GammaはWebSocketをサポートしていますか?
いいえ。GammaはRESTのみです。リアルタイム更新(価格変動、新規マーケット、order book)にはCLOB WebSocketを使ってください。このシリーズの第8章で扱います。