한 나라의 경제 캘린더를 읽어 거래하는 주제의 발표만 남기고 at 타임스탬프로 정렬합니다. 각 항목에는 UTC 발표 시간, 발표 기관의 시간대, 수치가 다루는 기간, 지표별 직전 값이 들어 있어 트레이더는 무엇이 곧 발표되고 무엇과 비교되는지 알 수 있습니다.
한 나라의 지표 하나 조회하기
GET /v1/economics/calendar로 국가와 날짜를 지정해 캘린더를 요청합니다. 이 요청은 일본의 11월 20일을 조회합니다.
curl -s -H "Authorization: Bearer $NARWHAL_API_KEY" \
"https://api.narwhalapi.com/v1/economics/calendar?countries=JPN&start_date=2026-11-20&end_date=2026-11-20&limit=100"{
"releases": [
{
"release_id": "6c00d274-da35-4ed4-bcc1-574101544a03",
"revision": 3,
"country": "JPN",
"series_id": "jpn-consumer-prices",
"name": "Consumer prices",
"topic": "consumer_prices",
"family": "prices",
"period": "2026-10",
"status": "scheduled",
"at": "2026-11-19T23:30:00Z",
"timezone": "Asia/Tokyo",
"values": [
{
"measure": "core_core_cpi_yoy",
"concept": "cpi_ex_fresh_food_energy",
"unit": "percent",
"transformation": "year_over_year",
"previous": "2.4",
"not_seasonally_adjusted": true
},
{
"measure": "core_cpi_yoy",
"concept": "cpi_ex_fresh_food",
"unit": "percent",
"transformation": "year_over_year",
"previous": "2.1",
"not_seasonally_adjusted": true
},
{
"measure": "cpi_mom",
"concept": "cpi",
"unit": "percent",
"transformation": "month_over_month",
"previous": "0.4"
},
{
"measure": "cpi_yoy",
"concept": "cpi",
"unit": "percent",
"transformation": "year_over_year",
"previous": "2.1",
"not_seasonally_adjusted": true
}
]
}
],
"next_cursor": null
}이 발표는 period가 2026-10인 일본의 소비자물가이며, 수치는 10월분입니다. at은 2026-11-19T23:30:00Z이고 timezone은 Asia/Tokyo입니다. values의 각 항목에는 measure와 previous(직전 값)가 있으며, cpi_yoy의 직전 값은 2.1, cpi_mom의 직전 값은 0.4입니다. 수치는 문자열이므로 비교하기 전에 숫자로 변환하세요.
transformation은 수치가 어떻게 산출되는지 알려 줍니다. cpi_yoy는 year_over_year, cpi_mom은 month_over_month입니다. 네 가지 지표 중 세 가지에 not_seasonally_adjusted: true가 붙어 있으므로, 예상치와 직전 값을 비교하기 전에 이 플래그를 확인하세요.
요청은 11월 20일을 지정했지만 UTC로는 at이 11월 19일입니다. 날짜 범위는 발표 기관의 현지 달력을 따르며, UTC 23:30은 도쿄에서 다음 날 아침 08:30이기 때문입니다.
다음 주요 발표를 고르고 시간 변환하기
캘린더에는 중요도 등급이 없으므로 무엇을 주요 발표로 볼지는 직접 정합니다. 아래 스크립트는 topic 값의 관심 목록을 사용해, 아직 scheduled 상태이고 at 시간이 있는 발표만 남기고 정렬한 뒤 처음 세 건을 가져옵니다.
- 관심 목록과 나의 시간대 설정하기 거래하는 주제를 집합에 넣습니다. 스크립트는 소비자물가, GDP, 노동력, 고용, 임금을 지켜보고 트레이더의 시간대인
America/New_York으로 변환합니다. - 기간 요청하기 한 나라와 날짜 범위를 지정합니다. 스크립트는 일본의 11월 16일부터 29일까지를
limit100으로 가져옵니다. - 필터링, 정렬, 변환
datetime.fromisoformat이 UTC 타임스탬프를 읽습니다.astimezone은 이를timezone필드의 발표 기관 시간대와 트레이더의 시간대로 변환합니다. 직전 값은values[].previous에서 가져옵니다.import os from datetime import datetime from zoneinfo import ZoneInfo import requests BASE = "https://api.narwhalapi.com" WATCH = {"consumer_prices", "gdp", "labour_force", "employment", "wages"} MY_TZ = ZoneInfo("America/New_York") r = requests.get( f"{BASE}/v1/economics/calendar", params={"countries": "JPN", "start_date": "2026-11-16", "end_date": "2026-11-29", "limit": 100}, headers={"Authorization": f"Bearer {os.environ['NARWHAL_API_KEY']}"}, timeout=10, ) r.raise_for_status() picked = [ x for x in r.json()["releases"] if x.get("topic") in WATCH and x["status"] == "scheduled" and "at" in x ] for x in sorted(picked, key=lambda x: x["at"])[:3]: utc = datetime.fromisoformat(x["at"].replace("Z", "+00:00")) local = utc.astimezone(ZoneInfo(x["timezone"])) mine = utc.astimezone(MY_TZ) prev = ", ".join(f"{v['measure']} {v['previous']}" for v in x["values"] if "previous" in v) print(x["name"], x["period"]) print(" UTC ", utc.strftime("%a %d %b %H:%M")) print(" Tokyo", local.strftime("%a %d %b %H:%M")) print(" NYC ", mine.strftime("%a %d %b %H:%M")) print(" previous:", prev or "none listed")
GDP 2026-Q3
UTC Sun 15 Nov 23:50
Tokyo Mon 16 Nov 08:50
NYC Sun 15 Nov 18:50
previous: none listed
Consumer prices 2026-10
UTC Thu 19 Nov 23:30
Tokyo Fri 20 Nov 08:30
NYC Thu 19 Nov 18:30
previous: core_core_cpi_yoy 2.4, core_cpi_yoy 2.1, cpi_mom 0.4, cpi_yoy 2.1
Wages and earnings 2026-09
UTC Tue 24 Nov 23:30
Tokyo Wed 25 Nov 08:30
NYC Tue 24 Nov 18:30
previous: average_cash_earnings_yoy 3.9, real_wages_yoy 1.6GDP 행은 창이 11월 16일에 시작하는데도 UTC로는 Sun 15 Nov 23:50으로 표시됩니다. 도쿄에서는 11월 16일 월요일 08:50이기 때문입니다. 직전 값 줄에 「none listed」라고 나오는 것은 이 GDP 발표의 values가 빈 목록이기 때문입니다. 스크립트는 previous가 없을 때마다 자리 표시 문자열을 출력하므로 수치 하나가 없어도 반복이 멈추지 않습니다.
하나의 순간을 세 개의 시계로 보기
| 시계 | 소비자물가 발표 | 산출 방법 |
|---|---|---|
| UTC | 11월 19일(목) 23:30 | at 값 |
| 도쿄 | 11월 20일(금) 08:30 | at을 timezone 필드(Asia/Tokyo)로 변환 |
| 뉴욕 | 11월 19일(목) 18:30 | at을 트레이더의 시간대로 변환 |
도쿄는 UTC보다 9시간 빠르므로 23:30에 9시간을 더하면 다음 날 08:30입니다. 뉴욕은 그 날짜에 UTC보다 5시간 늦으므로 23:30에서 5시간을 빼면 18:30입니다. 스크립트는 서머타임 규칙을 알아서 적용하는 zoneinfo를 쓰므로 오프셋을 따로 저장할 필요가 없습니다.
나중에 같은 발표 다시 읽기
모든 발표에는 release_id가 있습니다. GET /v1/economics/calendar/{release_id}는 해당 발표 하나를 돌려주며 version과 observed_at 두 필드가 추가됩니다. observed_at은 Narwhal이 발표 기관의 캘린더에서 그 발표를 마지막으로 확인한 시각을 알려 줍니다. 창 전체를 내려받지 않고도 지켜보는 발표의 행을 갱신할 때 사용하세요.
status는 수치가 공개되면 scheduled에서 published로 바뀌고, 그러면 값에 previous와 함께 actual이 들어갈 수 있습니다. 일부 발표에는 flash, advance, preliminary, final 같은 stage도 있습니다. 첫 추정치를 확정치로 착각하지 않도록 이름 옆에 표시하세요.
캘린더가 발표를 중요도로 순위 매깁니까?
아니요. 발표에는 prices, labour, gdp 같은 family와 consumer_prices 같은 topic이 있을 뿐 등급은 없습니다. 이 두 필드로 관심 목록을 만들고, 일부 발표에는 topic이 없으므로 .get("topic")을 사용하세요.
왜 어떤 발표에는 직전 값이 없습니까?
values는 항상 있지만 빈 목록일 수 있고, 지표에 previous가 없을 수도 있습니다. 위의 일본 GDP 발표는 빈 목록이었습니다. 발표가 이전 수치를 수정하면 previous_revised_from에 대체된 수치가 들어 있습니다.
정확한 시간이 없는 발표는 어떻게 됩니까?
그런 발표에는 at이 없고 대신 date, between, by 중 하나가 들어 있습니다. 스크립트는 변환에 타임스탬프가 필요하므로 이런 항목을 건너뜁니다. 이런 행도 보고 싶다면 시간을 추측하지 말고 date를 출력하고 시간을 알 수 없음으로 표시하세요.
에 게시되었습니다.