在兩個國家之間交割交易的券商後台,必須把交割日放在兩國都營業的一天,所以每種貨幣對應國家的假日都會讓日期順延。Narwhal 會回傳每個國家的國定假日,並附上適用範圍和行政區劃;一個簡短的腳本就能把整份交易清單對照兩套日曆,並標出所有與單純按平日計算結果不同的交易。
跨境交易為什麼需要兩套假日日曆
交割 USD/JPY 交易的券商後台,需要找到日本和美國都營業的一天。只要期間內任一國家有假日,只按平日計數就會出錯,而差一天的交割指示要麼失敗,要麼延遲送達。假日端點一次只回答一個國家,所以後台要對每一條腿分別請求,再合併結果。下面的請求詢問日本在 2026 年 11 月 23 日是否有假日。
curl -s -H "Authorization: Bearer $NARWHAL_API_KEY" \
"https://api.narwhalapi.com/v1/calendars/holidays/JPN/on/2026-11-23"{
"country": "JPN",
"coverage": [
{
"scope": "national_public",
"subdivision_codes": []
}
],
"holidays": [
{
"date": "2026-11-23",
"name": "Labor Thanksgiving Day",
"holiday_key": "labor_thanksgiving_day",
"local_name": "勤労感謝の日",
"scope": "national_public",
"subdivision_codes": []
}
]
}回傳的項目是 Labor Thanksgiving Day,scope 為 national_public,subdivision_codes 清單為空表示全國適用。對美國 11 月 26 日送出同樣的請求,會回傳 scope 為 federal_government 的 Thanksgiving Day。每個國家的清單都有自己的 scope,所以後台要記錄自己依據的是哪一份清單。只按平日計數的話,11 月 23 日週一仍會被當作交割日。
讓交易清單對照兩套日曆
腳本依每筆交易兩種貨幣所屬國家的日曆來交割,並把僅按平日計數得到的日期與實際日期並排列出。兩者不同的交易會標記為 CHECK,這就是營運主管要覆核的清單。
- 指定每條腿所屬的國家
JPY列出日本和美國,GBP列出英國(交易台所在的行政區劃為GB-ENG)和美國。 - 每年只載入一次
holidays取得一個國家某一年的清單並快取起來,所以幾百筆交易的清單也只需送出寥寥幾次請求。臨近 12 月 31 日的交易,在逐日推進到下一年時才會載入下一年的資料。 - 跳過週末和任一國家的休市日
closures回傳落在所列任一國家當天的假日,只有這份清單為空的日子才計入 N 天。帶有行政區劃清單的假日,只有當交易台所在的區劃在清單中時才會讓交易台休市。import os from datetime import date, timedelta from functools import cache import requests HEADERS = {"Authorization": f"Bearer {os.environ['NARWHAL_API_KEY']}"} @cache def holidays(country, year): r = requests.get( f"https://api.narwhalapi.com/v1/calendars/holidays/{country}/{year}", headers=HEADERS, timeout=10, ) r.raise_for_status() return r.json()["holidays"] def closures(day, places): out = [] for country, region in places.items(): for h in holidays(country, day.year): # an empty subdivision list means the holiday applies nationwide if h["date"] == day.isoformat() and (not h["subdivision_codes"] or region in h["subdivision_codes"]): out.append(f"{country} {h['name']}") return out def settle(trade, n, places): day, held = trade, [] while n > 0: day += timedelta(1) if day.weekday() >= 5: continue shut = closures(day, places) if shut: held.append(f"{day:%d %b} {'; '.join(shut)}") else: n -= 1 return day, held JPY = {"USA": None, "JPN": None} GBP = {"GBR": "GB-ENG", "USA": None} # country -> subdivision of the desk blotter = [ ("USD/JPY", date(2026, 11, 20), 2, JPY), ("USD/JPY", date(2026, 11, 24), 2, JPY), ("GBP/USD", date(2026, 12, 23), 2, GBP), ] for pair, trade, n, places in blotter: day, held = settle(trade, n, places) plain, _ = settle(trade, n, {}) flag = "CHECK" if day != plain else "same" print(f"{pair} {trade} T+{n} settles {day}, weekdays only {plain} [{flag}]", "; ".join(held))
USD/JPY 2026-11-20 T+2 settles 2026-11-25, weekdays only 2026-11-24 [CHECK] 23 Nov JPN Labor Thanksgiving Day
USD/JPY 2026-11-24 T+2 settles 2026-11-27, weekdays only 2026-11-26 [CHECK] 26 Nov USA Thanksgiving Day
GBP/USD 2026-12-23 T+2 settles 2026-12-29, weekdays only 2026-12-25 [CHECK] 25 Dec GBR Christmas Day; USA Christmas Day; 28 Dec GBR Boxing Day第一筆交易在 11 月 20 日週五,僅按平日計算會在 11 月 24 日週二交割。由於日本 11 月 23 日週一休市,第二天順延到 11 月 25 日週三。第二筆交易被美國的 Thanksgiving Day 順延,第三筆則因兩國的 Christmas Day 以及英國的 Boxing Day 順延到 12 月 28 日週一。這份清單中的每一行都與單純按平日計算的結果不同。
後台仍需人工核對的事項
| 檢查 | 來源 |
|---|---|
| 週末 | 跳過週六和週日的迴圈 |
| 各貨幣所屬國家的國定假日 | 假日端點,每條腿查一個國家 |
| 交易台所在地區的地區性假日 | 將 subdivision_codes 與交易台的行政區劃比對 |
| 交易所或支付系統的休市日 | 把該場所自己的清單加入迴圈檢查的集合 |
| 天數,T+1 還是 T+2 | 產品和交易場所的規則,API 不作規定 |
最後兩行仍由後台負責,因為假日清單屬於國家,而不屬於某個交易場所。
交易日期附近有休市日時提醒交易員
GET /v1/calendars/holidays/{country}/next?from_date=2026-11-20 會在 holiday 物件中回傳該日期當天或之後的第一個假日。日本回傳的是 11 月 23 日,美國回傳的是 11 月 26 日,兩者都落在 T+2 期間內。每次登錄交易時,對每條腿各呼叫一次,並告知交易員即將有休市日。判斷日期本身時,請使用整年的清單。
這份清單與交易所或支付系統的日曆一致嗎?
它列出一個國家的假日,附上適用範圍和行政區劃;只在交易所或支付系統存在的休市日不在其中。2026 年的美國清單有 11 個項目,其中沒有 4 月 3 日的 Good Friday,而部分交易所在這一天休市。請把交易場所的休市日加入迴圈檢查的集合。
某個國家當年沒有日曆時會怎樣?
API 會回傳 404 問題回應,代碼為 calendar_not_published。英國 2028 年的請求就是這樣。raise_for_status() 會讓腳本停下,對於不容出錯的指示,這是安全的行為。請決定是退回到按平日計算並標記該日期,還是等待。
貨幣對應當跳過哪些日子?
任一國家休市的日子都要跳過。USD/JPY 交易要等到東京和美國都營業的一天。T+1 還是 T+2,以及中間那一天有無例外,都由市場規則決定,API 不會給出,所以請核對產品的慣例。
發布於 。