해외선물 거래시간과 서머타임, 코드로 처리하는 법 (CME 세션·주말·휴장)

해외선물 플랫폼을 만들면서 제일 처음 틀렸던 게 거래시간이었습니다. "나스닥 선물은 월요일 아침 7시에 열린다"를 그대로 코드에 넣었더니, 11월 첫 주가 지나자 개장 시각이 한 시간씩 어긋났습니다. 미국 서머타임이 끝났기 때문입니다. 이 글은 해외선물 거래시간을 코드로 다룰 때 지켜야 할 원칙과, 실제로 쓰는 판정 함수를 정리한 것입니다.

결론부터: 한국시간으로 저장하지 않는다

거래시간은 거래소 현지 시간 + 시간대 이름으로 저장하고, 화면에 보여 줄 때만 한국시간으로 바꿉니다.

  • 나쁜 예: open_kst = "07:00"
  • 좋은 예: tz = "America/Chicago", open = "17:00"

한국은 서머타임이 없어서 KST로 저장하면 1년에 두 번 전부 틀어집니다. 거래소 규정 자체가 현지 시각 기준으로 쓰여 있으니, 규정 그대로 저장하는 것이 가장 덜 틀립니다.

CME 해외선물 거래시간 (나스닥·S&P·금·원유)

나스닥100, S&P500, 금, 원유 같은 CME 계열 주요 선물은 거의 같은 틀을 씁니다. CME 공식 기준은 시카고 시간(CT)입니다.

  • 개장: 일요일 17:00 CT
  • 매일 휴식: 월~목 16:00~17:00 CT (1시간)
  • 마감: 금요일 16:00 CT
  • 토요일: 종일 휴장

이걸 한국시간으로 바꾸면 계절에 따라 달라집니다.

구분미국 서머타임 기간미국 표준시 기간
주간 개장월 07:00월 08:00
매일 휴식06:00~07:0007:00~08:00
주간 마감토 06:00토 07:00

그래서 "해외선물 거래시간 주말"을 물으면 답은 토요일 새벽 마감부터 월요일 아침 개장까지 휴장입니다. 2026년 미국 서머타임은 3월 8일에 시작해서 11월 1일에 끝납니다.

판정 함수

현재 시각을 받아서 개장, 휴식, 휴장 중 하나를 돌려주는 함수입니다. 핵심은 먼저 거래소 시간대로 바꾼 다음 판단한다는 것 하나입니다. 서머타임 계산은 표준 라이브러리 zoneinfo가 알아서 합니다.

from datetime import datetime, time, timezone
from zoneinfo import ZoneInfo

CT = ZoneInfo("America/Chicago")

def cme_status(now_utc: datetime) -> str:
    t = now_utc.astimezone(CT)      # 거래소 현지 시각으로 변환
    wd, hm = t.weekday(), t.time()  # 월=0 ... 일=6

    if wd == 5:                     # 토요일 종일 휴장
        return "closed"
    if wd == 6:                     # 일요일은 17:00 CT 부터 개장
        return "open" if hm >= time(17) else "closed"
    if wd == 4 and hm >= time(16):  # 금요일 16:00 CT 주간 마감
        return "closed"
    if time(16) <= hm < time(17):   # 월~목 매일 1시간 휴식
        return "break"
    return "open"

print(cme_status(datetime.now(timezone.utc)))

한국시간으로 개장 시각을 보여 주고 싶으면 반대로 변환만 하면 됩니다.

from datetime import datetime
from zoneinfo import ZoneInfo

open_ct = datetime(2026, 11, 8, 17, 0, tzinfo=ZoneInfo("America/Chicago"))
print(open_ct.astimezone(ZoneInfo("Asia/Seoul")))  # 2026-11-09 08:00 (월)

서버 시계는 UTC로 두고, 입력은 항상 UTC로 받는 것을 추천합니다. 서버 시간대가 섞이면 같은 코드가 서버마다 다르게 동작합니다.

함정: 미국과 유럽의 서머타임은 날짜가 다르다

여러 거래소 종목을 같이 다루면 이 부분에서 한 번 더 틀립니다. 미국과 유럽은 서머타임 시작일과 종료일이 다릅니다.

  • 미국: 3월 둘째 일요일 ~ 11월 첫째 일요일 (2026년 3/8 ~ 11/1)
  • 유럽: 3월 마지막 일요일 ~ 10월 마지막 일요일 (2026년 3/29 ~ 10/25)

그래서 2026년 10월 25일부터 11월 1일까지 한 주 동안은 유럽만 표준시로 돌아간 상태입니다. 이 기간에 독일 DAX 현물장 개장(09:00 현지)은 한국시간 16:00에서 17:00으로 바뀌지만, CME 개장은 아직 07:00 그대로입니다. 봄에도 3월 8일부터 29일까지 3주 동안 비슷하게 어긋납니다.

두 거래소의 시차를 "항상 몇 시간"으로 박아 두면 이 기간에만 틀리고, 1년에 몇 주뿐이라 테스트에서 잘 안 잡힙니다. 종목마다 자기 시간대를 들고 있으면 이 문제는 저절로 사라집니다.

서머타임이 없는 거래소도 섞인다

홍콩 항셍 선물처럼 서머타임이 없는 거래소도 있습니다. 항셍 선물 주간 세션은 현지 기준 09:15~12:00, 13:00~16:30이고 점심 휴식이 있습니다. 홍콩은 한국보다 1시간 늦으니 한국시간으로는 10:15~13:00, 14:00~17:30입니다. 야간 세션도 따로 있습니다.

즉 세션은 "하루 한 구간"이 아니라 여러 구간의 목록으로 저장해야 합니다.

SESSIONS = {
    "NQ":  {"tz": "America/Chicago", "rule": "cme_globex"},
    "HSI": {"tz": "Asia/Hong_Kong",
            "day": [("09:15", "12:00"), ("13:00", "16:30")],
            "night": [("17:15", "03:00")]},  # 자정을 넘는 구간
}

자정을 넘는 구간(17:15~03:00처럼 끝이 시작보다 작은 경우)은 "시작 이후이거나 끝 이전"으로 판정해야 합니다. 이걸 빼먹으면 야간 세션 절반이 휴장으로 나옵니다.

휴장일과 조기 마감은 별도 테이블

미국 공휴일에는 휴장하거나 정오에 조기 마감합니다. 추수감사절 다음 날처럼 짧게 열리는 날도 있습니다. 이건 규칙으로 계산하지 말고 거래소가 매년 공지하는 휴장 일정을 테이블로 넣는 편이 안전합니다.

CREATE TABLE market_holidays (
  exchange   VARCHAR(16) NOT NULL,
  day        DATE        NOT NULL,   -- 거래소 현지 날짜
  kind       VARCHAR(16) NOT NULL,   -- 'closed' | 'early_close'
  close_at   TIME        NULL,       -- 조기 마감 시각(현지)
  PRIMARY KEY (exchange, day)
);

판정 함수는 세션 규칙보다 이 테이블을 먼저 봅니다. 관리자 화면에서 운영자가 직접 추가할 수 있게 해 두면 연말에 개발자를 부를 일이 없습니다.

화면 표시: 휴장인지 피드 장애인지 구분

마지막으로, 시세가 멈췄을 때 그게 휴장인지 시세 장애인지 구분해 줘야 합니다. 세션 판정 결과와 마지막 시세 수신 시각을 같이 봅니다.

  • 세션이 closed 또는 break: "장 마감" 또는 "휴식 중" 표시, 주문 차단
  • 세션이 open인데 마지막 시세가 몇 분 이상 없음: "시세 지연" 표시
  • 세션이 open이고 시세가 들어옴: 정상

이 구분이 없으면 휴식 시간마다 "왜 가격이 안 움직이냐"는 문의를 받게 됩니다.

정리

  • 거래시간은 거래소 현지 시각 + 시간대 이름으로 저장하고, KST 변환은 화면에서만 합니다.
  • CME 주요 선물은 일요일 17:00 CT 개장, 평일 16:00~17:00 CT 휴식, 금요일 16:00 CT 마감입니다. 한국시간으로는 서머타임 기간 월 07:00, 표준시 기간 월 08:00 개장입니다.
  • 미국과 유럽의 서머타임 날짜가 달라서 봄 3주, 가을 1주는 두 거래소 시차가 바뀝니다.
  • 세션은 여러 구간 목록으로, 휴장일은 별도 테이블로 관리합니다.
  • 휴장과 시세 장애를 화면에서 구분합니다.
profile
거래소 및 AI 자동화 시스템 개발 노트

0개의 댓글