Skip to content

Commit db1c3f9

Browse files
committed
fix: 달력 검증 도구가 장중 실행에서 오늘을 휴장으로 오판하던 문제
머지 직후 오늘 날짜까지 넣고 돌려 보니 2026-08-27을 휴장 오류로 잡았다. 장중(10:16)이라 지수 봉이 아직 안 올라왔을 뿐인데 '데이터 없음'을 '휴장'으로 읽었다. 데이터가 아직 없는 최근 날은 휴장이 아니라 모름이다. 확인 범위를 지수의 마지막 봉 날짜까지로 자르고, 어디까지 확인했는지 출력에 적는다. 없는 사실을 오류로 보고하지 않는 게 이 도구의 존재 이유다. 매일 오탐이 하나씩 뜨면 진짜 달력 오류가 묻힌다 — 이 저장소가 경보 위생으로 다섯 번 데인 그 패턴이다.
1 parent 6ff13e4 commit db1c3f9

2 files changed

Lines changed: 40 additions & 7 deletions

File tree

tests/test_snapshot_backfill.py

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -210,11 +210,31 @@ def test_verifier_reports_mismatch(self, monkeypatch):
210210
"""검증 도구가 불일치를 실제로 잡아내는가(달력이 맞아도 로직은 살아 있어야)."""
211211
import tools.verify_trading_calendar as v
212212

213-
# 시장은 6/1만 열렸다고 가정 — 나머지 평일은 전부 wrong_open이어야 한다
214-
monkeypatch.setattr(v, "market_open_days", lambda s, e, symbol=None: {date(2026, 6, 1)})
215-
r = v.compare(date(2026, 6, 1), date(2026, 6, 5))
216-
assert date(2026, 6, 1) not in r["wrong_open"]
217-
assert date(2026, 6, 2) in r["wrong_open"]
213+
# 6/8·6/10만 열렸다고 가정하면 그 사이 평일 6/9가 wrong_open으로 잡혀야 한다.
214+
# (6/3은 실제 휴장일로 등록돼 있어 대조 대상에서 제외 — 순수 로직만 본다)
215+
monkeypatch.setattr(
216+
v, "market_open_days",
217+
lambda s, e, symbol=None: {date(2026, 6, 8), date(2026, 6, 10)},
218+
)
219+
r = v.compare(date(2026, 6, 8), date(2026, 6, 12))
220+
assert date(2026, 6, 9) in r["wrong_open"]
221+
assert date(2026, 6, 8) not in r["wrong_open"]
222+
assert date(2026, 6, 10) not in r["wrong_open"]
223+
224+
def test_verifier_ignores_days_beyond_last_known_bar(self, monkeypatch):
225+
"""데이터가 아직 안 올라온 최근 날은 '휴장'이 아니라 '모름'이다.
226+
227+
장중에 돌리면 오늘 봉이 없어서 오늘이 휴장으로 오판됐다(실제 오탐).
228+
"""
229+
import tools.verify_trading_calendar as v
230+
231+
monkeypatch.setattr(
232+
v, "market_open_days",
233+
lambda s, e, symbol=None: {date(2026, 6, 1), date(2026, 6, 2)},
234+
)
235+
r = v.compare(date(2026, 6, 1), date(2026, 6, 30))
236+
assert r["verified_through"] == date(2026, 6, 2)
237+
assert r["wrong_open"] == [], "데이터 없는 미래 날짜를 휴장 오류로 보고했다"
218238

219239
def test_verifier_does_not_report_when_data_unavailable(self, monkeypatch):
220240
"""데이터 소스 장애를 달력 오류로 둔갑시키지 않는다."""

tools/verify_trading_calendar.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ def compare(start: date, end: date) -> dict:
6060
if opened is None:
6161
return {"error": "시장 데이터를 가져오지 못해 대조 불가", "wrong_open": [], "wrong_closed": []}
6262

63+
# 데이터가 아직 안 올라온 최근 날은 '휴장'이 아니라 '모름'이다. 장중에 돌리면
64+
# 오늘 봉이 없어서 오늘이 휴장으로 오판된다 — 확인 범위를 지수의 마지막 봉까지로
65+
# 자른다. 없는 사실을 오류로 보고하지 않는 게 이 도구의 존재 이유다.
66+
last_known = max(opened)
67+
if end > last_known:
68+
end = last_known
69+
6370
th = TradingHours(Config.get())
6471
wrong_open: list[date] = []
6572
wrong_closed: list[date] = []
@@ -77,7 +84,12 @@ def compare(start: date, end: date) -> dict:
7784
wrong_closed.append(d)
7885
d += timedelta(days=1)
7986

80-
return {"wrong_open": wrong_open, "wrong_closed": wrong_closed, "checked": checked}
87+
return {
88+
"wrong_open": wrong_open,
89+
"wrong_closed": wrong_closed,
90+
"checked": checked,
91+
"verified_through": end,
92+
}
8193

8294

8395
def main() -> int:
@@ -96,7 +108,8 @@ def main() -> int:
96108
return 0 # 데이터 소스 장애를 달력 오류로 보고하지 않는다
97109

98110
wo, wc = result["wrong_open"], result["wrong_closed"]
99-
print(f" 평일 {result['checked']}일 확인")
111+
through = result.get("verified_through")
112+
print(f" 평일 {result['checked']}일 확인 (~{through} 까지 — 지수 마지막 봉 기준)")
100113

101114
if wo:
102115
print(f"\n ❌ 거래일로 판정했지만 실제 휴장 ({len(wo)}일) — 커버리지 분모 과대")

0 commit comments

Comments
 (0)