Capital Markets and Settlement
What "today" means differs from system to system
한국어 원문으로 표시합니다.
한 줄 요약
거래일은 달력일이 아니고, 세션은 시장마다 다르며, 서머타임이 있는 시장에서는 같은 지역시가 두 번 나오거나 아예 없다. 이 셋을 고정 오프셋으로 뭉개 놓으면 한 해에 두 번, 전환 주말마다 조용히 틀린다.
왜 이게 필요했나
시각을 다루는 코드는 대개 두 번 쓰인다. 처음 쓸 때는 잘 돌고, 전환 주말에 한 번 고쳐진다. 그 사이의 몇 달 동안 아무도 문제를 모르는 이유는, 틀린 값이 예외를 던지지 않고 그냥 한 시간 어긋난 채로 저장되기 때문이다.
자본시장에서 이 어긋남은 곧바로 돈과 보고에 닿는다. 마감 배치가 한 시간 일찍 돌면 그 사이의 체결이 다음 날로 밀리고, 대사는 어긋난 채로 맞춰진다. 그리고 시장마다 전환 날짜가 다르다. 미국 시장이 이미 여름 시각으로 옮겨 간 뒤에도 유럽 시장은 아직 겨울 시각인 몇 주가 해마다 있고, 그 몇 주 동안 두 시장의 마감 간격은 평소와 다르다. 이 사실을 시스템이 몰라도 되는 이유는 없다.
어떻게 동작하나
첫째, 오프셋이 아니라 규칙으로 바꾼다. 지역시를 UTC 로 바꾸는 일은 "아홉 시간을 뺀다" 가 아니다. 그 지역이 그 날짜에 어떤 규칙 아래 있었는지를 봐야 한다. 그 규칙의 원본은 IANA 시간대 데이터베이스이고, 파이썬에서는 zoneinfo가 그것을 읽는다. 이 모듈이 표준에 들어온 배경은 PEP 615에 적혀 있다. 고정 오프셋을 코드에 박으면 전환일 이후의 모든 기록이 한 시간씩 어긋난다.
둘째, 전환일에는 벽시계가 성립하지 않는 순간이 있다. 봄에 시계를 앞당기는 시장에서는 건너뛴 한 시간이 통째로 존재하지 않는다. 그 시각이 적힌 기록은 지역시로 읽을 수 없고, "일단 변환해서 저장" 하면 조용히 한 시간 뒤의 값이 된다. 가을에 되돌리는 시장에서는 같은 벽시계 값이 두 번 지나가므로, 그 시각만으로는 두 순간 중 어느 쪽인지 정할 수 없다. 파이썬은 이 두 번째 경우를 fold 속성으로 구분하지만, 어느 쪽을 쓸지는 업무가 정해야 하는 규칙이지 라이브러리가 정해 주는 것이 아니다.
셋째, 세션과 달력은 별도의 자료다. 정규장 앞뒤에 개장 전과 개장 후 구간이 있고, 반일장이 있고, 휴장일이 있다. 이것을 코드에 상수로 박으면 해가 바뀔 때마다 배포가 필요해진다. 달력을 자료로 두면 그 자료 자체를 검증할 수 있다는 이점도 생긴다. 반일장 마감이 정규 마감보다 늦게 적혀 있거나, 같은 날이 휴장일이면서 반일장으로도 적혀 있는 일은 실제로 일어난다.
넷째, 거래일은 라벨이다. 자정을 넘는 야간장에서 새벽 한 시의 체결은 달력으로는 오늘이지만 거래일로는 어제다. 이 라벨을 정하지 않으면 같은 체결이 어느 날의 집계에 들어갈지 시스템마다 달라지고, 대사는 영원히 맞지 않는다. 표기 자체의 규칙은 RFC 3339가 정하지만, 거래일을 무엇으로 볼지는 시장의 규칙이다.
현장에서 만나는 모습
가장 흔하게 보는 사고는 전환 주말 직후의 마감 배치다. 어떤 시장의 마감을 UTC 로 고정해 두면 전환 뒤에는 그 시장이 아직 열려 있는 시각에 배치가 돈다. 반대로 지역시로만 잡아 두면 다른 시장의 배치와 같은 순간에 겹쳐 두 작업이 같은 자원을 두고 부딪힌다. 실제로 두 시장의 마감이 여름 시각 동안 정확히 같은 UTC 시각에 놓이는 구간이 있고, 그 몇 주 동안만 배치가 밀린다.
두 번째로 흔한 것은 오프셋 없는 시각 문자열이다. 로그와 전문에 2025-03-30 01:30:00 만 적혀 있으면, 그것이 어느 시간대인지는 문서에서 가져와야 한다. 그리고 그 시각이 그 시간대에 존재하지 않을 수도 있다는 것까지 다뤄야 한다.
세 번째는 달력이 코드 안에 있는 경우다. 휴장일과 반일장을 상수로 박아 두면 해가 바뀔 때마다 배포가 필요하고, 급하게 고치다 보면 그 값이 어디에서 왔는지 아무도 모르게 된다. 달력을 자료로 빼 두면 그때부터 달력 자체를 검증할 수 있다. 같은 날이 휴장일이면서 반일장으로도 적혀 있거나, 반일장 마감이 정규 마감보다 늦게 적혀 있는 일은 실제로 일어나고, 그런 줄 하나가 그 날 하루의 집계를 통째로 바꾼다. 이 검증은 몇 줄이면 되는데, 달력이 코드 안에 있으면 그 몇 줄을 쓸 자리가 없다.
그리고 이 모든 처리에는 공통의 원칙이 하나 있다. 시각은 받는 즉시 한 번만 해석하고, 그 뒤로는 절대 시각으로만 다닌다. 지역시 문자열을 그대로 들고 다니며 필요할 때마다 해석하면, 같은 값이 시스템의 층마다 다르게 읽힌다. 화면에 보여 줄 때만 다시 지역시로 바꾸면 되고, 그때는 어느 시장의 지역시인지가 그 화면의 맥락에서 정해진다.
다음 실습에서 할 것
네 시장의 세션 정의와 달력, 서른 건의 체결을 만들고 시간대 규칙으로 UTC 로 바꿉니다. 고정 오프셋으로 바꾼 결과와 견주어 어긋난 날을 찾고, 전환일의 없는 시각과 두 번 있는 시각을 가른 뒤, 세션 구간과 거래일 라벨을 매깁니다. 마지막에 시장별 마감을 UTC 로 모아 배치 창이 겹치는 날을 찾고, 달력 자체의 모순 두 가지를 찾아냅니다.