백테스트가 좋아 보인다는 착각부터 걷어냅니다
키움헌터v2를 만들며 가장 뼈아팠던 착각은, 새 필터 하나를 추가했더니 백테스트 누적 수익률 곡선이 예쁘게 올라가는 것을 보고 “이 필터가 효과가 있구나”라고 결론지었던 일입니다. 며칠 뒤 그 필터를 아예 빼고 다시 돌려 보니 성과가 거의 같았고, 오르막의 진짜 원인은 그 기간에 우연히 몰린 몇 개의 종목이었습니다.
이 경험 이후 저는 규칙 하나를 세웠습니다. “좋아 보인다”는 절대 근거가 아니라는 것입니다. 어떤 요소가 성과에 기여했는지는 그 요소를 넣었을 때와 뺐을 때를 나란히 비교해야만 알 수 있습니다.
이것이 머신러닝과 실험 설계에서 말하는 절제 실험(ablation), 쉽게 말해 ‘있음·없음 대조’의 핵심입니다.
수익률이라는 숫자 하나는 실력과 운, 시장 국면, 표본 편향이 전부 뒤섞인 결과물입니다. 이 뒤섞임을 풀어내지 않으면, 우리는 운으로 번 돈을 자기 실력으로 착각한 채 실거래에 그 규칙을 올리게 됩니다. 그리고 시장 국면이 바뀌는 순간 그 착각의 비용을 고스란히 치릅니다.
- 핵심 포인트 1: 곡선이 우상향한다는 사실 자체는 특정 규칙의 효과를 증명하지 않습니다. 같은 기간이면 아무 규칙이나 우상향했을 수 있습니다.
- 핵심 포인트 2: 한 요소의 기여도는 오직 대조군(그 요소가 없는 버전)과의 차이로만 측정됩니다. 대조군 없는 성과는 해석 자체가 불가능합니다.
왜 ‘한 번에 하나’가 아니라 2×2인가
가장 단순한 대조는 요소 하나를 넣은 버전(A)과 뺀 버전(B)을 비교하는 것입니다. 그러나 이 방식은 두 요소가 서로 맞물려 작동할 때 심각하게 오해를 부릅니다.
예를 들어 ‘종목 선별 규칙’과 ‘진입 시점 규칙’ 두 가지를 각각 따로 켜고 끄며 시험했다고 합시다. 각각만 보면 둘 다 효과가 미미해 보일 수 있습니다. 그런데 두 규칙이 동시에 켜졌을 때만 성과가 크게 나온다면, 하나씩 시험하는 방식으로는 이 상호작용을 영영 놓치게 됩니다.
그래서 저는 두 요소를 격자로 교차시키는 2×2 대조 실험을 기본 검증 틀로 씁니다. 요소 하나가 아니라, 두 요소의 조합이 만들어내는 네 가지 경우의 수를 모두 돌려 보는 것입니다.
| 구분 | 요소 B 없음 | 요소 B 있음 |
|---|---|---|
| 요소 A 없음 | 기준선(둘 다 끔) | B 단독 효과 측정 |
| 요소 A 있음 | A 단독 효과 측정 | A·B 결합 효과 측정 |
이 네 칸의 성과를 나란히 놓으면 세 가지를 한눈에 읽어낼 수 있습니다. 요소 A가 혼자서 얼마나 기여하는지, 요소 B가 혼자서 얼마나 기여하는지, 그리고 둘을 같이 켰을 때 단순 합보다 더 커지는(또는 오히려 깎이는) 상호작용이 있는지입니다.
특히 마지막 상호작용 항목이 실전에서 가장 값집니다. “이 두 개는 반드시 세트로 가야 한다” 혹은 “따로 보면 좋은데 같이 쓰면 서로 방해한다” 같은 판단은 오직 2×2 격자에서만 드러납니다.
- 1단계: 기준선 고정 — 두 요소를 모두 끈 가장 단순한 버전을 먼저 확정합니다. 이후 모든 비교는 이 기준선 대비 얼마나 나아졌는가로 읽습니다.
- 2단계: 조건만 바꿔 4회 실행 — 데이터 기간, 수수료, 슬리피지, 초기 자본 등 나머지 조건은 완전히 동일하게 고정한 채 A·B의 켬/끔 조합만 바꿔 네 번 돌립니다.
- 3단계: 같은 잣대로 채점 — 누적 수익률만 보지 말고 최대 낙폭, 승률, 손익비, 거래 횟수를 함께 기록합니다. 수익률은 같은데 낙폭만 커졌다면 그 요소는 오히려 해로운 것입니다.
대조 실험에서 자주 무너지는 지점들
격자를 만드는 것보다 어려운 것은, 네 번의 실행이 정말 ‘조건만 다르고 나머지는 같은’ 공정한 비교가 되도록 유지하는 일입니다. 여기서 대부분의 검증이 소리 없이 무너집니다.
- 오류 상황 1 — 기간을 슬쩍 바꿔치기: 요소를 켠 버전은 상승장 구간에서, 끈 버전은 하락장 구간에서 돌리면 비교 자체가 성립하지 않습니다. 네 실행 모두 완전히 같은 데이터 기간을 써야 하며, 이상적으로는 같은 종목 풀에서 돌려야 합니다.
- 오류 상황 2 — 표본이 너무 작음: 거래가 스무 번 남짓인 실험에서 나온 승률 차이는 대부분 우연입니다. 칸마다 충분한 거래 표본이 쌓였는지부터 확인하고, 표본이 얇으면 결과를 ‘경향’ 이상으로 해석하지 않습니다.
- 오류 상황 3 — 미래 정보 누수의 재발: 대조군을 만드는 과정에서 실수로 미래 데이터를 참조하는 코드가 한쪽에만 섞이면, 그 버전만 비현실적으로 좋아 보입니다. 앞서 다룬 순환논리·미래정보 누수 점검을 네 버전 모두에 동일하게 적용해야 합니다.
- 오류 상황 4 — 결론을 미리 정해두기: “이 요소는 분명 효과가 있을 것”이라는 기대를 품고 시작하면, 네 칸 중 그 기대에 맞는 칸만 눈에 들어옵니다. 실행 전에 “무슨 결과가 나오면 이 요소를 버리겠다”는 기준을 먼저 종이에 적어두는 편이 안전합니다.
한 가지 덧붙이면, 이 방법은 수익을 늘려 주는 마법이 아니라 헛된 규칙을 걸러내는 체입니다. 대조 실험을 통과하지 못한 요소를 과감히 버리는 만큼, 시스템은 가벼워지고 실거래에서의 예측 가능성은 올라갑니다.
무엇을 넣을지보다 무엇을 뺄지를 데이터로 결정하는 습관, 그것이 우연히 잘 나온 백테스트와 실거래에서도 버티는 시스템을 가르는 분기점입니다.
이 글은 자동매매 시스템을 직접 만들어 가는 학습 과정을 기록한 것으로, 특정 종목 추천이나 수익 보장과는 무관합니다. 모든 매매에는 원금 손실 위험이 있으며, 어떤 검증 방법도 미래 수익을 보장하지 않습니다.
답글 남기기