トレーディングデスクやオンコールチームへ発表前アラートを送る

リスクを減らすデスク、ジョブを止めるオンコールのエンジニア、スタッフに状況を伝えるシフトリーダーは、発表の前に同じ情報を必要とします。UTC と現地の時刻、対象期間、前回値です。Narwhal の経済カレンダーはこの 4 つをすべて返し、短い定期実行スクリプトで 1 件につき 1 行のメッセージにできます。

発表前アラートに必要な情報

主要な数字の発表前には、デスクがリスクを減らし、オンコールのエンジニアがバッチジョブを止め、シフトリーダーがスタッフに状況を伝えます。3 者が頼りにするのは同じ事実です。発表がいつか、どの期間が対象か、前回の数字は何だったか。別の都市にいるスタッフは自分の時間帯の時刻も必要です。「13:30 UTC」というメッセージでは、慌ただしい中で時差の計算をさせてしまいます。GET /v1/economics/calendar はこれらの事実をすべて返します。このリクエストは、11月10日の米国を求めています。

curl、ある 1 日の米国の発表
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 のままです。

発表ごとに 1 行のアラートを作る

以下のスクリプトは、たとえば毎朝のように定期実行することを想定しており、今後 24 時間以内に予定されている発表を 1 件につき 1 行で出力します。

  1. デスクのタイムゾーンと国を設定する DESK_TZ はスタッフがメッセージを読むタイムゾーンで、COUNTRIES はデスクが取引対象にしている、または依存している経済圏のリストです。
  2. 余裕を持たせた日付の範囲を指定する 日付フィルターは各発表機関の現地の日付に従うため、スクリプトは今日の 1 日前から 2 日後までを指定し、at 自体で絞り込みます。
  3. これから先の発表だけを残す 発表を残す条件は、status が scheduled であること、at の時刻があること、その時刻が現在から先行時間の間に入っていることです。NOW は任意の変数で、時計を固定してテストできます。
  4. 時刻を変換して前回値を添える astimezone は UTC の時刻をデスクのタイムゾーンに変換するので、どちらかの地域で時計が切り替わっても、手作業のオフセットは要りません。前回値は values から取ります。
    Python、発表前アラートの 1 行
    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 に設定すると、スクリプトは 2 行を出力しました。その日付のチューリッヒは UTC より 1 時間進んでおり、そのため 13:30 UTC が 14:30 と表示されます。米国の 2 件の発表は同じ発表時刻なので、メッセージを 1 つにまとめたいデスクは、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 を送信時のものと比較できます。プッシュ方式では、Webhook が release.scheduled、release.rescheduled、release.cancelled を通知します。Webhook を受け取るを参照してください。Webhook はスケジュールが変わった時点で届き、カウントダウンは含みません。そのため、先行時間は自前のタイマーで決めます。

電話でのリマインダーだけを望むスタッフは、POST /v1/calendars/subscriptions で作成したフィードをカレンダーアプリに登録できます。リクエストには countries、start_date、end_date を渡し、レスポンスの url は一度しか返されないため、シークレットとして保管してください。この呼び出しは何かを作成するため、このページでは説明するだけで実行しません。リクエストの詳細はカレンダー購読のドキュメントにあります。

発表に正確な時刻がまだない場合は?

発表によっては、at の代わりに date、between、by が付くものがあります。スクリプトは時計上の位置を決められないため、これらをスキップします。別の朝のメモに分けて載せ、分単位で時刻が決まらないまま発表されることもあると、デスクに伝えてください。

API が自分でリマインダーを送ってくれますか?

時刻を指定して送るリマインダーのエンドポイントはありません。リマインダーは、カレンダーアプリ、自分のスケジュール実行スクリプト、または自前のタイマーを起動する Webhook の受け手から届きます。

スクリプトが今日の前後の日付を要求するのはなぜですか?

日付の範囲は発表機関の現地の日付に従います。東京やシドニーの発表は、UTC の時刻とは別の暦の日付になることがあるため、リクエストに余裕を持たせ、何が対象かは at で決めます。

公開。

次のステップ