向交易台或值班团队发送数据发布前提醒

要减仓的交易台、要暂停任务的值班工程师、要向同事通报情况的班组长,在数据公布前需要的信息是一样的:UTC 时间和当地时间、所属周期以及前值。Narwhal 经济日历会返回这四项,再用一个简短的定时脚本,就能为每次发布生成一行消息。

发布前提醒需要包含什么

在重要数据公布前,交易台要降低风险,值班工程师要暂停批处理任务,班组长要向同事通报情况。三者依据的是同样的事实:数据何时公布、涵盖哪个周期、上一次的数值是多少。身处其他城市的同事还需要自己时区的时间,因为只写“13:30 UTC”的消息会让他们在紧张时还要自己换算。GET /v1/economics/calendar 会返回这些事实。这个请求获取美国在 11 月 10 日的数据。

curl,某一天的美国数据发布
curl -s -H "Authorization: Bearer $NARWHAL_API_KEY" \
  "https://api.narwhalapi.com/v1/economics/calendar?countries=USA&start_date=2026-11-10&end_date=2026-11-10&limit=100"
响应
{
  "releases": [
    {
      "release_id": "66f7f9f6-0318-4f25-8896-541c428ee07e",
      "revision": 2,
      "country": "USA",
      "series_id": "usa-wages-and-earnings",
      "name": "Wages and earnings",
      "topic": "wages",
      "family": "labour",
      "period": "2026-10",
      "status": "scheduled",
      "at": "2026-11-10T13:30:00Z",
      "timezone": "America/New_York",
      "values": [
        {
          "measure": "real_average_hourly_earnings_mom",
          "concept": "real_average_hourly_earnings",
          "unit": "percent",
          "transformation": "month_over_month",
          "previous": "-0.5"
        },
        {
          "measure": "real_average_hourly_earnings_yoy",
          "concept": "real_average_hourly_earnings",
          "unit": "percent",
          "transformation": "year_over_year",
          "previous": "-0.7"
        }
      ]
    },
    {
      "release_id": "f01e2289-2e17-49b3-9d64-d29118742dee",
      "revision": 3,
      "country": "USA",
      "series_id": "usa-consumer-prices",
      "name": "Consumer prices",
      "topic": "consumer_prices",
      "family": "prices",
      "period": "2026-10",
      "status": "scheduled",
      "at": "2026-11-10T13:30:00Z",
      "timezone": "America/New_York",
      "values": [
        {
          "measure": "core_cpi_yoy",
          "concept": "core_cpi",
          "unit": "percent",
          "transformation": "year_over_year",
          "previous": "2.6",
          "not_seasonally_adjusted": true
        },
        {
          "measure": "cpi_mom",
          "concept": "cpi",
          "unit": "percent",
          "transformation": "month_over_month",
          "previous": "0.6"
        },
        {
          "measure": "cpi_yoy",
          "concept": "cpi",
          "unit": "percent",
          "transformation": "year_over_year",
          "previous": "3.7",
          "not_seasonally_adjusted": true
        }
      ]
    }
  ],
  "next_cursor": null
}

at 是以 UTC 表示的发布时间。period 说明数据所属的月份,values[].previous 保存每项指标上一次公布的数值及其 unit。响应只列出前值,不含预测值,需要一致预期的交易台可从自己的数据源补充。在数据公布之前,status 始终为 scheduled。

为每次发布生成一行提醒

下面的脚本适合定时运行,例如每天早上一次,会为未来 24 小时内的每次发布各打印一行。

  1. 设置交易台时区和国家 DESK_TZ 是同事阅读消息所用的时区,COUNTRIES 列出交易台所交易或依赖的经济体。
  2. 请求带余量的日期窗口 日期过滤依据各发布机构的当地日期,所以脚本请求的范围是从今天的前一天到后两天,再按 at 本身过滤。
  3. 只保留尚未到来的发布 保留一次发布的条件是:状态为 scheduled,有 at 时间,且该时间落在现在到提前量之间。NOW 是可选变量,用来以固定时钟进行测试。
  4. 转换时间并附上前值 astimezone 会把 UTC 时间转换成交易台的时区,所以任何一边调整了时钟,都不需要手工计算偏移。前值来自 values。
    Python,发布前提醒的一行
    import os
    from datetime import datetime, timedelta, timezone
    from zoneinfo import ZoneInfo
    import requests
    
    DESK_TZ = ZoneInfo("Europe/Zurich")
    COUNTRIES = ["USA", "EMU"]
    LEAD = timedelta(hours=24)
    now = datetime.fromisoformat(os.environ["NOW"]) if "NOW" in os.environ else datetime.now(timezone.utc)
    
    r = requests.get(
        "https://api.narwhalapi.com/v1/economics/calendar",
        params={
            "countries": COUNTRIES,
            "start_date": (now - timedelta(days=1)).date().isoformat(),
            "end_date": (now + timedelta(days=2)).date().isoformat(),
            "limit": 100,
        },
        headers={"Authorization": f"Bearer {os.environ['NARWHAL_API_KEY']}"},
        timeout=10,
    )
    r.raise_for_status()
    
    due = []
    for x in r.json()["releases"]:
        if x["status"] != "scheduled" or "at" not in x:
            continue
        at = datetime.fromisoformat(x["at"].replace("Z", "+00:00"))
        if now <= at < now + LEAD:
            due.append((at, x))
    
    for at, x in sorted(due, key=lambda t: t[0]):
        prev = ", ".join(f"{v['measure']} {v['previous']}" for v in x["values"] if "previous" in v)
        print(f"{at:%H:%M} UTC / {at.astimezone(DESK_TZ):%H:%M} {DESK_TZ.key} | "
              f"{x['country']} {x['name']} {x.get('period', '-')} | previous: {prev or 'none listed'}")

把 NOW 设为 11 月 10 日 09:00 UTC 后,脚本打印了两行。那天苏黎世比 UTC 早一小时,所以 13:30 UTC 显示为 14:30。两项美国数据的发布时间相同,想只发一条消息的交易台可以按 at 值对这些行分组。

NOW 设为 2026-11-10T09:00:00+00:00 时的输出
13:30 UTC / 14:30 Europe/Zurich | USA Wages and earnings 2026-10 | previous: real_average_hourly_earnings_mom -0.5, real_average_hourly_earnings_yoy -0.7
13:30 UTC / 14:30 Europe/Zurich | USA Consumer prices 2026-10 | previous: core_cpi_yoy 2.6, cpi_mom 0.6, cpi_yoy 3.7

让提醒匹配阅读它的人

阅读者发布前的动作提醒需要的内容
交易员减仓或对冲UTC 和当地时间、前值
值班工程师在该分钟前后暂停部署或批处理任务确切的 at 时间,以及用来确认仍按计划进行的 status
班组长向同事通报即将发生的事发布名称、period 和前值

把这些行发到团队已经在看的渠道即可。API 提供事实,发送则交给你自己的聊天或邮件工具。像安排每日数据拉取那样用调度器运行脚本,运行频率至少要和你想要的提前量一样高。

在发布时间变动时保持提醒准确

发出早间清单之后,发布时间可能会变。每个日历条目都有一个 revision,详情变化时它会递增,所以在发布前不久重新读取日历的脚本,可以把当前 revision 与已发送的 revision 对比。如果要推送方式,Webhook 会报告 release.scheduled、release.rescheduled 和 release.cancelled,见接收 Webhook。Webhook 在日程变动时到达,不带倒计时,所以提前量仍由你自己的定时器决定。

只想要手机提醒的同事,可以让日历应用订阅通过 POST /v1/calendars/subscriptions 创建的订阅源。请求需要 countries、start_date 和 end_date,响应里的 url 只返回一次,请当作密钥保存。这个调用会创建资源,所以本页只做说明而不运行。完整请求见日历订阅文档。

如果发布还没有确切时间怎么办?

有些发布带的是 date、between 或 by,而不是 at。脚本无法把它们放到具体的钟点上,所以会跳过。可以把它们列在单独的早间备注里,让交易台知道有的发布可能没有固定的分钟。

API 能自己发送提醒吗?

没有任何端点会按时间发送提醒。提醒来自日历应用、你自己的定时脚本,或者一个会启动自有定时器的 Webhook 接收端。

为什么脚本要请求今天前后的日期?

日期窗口依据发布机构的当地日期。东京或悉尼的发布,其日历日期可能与 UTC 时间不同,所以请求时要放宽范围,由 at 决定哪些发布到期。

发布于。

后续步骤