Polymarket 歷史資料:取得預測市場賠率與結算結果做研究

預測市場研究需要賠率隨時間的變化與已結算的結果。Narwhal 依時間間隔提供二元與純量事件的歷史、已結算事件清單,以及每個事件含有 final 與各交易平台結算資訊的結果。

列出已結算的事件

events 端點會列出預測事件,可依 topic、shape、status、from、to 與 limit 篩選。這個請求取得最近一次已結算的聯準會決策。status 的值有 upcoming、trading、closed、settled 與 void。

curl,已結算事件
curl -s -H "Authorization: Bearer $NARWHAL_API_KEY" \
  "https://api.narwhalapi.com/v1/predictions/events?topic=usa-fed&status=settled&limit=1"
回應
{
  "events": [
    {
      "event_id": "usa-fed-2026-10",
      "question": "Federal Reserve rate decision, 28 October 2026",
      "status": "settled",
      "closes_at": "2026-10-28T17:59:00Z",
      "resolves_at": "2026-10-28T18:00:00Z",
      "release_id": "ae2a77cc-3b5b-4541-a060-3bc2ea1145d9",
      "result": {
        "final": true,
        "settled_at": "2026-10-28T20:01:40Z"
      },
      "topic_id": "usa-fed",
      "shape": "scalar"
    }
  ],
  "next_cursor": null
}

已結算的事件會附上 result 摘要。當所有交易平台的結果都已最終確定時,final 為 true,settled_at 是各平台結算時間中最晚的一個。最後一頁的 next_cursor 為 null,否則把它當作 cursor 傳回即可取得下一頁。

讀取結果與最後的賠率

用事件 id 可以打開完整的預測。這個回應省略了各交易平台的規則文字,只保留 hold 列與每個平台的勝出市場。

curl,已結算的純量事件
curl -s -H "Authorization: Bearer $NARWHAL_API_KEY" \
  "https://api.narwhalapi.com/v1/predictions/scalar/usa-fed-2026-10"
回應,已精簡
{
  "event_id": "usa-fed-2026-10",
  "topic_id": "usa-fed",
  "question": "Federal Reserve rate decision, 28 October 2026",
  "status": "settled",
  "closes_at": "2026-10-28T17:59:00Z",
  "resolves_at": "2026-10-28T18:00:00Z",
  "as_of": "2026-10-28T17:58:00Z",
  "result": {
    "final": true,
    "settled_at": "2026-10-28T20:01:40Z",
    "venues": [
      {
        "venue": "kalshi",
        "final": true,
        "settled_at": "2026-10-28T18:06:30Z",
        "markets": [
          {
            "market_id": "KXFEDDECISION-26OCT-H0",
            "outcome": "yes",
            "value": "1"
          }
        ]
      },
      {
        "venue": "polymarket",
        "final": true,
        "settled_at": "2026-10-28T20:01:40Z",
        "markets": [
          {
            "market_id": "2589812",
            "outcome": "Yes",
            "value": "1"
          }
        ]
      }
    ]
  },
  "outcomes": [
    {
      "key": "hold",
      "label": "No change",
      "lower": "-12.5",
      "upper": "12.5",
      "probability": "0.9622",
      "quotes": [
        {
          "venue": "kalshi",
          "probability": "0.9602",
          "market_ids": [
            "KXFEDDECISION-26OCT-H0"
          ]
        },
        {
          "venue": "polymarket",
          "probability": "0.9686",
          "market_ids": [
            "111061902544814266207267295505639408607400625795891618462682726460921782993748"
          ]
        }
      ]
    }
  ],
  "above": []
}

as_of 為 2026 年 10 月 28 日 17:58 UTC,也就是市場關閉前一分鐘,hold 的機率為 0.9622。result.venues 列出各交易平台的市場,以及已結算的 outcome 與 value。Kalshi 將 KXFEDDECISION-26OCT-H0 市場結算為 yes,該市場 id 出現在 hold 結果的報價中。已結算的事件沒有 stale 欄位,因為該欄位只會在 upcoming、trading 與 closed 事件上傳送。

取得賠率歷史

歷史端點需要 start 與 end,並可選 interval,適用於純量、二元、時點與極值事件。這個請求讀取衰退市場的日線,並保留連續的兩根。

curl,二元事件的每日歷史
curl -s -H "Authorization: Bearer $NARWHAL_API_KEY" \
  "https://api.narwhalapi.com/v1/predictions/binary/usa-recession-2026/history?start=2026-10-01T00:00:00Z&end=2026-10-08T00:00:00Z&interval=1d"
回應,已精簡
{
  "backfill_venue": "polymarket",
  "series": [
    {
      "key": "yes",
      "active_from": "2026-10-01T00:00:00Z",
      "bars": [
        {
          "timestamp": "2026-10-04T00:00:00Z",
          "close": "0.0850"
        },
        {
          "timestamp": "2026-10-05T00:00:00Z",
          "open": "0.0750",
          "high": "0.0750",
          "low": "0.0750",
          "close": "0.0750"
        }
      ]
    }
  ],
  "next_cursor": null
}

每根線都有表示起始時間的 timestamp 與 close。10 月 4 日的那根只有 close,而 10 月 5 日的那根還有 open、high 與 low。四個值齊全的線是即時擷取的,只有收盤價的線則是來自交易平台的回填資料。backfill_venue 會指出該平台,active_from 說明序列從何時開始。純量事件的每個結果 key 對應一條序列。

用結果核對最後的賠率

腳本讀取已結算的聯準會事件,找出 Kalshi 市場結算為 yes 的結果,再走訪該結果的每日歷史。它會一直跟隨 next_cursor 直到最後一頁,每次都重複相同的 start、end 與 interval。

python,已結算事件的賠率歷史
import json
import os
import urllib.parse
import urllib.request

def get(path):
    req = urllib.request.Request(
        "https://api.narwhalapi.com" + path,
        headers={"Authorization": "Bearer " + os.environ["NARWHAL_API_KEY"]},
    )
    with urllib.request.urlopen(req, timeout=30) as r:
        return json.load(r)

def history(event_id, start, end, interval="1d"):
    bars, cursor = {}, None
    while True:
        query = {"start": start, "end": end, "interval": interval}
        if cursor:
            query["cursor"] = cursor
        page = get(f"/v1/predictions/scalar/{event_id}/history?" + urllib.parse.urlencode(query))
        for series in page["series"]:
            bars.setdefault(series["key"], []).extend(series["bars"])
        cursor = page["next_cursor"]
        if not cursor:
            return bars

event = get("/v1/predictions/scalar/usa-fed-2026-10")
print(event["status"], "final:", event["result"]["final"])

# The winning outcome: the Kalshi market that settled to yes.
yes = {m["market_id"] for v in event["result"]["venues"] if v["venue"] == "kalshi"
       for m in v["markets"] if m["outcome"] == "yes"}
winner = [o["key"] for o in event["outcomes"] for q in o["quotes"]
          if yes & set(q["market_ids"])]
print("winner:", winner)

bars = history("usa-fed-2026-10", "2026-10-21T00:00:00Z", "2026-10-29T00:00:00Z")
for bar in bars[winner[0]]:
    print(bar["timestamp"][:10], bar["close"])

它會列印 settled final: True,接著是 winner: ['hold'],再來是 hold 結果從 2026 年 10 月 21 日到 10 月 28 日的每日收盤價。數值從 0.8707 升到 0.9622,最後一個收盤價等於事件中 hold 列的 probability。這樣就得到校準表中的一列:決策前夕,市場給勝出結果的定價是 0.9622。

要建立樣本,可用 status=settled、一個 topic,以及針對結算時間的 from 與 to 視窗,對 /v1/predictions/events 逐頁取資料。對每個 event_id 執行腳本,把收盤前最後的機率和已結算的結果一起儲存。橫跨多個月的研究用 interval=1d,決策前最後幾天用 1h。

as_of 與 stale 對研究者代表什麼?

as_of 是上次檢查各交易平台的時間。對進行中的事件,如果超過 3 分鐘沒有檢查平台,stale 為 true。超過 30 分鐘後,回應不再傳送機率,每個 quotes 清單都是空的,所有平台都被排除。研究中應剔除這些時刻,或標記為缺漏。已結算與 void 的事件沒有 stale 欄位。

結果何時最終確定?

當所有交易平台的結果都最終確定後,result.final 為 true。平台已經裁定但尚未最終確定的結果仍可能變動。如果 Narwhal 發現某個最終結果在爭議或修正後有所改變,該結果會帶有 amended_at。凍結標籤之前,請檢查 final 與 amended_at。

void 事件長什麼樣子?

void 事件在事件清單中的狀態為 void。當某個平台結算或作廢了它的市場後,venues 中該平台的項目會帶有 settlement,值為 settled 或 void。在上面的聯準會回應中,兩個平台都顯示 settled。用 status=void 篩選可以找到被作廢的事件,在校準樣本中要把它們與已結算事件分開處理。

最多能回溯多久,間隔有哪些?

interval 可選 1m、5m、1h 或 1d,預設為 1h。單次請求最多可涵蓋:1m 為 2 天,5m 為 7 天,1h 為 92 天,1d 為 3,660 天。一頁約有 5,000 根線,而且即使 next_cursor 不是 null,該頁也可能是空的,所以要持續跟隨游標。完整的參數清單請見預測市場文件。

發布於 。

後續步驟