
들어가며: 그럴듯한 숫자를 의심하기

퀀트 백테스트를 만지다 보면 결과가 좋게 나올수록 오히려 조심해야 하는 순간이 있습니다. 이번 글은 매매 당일 자기 종가로 레짐(regime)을 라벨링하던 미래참조(look-ahead) 버그를 발견하고 고친 기록입니다. 고치고 나니 레짐 필터의 효과가 부풀려져 있었을 뿐 아니라, 최고와 최악의 순서까지 반대로 뒤바뀌었습니다.
이 글은 완결된 전략 소개가 아니라, 하나의 검증 실패와 수정 과정을 남기는 개발 기록입니다.
문제: 레짐과 수익률이 같은 하루를 봤다

build_backtest는 각 매매일에 regime_by_date[매매일] = 그 매매일의 지수 등락률로 레짐 라벨을 붙이고 있었습니다. 문제는 수익률도 같은 날 시가→종가로 측정했다는 점입니다. 즉 레짐과 수익률이 같은 하루를 측정한 것입니다.
지수가 -4%로 끝난 날을 RISK_OFF로 부르고 "그날 개별 종목이 빠졌다"고 말하는 것은 발견이 아니라 동어반복에 가깝습니다. "RISK_OFF를 빼면 흑자"라는 결론 역시 그날 장이 끝나야 알 수 있는 정보로 필터링한 것이라, 매매 시점에는 알 수 없는 정보를 쓴 셈입니다.
배경: 미래참조(look-ahead)란
이해를 돕기 위한 짧은 배경입니다. 미래참조는 백테스트가 그 시점에는 알 수 없었던 미래 정보를 의사결정에 사용하는 오류를 말합니다. 실전에서는 재현되지 않는 성과를 만들어내기 때문에, 백테스트의 대표적인 함정으로 꼽힙니다.
이번 사례에서 매매 시점(당일 시가)에 알 수 있는 정보는 전일 지수까지입니다. 당일 종가로 레짐을 붙이는 순간, 아직 오지 않은 정보를 미리 본 것이 됩니다.
해결: 전일 레짐을 붙이고 회귀 테스트
매매일에 직전 거래일의 레짐을 붙이도록 바꿨습니다. 규칙은 단순합니다.
regime_by_date[t] = regime(t-1)— 매매 시점에 알 수 있는 범위(전일 지수)로 제한
그리고 회귀 테스트 3건을 추가했습니다.
- 급락한 당일에는 RISK_OFF가 붙지 않을 것
- 급락한 다음 날에는 붙을 것
- 데이터 첫날은 레짐이 없을 것
결과: 순서까지 뒤바뀌었다
수정 후 결과가 뒤집혔습니다. 아래는 개발 기록에 남은 수정 전후 수치입니다.
| RISK_ON | +1.63% / 49.5% | -1.11% / 36.5% |
| RISK_OFF | -4.17% / 21.3% | -2.30% / 32.6% |
순서까지 반대가 됐습니다. 이제 RISK_ON이 최악, NEUTRAL이 최고로 나왔고, 승률 편차는 28.2%p에서 12.2%p로 줄었습니다. RISK_OFF vs 나머지 검정은 p=0.220으로 우연과 구분되지 않았습니다. 즉 "전일 레짐으로 매수를 거른다"는 실행 가능한 규칙에는 가치가 없다는 결론입니다.
파급: 같은 도구를 쓴 다른 규칙
ENABLE_RISK_OFF_BUY_BLOCK의 근거였던 이전 DEVLOG 기록("차단 시 기대값 -0.49% → +0.57% 흑자 전환")이 같은 도구에서 나왔다면, 동일한 미래참조를 안고 있을 가능성이 있습니다.
다만 주의할 점은, 라이브 차단은 당일 실시간 지수를 사용하므로 두 백테스트 어느 쪽도 측정하지 않은 규칙이라는 것입니다. 지금으로선 끄자고 할 근거도, 켜두자고 할 근거도 없습니다. 이 규칙을 제대로 재현·측정하려면 장중 지수 시계열이 필요합니다.
배운 점
가장 크게 남은 교훈은 하나입니다. 백테스트 결과를 받아들이기 전에 "이 정보를 그 시점에 알 수 있었나"부터 물어야 한다는 것입니다.
- 미래참조는 결과를 좋게 만들 뿐 아니라 방향까지 바꾼다 — 고치고 나니 최고와 최악이 뒤바뀌었다.
- 이런 버그는 조용하다. 숫자가 그럴듯하면 아무도 시점을 따지지 않는다.
라이브 차단 규칙을 실제 측정 가능한 형태로 재현하려면 장중 지수 시계열이 있어야 합니다.
'EP 빌드로그' 카테고리의 다른 글
| EP.27 S5 립싱크 실수: 클론 음성 단순 remux의 함정 (0) | 2026.08.09 |
|---|---|
| EP.26 자동화 알림에서 '해야 할 일'과 '관찰 결과'를 분리하는 법 (0) | 2026.08.07 |
| EP.24 스캘핑 섀도우 3종 하루 완성기: KR·US·Coin 동시 구현 (0) | 2026.08.05 |
| EP.23 스캘핑 전략은 왜 수집기부터 시작하나 (0) | 2026.08.04 |
| EP.22 허브가 스스로 판단하게 만든 첫 단계: 2-모델 긴급도 판정 (0) | 2026.08.03 |