向客户和交易员展示降息、维持与加息的概率

利率概率展示需要三样东西:每次会议降息、不变、加息的百分比,这些价格形成的时间,以及客户能正确理解的措辞。Narwhal 按会议返回概率,并附带 as_of 时间,本页介绍展示规则。

请求一次路径,并显示定价时间

展示利率概率的产品在做设计之前就有两个问题。数字会变动,页面加载时正确的内容,一小时后可能就不对了。一次请求即可返回某家央行所有已定价的会议,以及报价的获取时间。这里请求的是美联储,并只保留前两次会议。

curl,美联储政策利率路径
curl -s -H "Authorization: Bearer $NARWHAL_API_KEY" \
  "https://api.narwhalapi.com/v1/predictions/policy-paths/federal-reserve"
响应,前两次会议
{
  "as_of": "2026-11-03T03:12:00Z",
  "meetings": [
    {
      "event_id": "usa-fed-2026-12",
      "p_cut": "0.0096",
      "p_hold": "0.2533",
      "p_hike": "0.7371",
      "expected_change_bps": "18.6",
      "cumulative_change_bps": "18.6",
      "resolves_at": "2026-12-09T19:00:00Z"
    },
    {
      "event_id": "usa-fed-2027-01",
      "p_cut": "0.0280",
      "p_hold": "0.7055",
      "p_hike": "0.2665",
      "expected_change_bps": "6.0",
      "cumulative_change_bps": "24.6",
      "resolves_at": "2027-01-27T19:00:00Z"
    }
  ]
}

p_cut、p_hold 和 p_hike 是介于 0 和 1 之间的十进制字符串,每次会议三者之和为 1。resolves_at 是决议时间。as_of 是报价时间,也是应该显示在界面上的时间,而不是你的服务器发出请求的时间。

把字段变成客户能正确理解的句子

像 73.71% 这样的数字读起来像预测。有四条规则可以让界面保持诚实。取整到整数百分比。让三个数字之和为 100。称其为交易者所定价的概率。在旁边打印时间。脚本应用了前两条规则并生成这一行文字。直接使用 round 会让 1 月 27 日的会议显示 27%、71% 和 3%,总和为 101,因此脚本把多出的一个百分点分给小数部分最大的数字。

python,接下来几次会议的展示行
import json, os, urllib.request
from datetime import datetime, timezone
from decimal import Decimal

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 whole_percent(odds):
    """Round to whole percents that add up to 100 (largest remainder)."""
    raw = {k: v * 100 for k, v in odds.items()}
    out = {k: int(v) for k, v in raw.items()}
    for k in sorted(raw, key=lambda k: raw[k] - out[k], reverse=True)[:100 - sum(out.values())]:
        out[k] += 1
    return out

path = get("/v1/predictions/policy-paths/federal-reserve")
as_of = datetime.fromisoformat(path["as_of"].replace("Z", "+00:00"))
age = int((datetime.now(timezone.utc) - as_of).total_seconds() // 60)
for m in path["meetings"][:3]:
    day = datetime.fromisoformat(m["resolves_at"].replace("Z", "+00:00"))
    p = whole_percent({k: Decimal(m["p_" + k]) for k in ("cut", "hold", "hike")})
    print(f"{day.day} {day:%B}: {p['hike']}% rise, {p['hold']}% no change, {p['cut']}% cut")
print(f"Market prices as of {as_of:%H:%M} UTC, {age} min old")
产出
9 December: 74% rise, 25% no change, 1% cut
27 January: 27% rise, 70% no change, 3% cut
17 March: 50% rise, 44% no change, 6% cut
Market prices as of 03:12 UTC, 0 min old
字段面向客户的措辞
p_hike加息的可能性
p_hold利率维持不变的可能性
p_cut降息的可能性
as_of价格时间,按客户所在时区显示
expected_change_bps面向交易室:市场定价的平均变动幅度,单位为基点

这些是合约价格,所以要写明这是市场概率。避免使用“美联储将会”之类的措辞。对于交易室,expected_change_bps 和 cumulative_change_bps 以基点给出每次会议的平均变动幅度和累计总和。

按你选择的频率刷新展示

Narwhal 在被请求时才回答,因此由产品决定多久请求一次。按你自己的间隔获取,把最近一次成功的响应放进缓存,让每次页面访问都读取缓存。绘制前先把 as_of 与当前时间比较。脚本会打印以分钟计的时长,当时长超过业务设定的上限时,产品可以显示提示或隐藏卡片。

政策路径只带有 as_of。对于单次会议,GET /v1/predictions/scalar/{event_id} 还会提供 status 和 stale 标记,确认步骤可以借此检查卡片是否仍然有效。请丢弃 resolves_at 已经过去的行。

请缓存响应,避免用户流量直接打到 API。关于重试规则,请参阅指南缓存响应并处理 429 错误。

为什么取整后的概率有时加起来是 99 或 101?

因为每个数字是单独取整的。在 1 月 27 日的会议上,取整前的概率是加息 26.65、维持 70.55、降息 2.80。分别取整得到 27、71 和 3,总和是 101。脚本中的最大余数步骤会把缺少的点数加到余数最大的数字上,得到 27、70 和 3。

界面上可以称之为预测吗?

这些概率是 Kalshi 和 Polymarket 上交易的合约价格,以概率形式显示。Narwhal 不做预测。请把卡片措辞为市场概率,显示时间,并注明合约的来源。受监管产品的措辞是否需要审核,由公司自行决定。

这个展示可以覆盖哪些央行?

请求 GET /v1/predictions/topics?group=central_banks 获取决议市场。列表为每家银行提供一个主题,例如美联储、澳大利亚储备银行、日本央行和印度尼西亚银行,并带有下一次会议的 next_event_id。venues 字段因主题而异。印度尼西亚银行只列出 Kalshi,而美联储列出 Kalshi 和 Polymarket。政策路径支持 federal-reserve、european-central-bank、bank-of-japan、bank-of-canada、reserve-bank-of-australia、bank-of-england 和 bank-indonesia。

路径包含多少次会议?

在上面的运行中,美联储路径包含从 2026 年 12 月到 2027 年的八次会议,每一行都有自己的 resolves_at。脚本显示了三次。更长的图表可以绘制所有行,cumulative_change_bps 给出平均变动幅度的累计总和。指南如何解读美联储利率概率解释了每个字段。

发布于。

后续步骤