リスクを減らすデスク、ジョブを止めるオンコールのエンジニア、スタッフに状況を伝えるシフトリーダーは、発表の前に同じ情報を必要とします。UTC と現地の時刻、対象期間、前回値です。Narwhal の経済カレンダーはこの 4 つをすべて返し、短い定期実行スクリプトで 1 件につき 1 行のメッセージにできます。
発表前アラートに必要な情報
主要な数字の発表前には、デスクがリスクを減らし、オンコールのエンジニアがバッチジョブを止め、シフトリーダーがスタッフに状況を伝えます。3 者が頼りにするのは同じ事実です。発表がいつか、どの期間が対象か、前回の数字は何だったか。別の都市にいるスタッフは自分の時間帯の時刻も必要です。「13:30 UTC」というメッセージでは、慌ただしい中で時差の計算をさせてしまいます。GET /v1/economics/calendar はこれらの事実をすべて返します。このリクエストは、11月10日の米国を求めています。
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 行で出力します。
- デスクのタイムゾーンと国を設定する
DESK_TZはスタッフがメッセージを読むタイムゾーンで、COUNTRIESはデスクが取引対象にしている、または依存している経済圏のリストです。 - 余裕を持たせた日付の範囲を指定する 日付フィルターは各発表機関の現地の日付に従うため、スクリプトは今日の 1 日前から 2 日後までを指定し、
at自体で絞り込みます。 - これから先の発表だけを残す 発表を残す条件は、status が
scheduledであること、atの時刻があること、その時刻が現在から先行時間の間に入っていることです。NOWは任意の変数で、時計を固定してテストできます。 - 時刻を変換して前回値を添える
astimezoneは UTC の時刻をデスクのタイムゾーンに変換するので、どちらかの地域で時計が切り替わっても、手作業のオフセットは要りません。前回値はvaluesから取ります。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 の値で行をグループ化できます。
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 で決めます。
公開。