- 전방참조는 백테스트가 그 시점에 알 수 없었던 정보를 쓰는 것입니다. 한 종류가 아니라 최소 여섯 갈래로 들어옵니다.
- 전방참조를 걷어내면 백테스트 성적은 대체로 내려갑니다. 올라가는 경우도 있지만 드뭅니다.
- 가장 비싼 유형은 체결 가정입니다. 「3% 오르면 산다」고 적었는데 백테스트는 3% 올랐다가 밀린 종목을 안 산 것으로 처리하고 있었습니다.
- 편향이 있다고 반드시 손해인 것은 아닙니다. 실제로 재보면 피해가 0인 경우도 있습니다.
지난 글에서 연 1억 퍼센트짜리 백테스트의 정체가 전방참조였다는 이야기를 했습니다.
그런데 그게 하나가 아니었습니다.
하나를 찾고 나서 다른 백테스트들을 전부 다시 뒤졌습니다. 그랬더니 같은 병이 모양만 바꿔서 여기저기 들어 있었습니다. 이 글은 그걸 유형별로 정리한 것입니다.
백테스트를 만드시는 분이라면 점검표로 쓰시라고 적어둡니다.
전방참조가 뭔가
한 줄로 말하면 이렇습니다.
말은 간단한데, 실제로는 알아채기가 아주 어렵습니다. 오류 메시지도 없고 프로그램도 잘 돌아갑니다. 결과가 좋게 나올 뿐입니다.
그래서 어디에 숨는지를 유형으로 알고 있어야 찾을 수 있습니다.
여섯 가지 길

① 체결 가정 — 제가 가장 크게 속은 것
백테스트는 "얼마에 샀다고 칠 것인가"를 정해야 합니다. 여기가 첫 번째 함정이고, 저를 가장 오래 속인 자리입니다.
제가 적은 규칙은 단순했습니다.
급등이 시작되는 자리를 잡겠다는 겁니다. 더 설명할 것도 없는 규칙입니다.
그런데 백테스트가 실제로 한 일은 달랐습니다.
3% 올랐다가 밀려서 하락으로 끝난 종목은 매수 목록에 아예 없었습니다.
이게 왜 이렇게 되는지 한참 이해가 안 됐습니다. 저는 "3% 오르면 산다"고 적었지, "3% 오른 뒤에 그대로 잘 끝나면 산다"고 적은 적이 없으니까요.
이게 왜 치명적인지는 잠깐만 생각해보면 압니다.
하루에 3% 오르는 종목은 많습니다. 그리고 그중 상당수는 오르다가 밀려서 마이너스로 끝납니다. 실전에서 제일 자주 겪고 제일 아픈 게 바로 그겁니다. 사자마자 고꾸라지는 거래요.
원인은 체결을 판정하는 자리에 그날의 결과가 섞여 들어간 것이었습니다. 3%에 닿았는지를 판정하려면 그날 가격 범위를 봐야 하는데, 그 범위는 장이 끝나야 확정됩니다. 그래서 판정 자체가 「그날 어떻게 끝났는지」를 이미 알고 있는 상태에서 이뤄졌습니다.
결과가 어땠는지 말씀드리면 이렇습니다.
이 유형이 무서운 건 규칙 자체는 아무 문제가 없어 보인다는 점입니다. 「3% 오르면 산다」는 문장에는 미래를 보는 대목이 한 글자도 없습니다. 미래는 그 문장을 실행하는 코드에 들어가 있었습니다.
제대로 고쳤더니 이렇게 됐습니다.
| 체결 가정 | PF (손익비) |
|---|---|
| 3% 오른 종목 중 상승 마감한 것만 매수 | 1.37 |
| 3% 오르면 마감 결과와 무관하게 매수 | 0.87 |
PF는 1.0이 본전입니다. 1.37에서 0.87로 떨어졌다는 건 「버는 전략」이 「잃는 전략」으로 바뀌었다는 뜻입니다.
겉보기 엣지가 통째로 「이긴 날만 샀다고 친 것」에서 나오고 있었습니다. 전략이 좋았던 게 아니라 채점 방식이 후했던 것입니다.
② 당일 확정값 — 가장 흔합니다
종가·고가·저가·거래량은 전부 장이 끝나야 확정됩니다. 그런데 그날의 판단에 쓰기가 너무 쉽습니다.
제가 걸린 예는 지수 급락일에 매수를 막는 규칙이었습니다. 「지수가 많이 빠진 날은 사지 않는다」는 건데, 그 판정에 당일 종가 기준 지수 등락률을 쓰고 있었습니다.
장중에 매수할 때는 그날 지수가 얼마나 빠질지 모릅니다. 전날 기준으로 고쳤더니 성적이 이만큼 내려갔습니다.
- 승률 0.7%p 하락
- PF 0.14 하락
- 연평균 수익률 2.6%p 하락
규칙 하나의 기준일을 하루 옮겼을 뿐인데 연 2.6%가 사라졌습니다. 그 2.6%는 처음부터 없던 돈이었습니다.
③ 사후에만 아는 지점 — 가장 교묘합니다
저점·고점·「급등이 시작된 날」 같은 것들입니다.
지나고 나서 차트를 보면 저점이 어디인지 한눈에 보입니다. 그래서 "저점에서 며칠 뒤에 산다" 같은 규칙을 자연스럽게 만들게 됩니다.
그런데 그날 그 자리에서는 그게 저점인지 알 수 없습니다. 더 내려갈 수도 있으니까요. 저점이라는 걸 아는 순간 이미 미래를 본 것입니다.
저는 이걸 확인하려고 시작 기준을 셋으로 나눠 재봤습니다.
| 기준 | 정직한가 |
|---|---|
| 저점 다음 날부터 | ⛔ 전방참조 |
| 조건이 끝난 다음 날부터 | 정직하지만 8~14일 늦음 |
| 조건이 처음 걸린 다음 날부터 | ✅ 정직 |
여기서 배운 게 있습니다. 「저점을 안다」를 규칙에서 빼도, 다른 기준으로 같은 자리를 잡을 수 있으면 전략은 살아남습니다. 죽는 건 전략이 아니라 제 게으른 정의였습니다.
④ 소급 계산 — 찾기가 제일 어렵습니다
이건 지표 자체가 아니라 지표를 만드는 재료에 숨어 있습니다.
시가총액을 「주식수 × 주가」로 계산하고 있었습니다. 맞는 식입니다. 문제는 그 주식수가 「지금」 주식수 하나였다는 것입니다.
과거 주가에 지금 주식수를 곱하면 어떻게 될까요. 그 사이에 증자를 한 종목은 과거 시총이 통째로 부풀려집니다. 심한 경우 39배까지 커졌습니다.
그러면 원래 소형주였던 종목이 백테스트에서는 대형주로 잡히고, 시총 조건에 잘못 걸려 들어옵니다. 실제로 어떤 모델에서는 가짜 신호가 13%였습니다.
날짜별 진짜 시총으로 바꿔서 다시 재봤습니다.

결과가 뜻밖이었습니다. 거래 두 건이 줄고, 연평균이 0.25%p 내려가고, 최대낙폭은 그대로였습니다. 손익비는 오히려 소수점 셋째 자리에서 올랐습니다.
이유는 단순했습니다. 그 모델에는 시총 하한 조건이 있어서, 부풀림의 피해자가 될 소형주를 애초에 걸러내고 있었습니다. 편향은 있었지만 그 편향이 닿는 자리에 거래가 없었던 것입니다.
⑤ 중앙정렬 창 — 계산식 안에 숨습니다
어떤 계산은 한 지점의 앞뒤를 같이 봅니다. 예를 들어 「이 봉이 주변에서 제일 높은가」를 판정하려면 뒤쪽 봉도 봐야 합니다.
이걸 그대로 쓰면 그 시점에는 아직 오지 않은 봉을 보는 셈입니다.
고치는 법은 창이 다 채워진 뒤부터만 값을 쓰는 것입니다. 창이 열흘짜리라면 열흘이 지난 다음부터 씁니다.
이 유형은 특히 조심하셔야 합니다. 지표 이름만 보면 문제가 안 보입니다. 계산식을 열어봐야 압니다.
⑥ 현재 명단 — 생존편향
과거를 재는데 지금 상장된 종목 목록을 쓰는 것입니다. 그러면 그 사이에 사라진 종목이 통계에서 통째로 빠집니다.
망한 회사가 빠진 데이터로 성적을 재면 당연히 좋게 나옵니다. 이걸 생존편향이라고 합니다.
그런데 여기서 두 번째 반전이 있었습니다. 실제로 세어봤습니다.
| 확인한 것 | 결과 |
|---|---|
| 그 기간의 부실 상장폐지 | 95건 |
| 그중 이 전략의 매수 조건에 걸릴 만한 것 | 7건 |
| 그 7건 중 실제로 샀을 종목 | 0건 |
이유가 있었습니다. 망해가는 회사의 차트는 이 전략이 사는 모양과 정반대였습니다. 그리고 남은 7건도 다른 조건에서 전부 걸러졌습니다.
편향이 있다고 반드시 손해인 것은 아닙니다. 있는지 없는지가 아니라 얼마나 닿는지를 재야 합니다.
그래서 수익이 올랐나
솔직히 말씀드리면 아닙니다. 내려갔습니다.
여섯 건을 다 걷어내고 나니 백테스트 성적은 전보다 낮아졌습니다. 어떤 건 「버는 전략」이 「잃는 전략」이 됐고, 어떤 건 연 2.6%가 사라졌습니다.
그런데 그게 이 작업의 목적이었습니다.
그리고 여기서부터가 진짜입니다.
오염된 숫자 위에서는 개선을 해도 그게 개선인지 착시인지 구분이 안 됩니다. 지난 글에서 가짜 점수를 0.001씩 올리며 몇 주를 쓴 게 그 이야기였습니다.
정직한 바닥을 만든 다음에야 「이걸 바꿨더니 좋아졌다」가 믿을 만한 문장이 됩니다. 낮은 데서 다시 시작하는 게 억울해 보이지만, 그게 유일하게 앞으로 나아가는 방법이었습니다.
점검표
백테스트를 돌리시는 분이라면 이 여섯 개를 한 번씩 확인해보시기 바랍니다.
| 확인할 것 | 물어볼 질문 |
|---|---|
| 체결 가정 | 그 가격에 실제로 닿은 걸 확인하고 샀는가 |
| 당일 값 | 그날 판단에 그날 종가·고가·저가·거래량이 들어가는가 |
| 사후 지점 | 저점·고점·시작일을 규칙에 쓰는가 |
| 소급 계산 | 과거 값을 계산하는 데 현재 값을 쓰는가 |
| 계산 창 | 그 지표가 뒤쪽 봉을 보는가 |
| 종목 명단 | 그때 상장돼 있던 종목으로 재는가 |
질문은 결국 하나로 모입니다.
이 한 문장을 백테스트에 들어가는 값마다 물어보면 대부분 걸러집니다. 저는 이걸 몰라서 두 달을 썼습니다.
마무리
전방참조는 실력이 늘어도 계속 나옵니다. 새 규칙을 하나 붙일 때마다 새로 들어올 수 있어서, 한 번 청소하고 끝나는 일이 아닙니다.
그래서 저는 새 조건을 넣을 때마다 「이 값을 그때 알 수 있었나」를 먼저 묻는 습관을 들였습니다. 나중에 발견하면 그 위에 쌓은 게 다 무너지기 때문입니다.
백테스트 성적이 좋게 나왔을 때 기뻐하기 전에 이 여섯 개를 훑어보시기 바랍니다. 그게 제가 두 달 주고 산 교훈입니다.