建立總經事件的市場賠率儀表板

總經賠率儀表板需要主題清單,以及每個卡片一次事件讀取。Narwhal 以四種命名形態提供 CPI、非農就業、失業率、衰退與央行決策的市場賠率:scalar、binary、timing 和 extreme。

列出為儀表板提供內容的主題

儀表板上的每個卡片對應一個主題。主題端點會列出它們,並接受可選的 group 參數。總經分組有 central_banks、us_prices、us_jobs、us_activity、global_activity 和 global_prices。這個請求指定 us_jobs,並只保留前兩個主題。

curl,美國就業主題
curl -s -H "Authorization: Bearer $NARWHAL_API_KEY" \
  "https://api.narwhalapi.com/v1/predictions/topics?group=us_jobs"
回應,已精簡
{
  "topics": [
    {
      "topic_id": "usa-payrolls",
      "group": "us_jobs",
      "title": "US nonfarm payrolls change",
      "shape": "scalar",
      "unit": "jobs",
      "unit_key": "job",
      "venues": [
        "kalshi"
      ],
      "resolution_kind": "release",
      "calendar": {
        "country": "USA",
        "family": "labour"
      },
      "next_event_id": "usa-payrolls-2026-10"
    },
    {
      "topic_id": "usa-unemployment",
      "group": "us_jobs",
      "title": "US unemployment rate",
      "shape": "scalar",
      "unit": "percent",
      "unit_key": "percent",
      "venues": [
        "kalshi",
        "polymarket"
      ],
      "resolution_kind": "release",
      "calendar": {
        "country": "USA",
        "family": "labour"
      },
      "next_event_id": "usa-unemployment-2026-10"
    }
  ]
}

shape 告訴你該呼叫哪個端點:scalar、binary、timing 或 extreme。unit 給出答案的單位,venues 列出背後的市場,resolution_kind 說明該主題如何結算。next_event_id 是目前應顯示的事件。有些主題(例如 deu-gdp-yoy)沒有 next_event_id,腳本會跳過它們。

讀取一個事件:衰退賠率

binary 事件提出的是是非題。這個請求讀取衰退市場,回應中不包含各市場的規則文字。

curl,binary 事件
curl -s -H "Authorization: Bearer $NARWHAL_API_KEY" \
  "https://api.narwhalapi.com/v1/predictions/binary/usa-recession-2026"
回應,已精簡
{
  "event_id": "usa-recession-2026",
  "topic_id": "usa-recession-2026",
  "question": "US recession by end of 2026?",
  "status": "trading",
  "closes_at": "2026-12-31T00:00:00Z",
  "resolves_at": "2026-12-31T00:00:00Z",
  "as_of": "2026-11-03T02:21:00Z",
  "stale": false,
  "resolution": "Two consecutive negative quarters of US real GDP from Q2 2025 to Q4 2026, or an NBER recession call for 2025 or 2026",
  "venues": [
    {
      "venue": "kalshi",
      "url": "https://kalshi.com/markets/kxrecssnber/kxrecssnber-26",
      "rules_url": "https://assets.kalshi.com/contract_terms/NBERRECSS.pdf",
      "settlement_source": "Bureau of Economic Analysis",
      "excluded_reason": "rules",
      "match": {
        "differences": [
          "rules"
        ],
        "note": "Kalshi resolves on two negative GDP quarters only; Polymarket also counts an NBER recession call"
      },
      "volume_24h_usd": "123.64",
      "open_interest_usd": "17994.22"
    },
    {
      "venue": "polymarket",
      "url": "https://polymarket.com/event/us-recession-by-end-of-2026",
      "settlement_source": "Bureau of Economic Analysis; NBER",
      "weight": "1.0000",
      "volume_24h_usd": "2090.24"
    }
  ],
  "probability": "0.0550",
  "quotes": [
    {
      "venue": "kalshi",
      "probability": "0.0250",
      "market_ids": [
        "KXRECSSNBER-26"
      ]
    },
    {
      "venue": "polymarket",
      "probability": "0.0550",
      "market_ids": [
        "100379208559626151022751801118534484742123694725746262280150222742563282755057"
      ]
    }
  ]
}

probability 是「是」的市場賠率,這裡為 0.0550,quotes 列出各市場的價格。Kalshi 的項目帶有 excluded_reason: rules 和一則 match 說明:其規則只計入 GDP 連續兩個季度為負,而 Polymarket 還計入研究機構作出的衰退判定。Kalshi 的 0.0250 仍保留在 quotes 中供參考,而頂層的 probability 等於 Polymarket 的報價。as_of 是報價時間,報價有效時 stale 為 false。

API 命名的四種形態

形態回答的問題需要讀取的欄位範例事件
scalar某次數據公布或決策會落在哪個數值或區間outcomes,每一項包含 key、label、lower、upper、probabilityusa-cpi-yoy-2026-11
binary會不會發生probability 和 quotesusa-recession-2026
timing會在何時之前發生steps,每一項包含 by、label、probabilityusa-fed-next-cut-to-2028-12-31
extreme某個序列會升到多高或降到多低由 level 和 probability 組成的 up 與 down 清單,外加 windowusa-unemployment-peak-2026

scalar 事件涵蓋總經儀表板要呈現的各項數據公布:CPI 的 12 個月變化、失業率、非農就業人數以及各央行的利率決策。CPI 或失業率事件的 resolves_with 欄位指向用於結算它的 Narwhal 序列,例如 /v1/economics/USA/cpi。因此事件結算後,卡片可以從賠率直接連結到已公布的數字。

scalar 事件還會替區間的邊界命名。在一個 outcome 中,lower 和 upper 限定區間範圍,邊界為 null 表示該側是開區間,例如表示 3.0% 及以下的 le_3.0 一列。在為本頁讀取的 CPI、失業率與聯準會事件中,各列的 probability 總和為 1,因此用 outcomes 畫長條圖就能呈現完整的分布。

產生儀表板的各列

腳本遍歷三個分組,用各主題的形態所指向的端點讀取該主題的下一個事件,並為每個卡片印出一行標題。scalar 顯示可能性最大的結果,binary 顯示「是」的賠率,timing 顯示第一個節點,extreme 顯示第一個水準。沒有可用報價的卡片會如實說明。

python,每個主題一列標題
import json
import os
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 headline(shape, e):
    if shape == "binary":
        if "probability" not in e:
            return "no usable quote"
        return f"yes {float(e['probability']):.1%}"
    if shape == "scalar":
        priced = [o for o in e["outcomes"] if "probability" in o]
        if not priced:
            return "no usable quote"
        top = max(priced, key=lambda o: float(o["probability"]))
        return f"{top['label']} {float(top['probability']):.1%}"
    if shape == "timing":
        step = e["steps"][0]
        if "probability" not in step:
            return "no usable quote"
        return f"by {step['label']} {float(step['probability']):.1%}"
    if shape == "extreme":
        if not e["up"] or "probability" not in e["up"][0]:
            return "no usable quote"
        step = e["up"][0]
        return f"reach {step['level']} {float(step['probability']):.1%}"

for group in ("us_prices", "us_jobs", "us_activity"):
    for topic in get("/v1/predictions/topics?group=" + group)["topics"]:
        if not topic.get("next_event_id") or topic["shape"] == "scalar" and topic["unit"] == "count":
            continue
        e = get(f"/v1/predictions/{topic['shape']}/{topic['next_event_id']}")
        print(group, e["event_id"], topic["shape"], headline(topic["shape"], e),
              "stale" if e["stale"] else "live")
事件形態標題
usa-cpi-yoy-2026-11純量3.9%, 20.0%
usa-unemployment-2026-10純量4.2%, 37.1%
usa-unemployment-peak-2026極值觸及 5.0,3.1%
usa-recession-2026二元是 5.5%
usa-gdp-2026-q4純量無可用報價

這些列是某一次執行的輸出。賠率會隨市場變動,所以請查看每個卡片上的 as_of,並從 API 重新整理頁面。

沒有可用報價的卡片是什麼意思?

事件回應帶有 stale: true,且沒有機率欄位。以 emu-ecb-cut-2026 為例,其 binary 回應的 quotes 清單為空,Polymarket 的項目帶有 excluded_reason: thin。回應中沒有可顯示的機率,所以這類卡片應顯示為不可用,而不是 0。

CPI、非農就業和失業率分別在哪些主題裡?

usa-cpi-yoy、usa-cpi-mom、usa-core-cpi-yoy 和 usa-core-cpi-mom 在 us_prices 中。usa-payrolls 和 usa-unemployment 在 us_jobs 中。usa-recession-2026 在 us_activity 中,利率決策在 central_banks 中。先查詢分組,再讀取每個主題的 next_event_id。

如何列出即將到來的事件,而不是每個主題只取一個?

用 topic 和 status=trading 呼叫 /v1/predictions/events。對 usa-cpi-yoy,它會回傳 2026 年 11 月的事件 usa-cpi-yoy-2026-11(在 2026 年 12 月 10 日 13:30 UTC 結算)以及 2026 年 12 月的事件 usa-cpi-yoy-2026-12。每一列都有 question、closes_at、resolves_at 和 shape。可以用它來做已有市場的數據公布行事曆檢視,再用對應形態的端點開啟每個事件。

同一個清單還接受 shape、from、to、limit 和 cursor,status=settled 則回傳已經結算的事件。

如何呈現利率決策卡片?

使用 central_banks 分組,或者呼叫某家央行的政策路徑,即可在一個回應中得到每次已有定價的會議的降息、維持不變和升息賠率。聯準會的例子見如何解讀聯準會利率賠率。

發布於 。

後續步驟