영업일 계산으로 두 나라 공휴일이 다른 국경 간 거래의 결제일 구하기

두 나라에 걸친 거래를 결제하는 증권사 백오피스는 양국이 모두 영업하는 날에 결제해야 하므로 통화별 공휴일에 따라 날짜가 밀립니다. Narwhal은 국가별 공휴일을 적용 범위와 하위 지역 정보와 함께 돌려주며, 짧은 스크립트로 거래 목록 전체를 두 달력에 대조해 평일 계산과 날짜가 다른 거래를 모두 표시할 수 있습니다.

국경 간 거래에 공휴일 달력이 두 개 필요한 이유

USD/JPY 거래를 결제하는 증권사 백오피스는 일본과 미국이 모두 문을 여는 날을 찾아야 합니다. 기간 안에 어느 한 나라라도 공휴일이 있으면 평일만 세는 방식은 틀리고, 하루 어긋난 결제 지시는 실패하거나 늦게 도착합니다. 공휴일 엔드포인트는 한 번에 한 나라씩 응답하므로 백오피스는 각 레그를 따로 조회해 결과를 합칩니다. 이 요청은 일본에 2026년 11월 23일 공휴일이 있는지 묻습니다.

curl, 하루 날짜의 일본 공휴일
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 표시가 붙으며, 이것이 운영 책임자가 검토하는 목록입니다.

  1. 각 레그의 나라 지정하기 JPY에는 일본과 미국을, GBP에는 영국(데스크의 하위 지역 GB-ENG)과 미국을 지정합니다.
  2. 연도별로 한 번만 불러오기 holidays는 한 나라의 연도별 목록을 가져와 보관하므로, 수백 건의 거래가 있어도 요청은 몇 번뿐입니다. 12월 31일 근처의 거래는 날짜를 따라가다 다음 해에 닿을 때 다음 해 목록을 불러옵니다.
  3. 주말과 어느 한 나라의 휴장일 건너뛰기 closures는 나열된 어느 나라에서든 해당 날짜에 걸리는 공휴일을 돌려주며, 이 목록이 비어 있는 날만 N일 계산에 들어갑니다. 하위 지역 목록이 있는 공휴일은 그 지역이 목록에 있을 때만 데스크를 쉬게 합니다.
    Python, 두 통화쌍의 결제 거래 목록
    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는 코드가 calendar_not_published인 404 문제 응답을 돌려줍니다. 영국의 2028년 요청이 그랬습니다. raise_for_status()가 스크립트를 멈추는데, 잘못된 지시가 나가면 안 되는 상황에서는 이것이 안전한 동작입니다. 평일 계산으로 대체하고 날짜에 표시를 할지, 아니면 기다릴지 정하세요.

통화쌍은 어떤 날을 건너뛰어야 합니까?

어느 한 나라라도 쉬는 날은 건너뜁니다. USD/JPY 거래는 도쿄와 미국이 모두 문을 여는 날까지 기다립니다. T+1인지 T+2인지, 중간 날짜의 예외는 시장 규칙에서 나오며 API가 알려 주지 않으므로 상품별 관행을 확인하세요.

에 게시되었습니다.

다음 단계