백테스트의 함정
"10년 백테스트 연평균 40%." 이런 광고는 그래프까지 붙어 있어서 그럴듯해 보인다. 그래프는 거짓말을 하지 않는다. 다만 그 그래프를 만든 과정이 거짓말을 할 수 있다. 이 장에서는 규칙을 과거 가격에 돌려 보는 백테스트를 직접 돌려 보고, 수익 곡선을 부풀리는 함정을 하나씩 일부러 밟았다가 걷어 낸다. 마지막에는 그 "연 40%"를 해부해서 무엇이 남는지 본다.
- 백테스트가 "신호 → 다음 날 체결 → 비용 → 자산 곡선"의 순서로 돌아간다는 것을 알고, 그 순서가 어긋나는 미래 참조를 찾아낸다.
- 생존 편향, 거래 비용·슬리피지 누락, 체결 가능성, 표본 기간 의존이 결과를 어느 방향으로 얼마나 바꾸는지 숫자로 본다.
- 파라미터를 많이 맞출수록 표본 안 성과는 좋아지고 표본 밖 성과는 나빠지는 과최적화와, 많이 시험하면 하나는 맞는 데이터 스누핑을 구분한다.
- 샤프 비율 0.5짜리 전략도 10년 데이터로는 운과 가려내기 어렵다는 것을 표준오차로 설명한다.
- 훈련·검증 분리, 워크포워드, 파라미터 안정성(봉우리보다 고원), 단순한 규칙, 다중 검정 보정으로 백테스트를 의심하는 습관을 만든다.
백테스트란: 규칙을 과거에 돌려 보기
12장에서 한결은 유튜브에서 본 골든크로스 규칙을 지수에 시험해 보았다. 그것이 백테스트(Backtest)다. 매매 규칙을 미리 정해 두고, 그 규칙을 과거의 가격 위에서 하루씩 따라가며 "그때 이 규칙대로 샀다면 지금 얼마가 되었을까"를 계산하는 일이다. 결과는 보통 하나의 선, 자산 곡선(Equity curve)으로 나온다.
백테스트는 실제 돈을 걸기 전에 아이디어를 거르는 값싼 체다. 문제는 이 체가 너무 쉽게 만들어진다는 데 있다. 컴퓨터는 수천 개의 규칙을 몇 초 만에 돌릴 수 있고, 그중 가장 멋진 선 하나만 골라 보여 주면 광고가 된다. 그래서 백테스트를 읽는 사람이 알아야 할 것은 "수익이 얼마인가"보다 "이 선이 어떻게 만들어졌는가"다.
먼저 엔진을 돌려 보자. 아래는 이 책의 가상의 시장(교육용으로 만든 가짜 가격) SB 종합지수 10년에 12장의 이동평균 교차 규칙을 돌린 결과다. 단기 이동평균이 장기 이동평균보다 위에 있으면 지수를 전부 들고, 아래에 있으면 전부 현금으로 둔다. 두 기간을 바꿔 보면서 매매 표시(▲ 매수, ▼ 매도)와 아래쪽 자산 곡선이 어떻게 바뀌는지 보자.
백테스트 엔진: 이동평균 교차 규칙
기본값에서 전략의 연평균 수익은 약 7.1%로, 그냥 들고 있었을 때의 약 5.8%보다 높고 최대 낙폭도 −42%에서 −31%로 얕다. 그런데 단기 5일·장기 20일로 바꾸면 약 2.2%, 50일·200일이면 약 2.2%로 떨어진다. 이 장의 거의 모든 함정은 이 한 장면에서 출발한다. 어떤 숫자 조합이 과거에 잘 맞았다는 사실은, 그 조합이 앞으로도 잘 맞는다는 증거가 되기 어렵다.
엔진이 하루에 하는 일
백테스트 엔진이 정직하려면 한 가지 순서를 지켜야 한다. i일 장이 끝나고 종가가 나오면 그 종가까지의 정보로 신호를 계산한다. 그 신호로 주문을 낼 수 있는 가장 이른 때는 다음 거래일이다. 이 책의 엔진(ST.backtest)은 보수적으로 i일의 신호를 i+1일 종가에 체결한다. 아래에서 하루씩 넘기며 그 순서를 눈으로 따라가 보자. 오른쪽의 어두운 부분은 아직 오지 않은 날이다. 엔진도 그 안을 볼 수 없어야 한다.
하루씩 넘기는 백테스트: 신호는 오늘, 체결은 내일
신호(●)와 체결(▲·▼) 사이에는 늘 하루가 있다. 급락이 시작된 날 신호가 나와도 실제로 파는 것은 다음 날이라서, 그 하루치 하락은 고스란히 맞는다. 이 하루가 귀찮다고 지워 버리면 결과가 좋아진다. 그리고 그것이 가장 흔한 실수다.
좋은 백테스트의 조건
함정을 하나씩 보기 전에, 믿을 만한 백테스트가 갖춰야 할 것을 먼저 적어 둔다. 광고나 보고서에서 백테스트를 볼 때 이 목록으로 하나씩 물어보면 된다. 이 장의 나머지는 각 줄을 어겼을 때 무슨 일이 생기는지 보여 주는 실험이다.
미래 참조: 그날 몰랐던 것을 쓰기
미래 참조 편향(Look-ahead bias)은 백테스트 속의 내가 그 시점에는 알 수 없었던 정보를 쓰는 것이다. 대놓고 미래 가격을 보는 사람은 없다. 미래 참조는 거의 언제나 날짜가 하루, 몇 주 어긋나는 실수로 숨어 들어온다.
- 종가 보고 종가에 사기. 종가는 장이 끝나야 확정된다. 그 종가로 계산한 신호로 같은 종가에 샀다고 기록하면, 실제로는 불가능한 거래를 한 셈이다.
- 나중에 발표된 실적 쓰기. 3월 31일로 끝나는 분기의 실적은 5월 중순쯤 공시된다(분기보고서 제출 기한은 분기 말 후 45일). 데이터베이스에 "1분기 실적"이 3월 31일 날짜로 저장되어 있으면, 백테스트는 6주 먼저 실적을 안 셈이 된다.
- 나중에 고쳐진 데이터. 경제 지표나 재무 수치가 뒤에 정정되면, 지금 내려받은 데이터에는 정정된 값이 들어 있다. 그 당시 사람들이 본 값은 아니다.
- 지금의 구성 종목으로 과거 지수 만들기. 다음 절의 생존 편향과도 겹친다.
미래 참조가 결과를 얼마나 바꾸는지 직접 켜 보자. 규칙 세 가지에 세 단계의 "엿보기"를 붙였다. 정상은 앞 시뮬레이터처럼 신호 다음 날 체결한다. 종가 체결은 신호를 낸 그 종가에 샀다고 기록한다. 내일 종가 섞임은 신호를 계산할 때 내일 종가가 실수로 하나 섞여 들어간 경우다. 데이터 배열에서 인덱스 하나가 밀리면 실제로 이렇게 된다.
미래 참조 스위치: 하루를 엿보면 생기는 일
마지막 경우는 우스워 보이지만 실제로 흔하다. 내일 종가가 섞인 규칙은 "내일 오를 날만 골라 들고 있는" 규칙이 되므로 비용을 내고도 곡선이 하늘로 솟는다. 반대로 미래 참조가 조금만 섞이면 곡선은 "조금 더 좋은" 정도라서 눈치채기 어렵다. 20일 신고가 규칙이 정확히 그렇다. 정상일 때는 연 −0.7%로 쓸모없던 규칙이, 하루치 엿보기로 연 약 19%, 최대 낙폭 −9%의 꿈같은 전략이 된다. 결과가 너무 좋으면 먼저 날짜부터 의심한다.
생존 편향: 사라진 종목이 빠진 데이터
오늘 증권사 앱에서 내려받을 수 있는 종목 목록은 "오늘까지 살아남은" 종목들이다. 10년 사이 상장폐지된 회사는 목록에 없다. 이 목록으로 10년 전부터 백테스트를 하면, 10년 전의 나는 어느 회사가 망할지 미리 알고 그 회사들만 피해 간 셈이 된다. 이것이 생존 편향(Survivorship bias)이다. 생존 편향은 미래 참조의 한 종류이기도 하다. "앞으로 살아남을 것"이라는 미래 정보를 쓴 것이기 때문이다.
아래는 이 책의 가상 유니버스(월간 수익률 10년, 가상의 300종목)다. 그중 일부는 주가가 무너지거나 부실해져 중간에 상장폐지된다. 매달 모든 종목을 같은 비중으로 사는 단순한 전략을, 상장폐지 종목까지 포함한 전체 데이터와 오늘 살아남은 종목만 있는 데이터로 각각 돌려 보자. 차트 위를 끌면 그 달까지 사라진 종목 수가 보인다.
생존 편향: 살아남은 종목만으로 돌린 백테스트
전체 300종목으로는 해마다 약 1.2%p, 소형주만 보면 약 1.6%p 차이가 난다. 1년에 1~2%p는 작아 보이지만 10년이면 누적으로 수십 %p다. 게다가 생존 편향은 방향이 늘 한쪽이다. 망한 회사를 빼면 성과는 좋아지기만 한다. 소형주, 저PBR주, 적자 기업처럼 상장폐지가 잦은 곳을 다루는 전략일수록 이 편향이 크다. 상장폐지 종목을 포함한 데이터를 생존 편향 없는 데이터(Survivorship-bias-free)라고 부르고, 믿을 만한 연구는 이것을 쓴다.
비용, 슬리피지, 체결 가능성
백테스트 속의 매매는 공짜이고, 원하는 가격에, 원하는 양만큼 언제나 체결된다. 현실은 셋 다 아니다. 3장에서 본 것처럼 한 번 사고팔 때마다 수수료(약 0.015%씩)와 매도 때 증권거래세(2026년 기준 0.20%)가 나가고, 시장가 주문은 호가 차이(스프레드)만큼 불리하게 체결된다. 주문이 크면 호가를 여러 칸 먹으면서 가격을 밀어 올린다. 생각한 가격과 실제 체결 가격의 차이를 슬리피지(Slippage)라고 한다.
비용의 무게는 매매 횟수가 정한다. 1년에 한두 번 사고파는 규칙에는 0.3%의 비용이 별일 아니지만, 1년에 30번 사고파는 규칙에는 해마다 몇 %p가 사라진다. 아래에서 규칙의 빠르기를 고르고 비용과 슬리피지를 올려 보자.
비용과 슬리피지: 자주 사고팔수록 녹는 곡선
빠른 규칙은 1년에 열 번 넘게 사고판다(매수와 매도를 각각 한 번으로 센다). 편도 비용 0.215%(수수료·세금 0.115% + 슬리피지 0.1%)라면 그것만으로 해마다 3%p 넘게 빠진다. 많은 단기 전략의 "초과수익"은 정확히 이 정도 크기라서, 비용을 넣는 순간 사라진다.
그 양을 실제로 살 수 있었나
슬리피지는 주문 크기에 따라 달라진다. 백테스트가 "소형주 하나에 1억원어치를 종가에 샀다"고 적어도, 실제 호가창에 1억원어치 매도 물량이 없으면 그 가격에 살 수 없다. 이것이 체결 가능성, 다른 말로 유동성(Liquidity) 문제다. 아래 호가창의 매도 쪽(파랑)에 시장가 매수 주문을 넣는다고 생각하고, 차트를 좌우로 끌어 주문 금액을 바꿔 보자.
주문이 가격을 민다: 주문 금액과 평균 체결가
ST.Book으로 만든 가상 호가 20단계, 시장가 매수만 계산)운용 금액이 작은 개인에게 유동성은 대형주에서는 큰 문제가 아니다. 그러나 백테스트가 고른 종목이 거래가 적은 소형주라면 이야기가 다르다. 소형주 전략의 백테스트 수익이 유난히 좋다면, 그 수익의 상당 부분은 "실제로는 그 가격에 살 수 없었던" 데서 나왔을 수 있다. 이 장 끝의 광고 해부에서 소형주 전략에 편도 0.4%의 슬리피지를 붙이는 이유다.
표본 기간과 국면: 언제를 돌렸나
시장은 늘 같은 성격이 아니다. 이 책의 가상 시장 10년에도 완만한 상승, 조정, 강세장, 40일 만의 −34% 급락, 급반등, 약세장, 횡보가 차례로 들어 있다. 이런 시장의 성격이 바뀌는 것을 국면 변화(Regime change)라고 한다. 추세를 따라가는 규칙은 길게 오르거나 길게 내리는 국면에서 빛나고, 위아래로 흔들리는 국면에서 사고팔기만 반복하며 돈을 잃는다. 아래에서 규칙을 바꿔 가며 국면마다 전략과 보유를 비교해 보자.
국면별 성과: 전략 vs 그냥 보유
추세 규칙의 성적표는 "어떤 국면이 몇 번 들어 있었나"에 크게 달려 있다. 급락이 한 번 있었던 10년이면 낙폭을 피한 덕에 영웅이 되고, 같은 규칙도 횡보장 5년만 돌리면 비용만 내는 바보가 된다. 그러니 백테스트 기간을 고르는 일 자체가 결과를 고르는 일이 될 수 있다. 직접 해 보자. 아래 차트의 두 손잡이를 끌어 백테스트할 기간을 고른다.
기간 고르기: 손잡이 두 개로 결론 뒤집기
광고 속 백테스트의 시작일이 이상하게 특정한 날짜라면, 그 날짜가 왜 골라졌는지 물어볼 만하다. 정직한 백테스트는 데이터가 있는 가장 긴 기간을 쓰고, 여러 국면에서 따로 성적을 보여 준다.
과최적화: 과거에 꼭 맞는 옷
첫 시뮬레이터에서 단기·장기 이동평균 기간을 바꿔 보았다. 그 두 숫자를 파라미터(Parameter)라고 한다. 파라미터를 바꿔 가며 가장 좋은 조합을 찾는 것을 최적화라고 하는데, 너무 열심히 하면 규칙이 시장의 원리가 아니라 그 기간의 우연한 소음에 맞춰진다. 이것이 과최적화(Overfitting)다. 과거의 몸에 꼭 맞춘 옷은 미래의 몸에 맞지 않는다.
확인하는 방법은 간단하다. 데이터를 둘로 나눠 앞부분(훈련 구간, In-sample)에서만 최적화하고, 손대지 않은 뒷부분(검증 구간, Out-of-sample)에서 그 파라미터를 시험한다. 아래 격자는 단기 8가지 × 장기 10가지 조합을 모두 돌린 결과다. 칸의 색은 샤프 비율(빨강일수록 좋고, 파랑이면 손실)이다. 칸을 눌러 그 조합의 훈련·검증 성과를 보자.
파라미터 격자: 훈련의 봉우리는 검증에서 어떻게 되나
훈련 구간에서 가장 좋았던 조합이 검증 구간에서도 1등일 가능성은 낮다. 훈련 성과에는 진짜 원리와 우연이 섞여 있고, 1등은 대개 우연을 가장 많이 받은 조합이기 때문이다. 그래서 1등 칸 하나보다 넓게 좋은 지역을 본다. 주변 값을 조금 바꿔도 성과가 비슷한 고원(Plateau)은 규칙이 실제로 무언가를 잡고 있다는 신호이고, 한 칸만 솟은 봉우리(Peak)는 소음일 가능성이 크다.
이 가상 시장에서는 훈련 1등(15일·30일)이 훈련 샤프 1.09로 70개 중 1위였다가 검증에서 −0.23, 65위로 떨어진다. 고원 가운데(15일·40일)도 검증 샤프는 0 근처다. 고원은 필요조건이지 충분조건이 아니다. 훈련 구간 전체가 우연히 이동평균 규칙에 유리했다면 고원째로 무너진다. 그래서 다음 절의 표본 밖 검증이 따로 필요하다.
조건을 하나씩 붙이면
파라미터만이 손잡이가 아니다. "월요일에는 쉰다", "9월에는 안 산다" 같은 조건도 하나하나가 손잡이다. 아래에서는 지수를 그냥 들고 있는 전략에서 출발해, 훈련 구간의 샤프 비율을 가장 많이 올려 주는 조건을 하나씩 붙인다. 후보는 요일 다섯 개, 달 열두 개, 전날 오르거나 내린 날, 월초·월말 같은 21가지다. 가상 시장에는 요일이나 달에 따른 규칙성이 전혀 없도록 만들었다. 그러니 어떤 조건도 진짜일 수 없다.
조건 덧붙이기: 훈련 샤프는 오르고, 검증 샤프는
조건 네 개(7월·목요일·1월·11월 쉬기)를 붙이자 훈련 샤프는 0.55에서 1.61로 세 배가 되었다. 그럴 수밖에 없다. 매번 훈련 구간에서 가장 좋은 조건을 골랐으니까. 그러나 검증 샤프는 0.24에서 오르락내리락하다 0.10으로 끝난다. 처음 그냥 들고 있던 것보다 못하다. 조건의 수가 늘수록 규칙은 훈련 구간의 우연한 무늬를 외운다. 손잡이가 많은 전략일수록 백테스트 성과를 깎아서 읽어야 한다.
데이터 스누핑: 많이 시험하면 하나는 맞는다
과최적화가 한 규칙의 손잡이를 너무 많이 돌리는 것이라면, 데이터 스누핑(Data snooping)은 너무 많은 규칙을 시험하는 것이다. 동전 1,000개를 열 번씩 던지면 열 번 모두 앞면이 나오는 동전이 평균 한 개쯤 나온다. 그 동전이 특별한 것은 아니다. 1,000번 시험했기 때문에 나온 것이다. 통계에서는 이것을 다중 검정(Multiple testing) 문제라고 부른다.
아래에서 완전히 무작위인 전략 1,000개를 만든다. 각 전략은 매달 동전을 던져 지수를 들고 있을지 현금으로 둘지 정한다. 어떤 전략에도 실력은 없다. 그래도 1,000개를 시험하면 그중 최고는 꽤 멋져 보인다. 그 최고 전략을 다음 기간에 돌리면 어떻게 될까.
무작위 전략 1,000개: 운의 최대값
전략 하나하나의 샤프 비율은 운에 따라 평균 주위로 흩어진다. 그 흩어짐의 크기를 \(\sigma\)라고 하면, \(N\)개를 시험했을 때 운만으로 나오는 최고값은 대략 이렇다.
최고 전략의 검증 성과는 평균 근처로 돌아간다. 처음부터 실력이 아니라 운이 만든 1등이었기 때문이다. 이것을 거꾸로 보면 중요한 질문이 생긴다. 어떤 백테스트 결과를 볼 때 "이것이 몇 번째 시도인가"를 모르면, 그 결과가 얼마나 대단한지 판단할 수 없다. 광고는 1,000개 중 1등만 보여 주고 나머지 999개는 말하지 않는다.
눈으로 가려낼 수 있을까
반대 방향도 시험해 보자. 아래 여덟 개의 자산 곡선 중 하나만 진짜 실력(샤프 0.5)이 있는 전략이고, 나머지 일곱은 실력이 0인 전략이다. 변동성은 모두 연 15%로 같다. 진짜를 골라 보자. 기간을 바꾸면서 몇 판씩 해 보면 감이 온다.
진짜 실력 찾기: 여덟 곡선 중 하나
"가장 높이 오른 곡선을 고른다"는 방법이 맞는 비율은 3년이면 약 34%, 10년이면 약 57%, 40년이면 약 94%다. 후보가 여덟 개만 되어도 10년 데이터로는 두 번에 한 번꼴로 운 좋은 가짜를 고른다. 후보가 1,000개라면 진짜는 운의 최대값 속에 묻혀 거의 보이지 않는다.
통계적 유의성: 샤프 0.5는 몇 년이면 보이나
마지막 게임이 어려웠던 이유는 숫자로 설명할 수 있다. 관측한 샤프 비율은 진짜 샤프 비율의 추정값이고, 추정값에는 오차가 있다. 연 단위 샤프 비율 SR을 T년 데이터로 잴 때, 그 오차(표준오차)는 대략 다음과 같다.
진짜 샤프가 0.5인 전략을 10년 동안 재면 표준오차는 약 \(\sqrt{1.125/10} \approx 0.34\)다. 관측값은 대략 0.5 ± 0.67(±2 표준오차), 즉 −0.2에서 1.2 사이 어디든 나올 수 있다. 실력이 전혀 없는 전략(진짜 샤프 0)도 10년이면 관측 샤프가 0.5 이상 나올 확률이 약 6%다. 위의 무작위 전략 1,000개라면 그런 것이 수십 개다. 아래에서 진짜 샤프와 데이터 길이를 바꿔 보자.
샤프 비율의 불확실성: 진짜 값과 관측값
진짜 샤프 0.5짜리 전략이 "운이 아니다"라고 말하려면(관측값이 표준오차의 두 배를 넘으려면) 대략 \(4(1+SR^2/2)/SR^2 = 4 imes 1.125 / 0.25 = 18\)년이 필요하다. 지수 자체의 샤프 비율이 0.3~0.5 언저리라는 것을 생각하면, 지수를 이긴다는 전략의 초과 성과는 이보다 훨씬 작아서 수십 년 데이터로도 증명하기 어렵다. 10년 백테스트 하나로 "이 전략은 검증되었다"고 말하는 것은 대개 지나친 말이다.
대책: 백테스트를 의심하는 방법
함정을 다 피하는 백테스트는 없다. 다만 함정에 덜 빠지는 습관은 있다. 가장 중요한 것은 결과를 보기 전에 규칙을 정하고, 손대지 않은 데이터에서 다시 확인하는 것이다.
훈련과 검증을 어디서 나누나
나누는 위치도 결과를 바꾼다. 아래 차트의 세로선을 끌어 훈련·검증의 경계를 옮겨 보자. 그때마다 훈련 구간에서 1등인 조합을 다시 찾고, 아래쪽 점 그림에 모든 조합의 훈련 샤프(가로)와 검증 샤프(세로)를 찍는다. 점들이 오른쪽 위로 비스듬히 늘어서면 훈련 성적이 검증 성적을 예측한다는 뜻이고, 둥글게 흩어지면 예측하지 못한다는 뜻이다.
훈련·검증 경계 끌기
경계를 조금만 옮겨도 1등 조합이 바뀌고, 1등의 검증 순위는 위아래로 크게 흔들린다. 검증 구간도 결국 한 번의 표본이라는 뜻이다. 그래서 검증 구간을 여러 번 들여다보며 규칙을 고치면, 검증 구간마저 훈련 구간이 되어 버린다. 검증 데이터는 마지막에 한 번만 본다.
워크포워드: 실제로 운용했다면
한 번 나누기보다 현실에 가까운 방법이 워크포워드(Walk-forward) 분석이다. 그 시점까지의 데이터(훈련 창)로 1등 조합을 고르고, 다음 반년 동안 그 조합으로 운용한다. 반년이 지나면 창을 반년 밀어서 다시 고른다. 이렇게 이은 성적은 "그때그때 최선을 다해 최적화했다면 실제로 받았을 성적"이다. 재생을 눌러 창이 미끄러지는 것을 보자.
워크포워드: 창을 밀며 다시 고르기
사후 1등 곡선은 같은 기간을 다 보고 고른 조합이다. 광고에 나오는 곡선은 대개 이것이다. 훈련 창 3년에서 사후 1등은 연 약 12.2%, 보유는 약 9.2%인데 워크포워드는 약 3.8%다. 둘 사이의 간격이 "과거를 알고 고른 덕"이다. 창 길이를 바꾸면 더 놀랍다. 1년이면 약 7.7%, 2년이면 약 10.0%, 4년이면 약 0.4%다. 훈련 창 길이라는 손잡이 하나에 결과가 이만큼 흔들린다면, 그 규칙에는 믿고 기댈 만한 무엇이 없다는 뜻이다.
의심하는 습관 다섯 가지
- 먼저 정하고, 나중에 본다. 규칙과 평가 기준을 적어 둔 뒤 돌린다. 결과를 보고 규칙을 고칠 때마다 검증 구간은 조금씩 훈련 구간이 된다.
- 표본 밖에서, 한 번만. 훈련·검증을 나누고, 가능하면 워크포워드로 실제 운용을 흉내 낸다.
- 봉우리보다 고원. 이웃 파라미터에서도 성과가 비슷한지 본다. 한 칸만 좋은 규칙은 버린다.
- 단순한 규칙. 손잡이가 적을수록 우연에 맞출 여지가 적다. 조건 하나를 더할 때마다 "왜 그래야 하는가"에 대한 경제적 이유가 있어야 한다.
- 시험한 횟수를 센다. 시험을 많이 했다면 기준을 올린다. 관측 샤프의 표준오차와 "N개 중 최고"의 기대값을 같이 본다.
"연 40% 전략" 해부
이제 처음의 광고로 돌아가자. 한결이 본 광고는 이랬다.
규칙 자체는 단순하다. 매달 말, 소형주 가운데 지난 L개월 동안 가장 많이 오른 k종목을 같은 비중으로 사서 한 달 들고 있는다. 16장의 모멘텀이다. 광고를 만든 사람은 L과 k를 여러 가지로 돌려 가장 좋은 것을 골랐고, 오늘 살아 있는 종목 데이터만 썼고, 순위를 매긴 데이터에 다음 달 첫날 종가가 섞여 있었고, 비용은 넣지 않았다. 아래에서 함정을 하나씩 걷어 내 보자.
광고 해부: 함정을 하나씩 걷어 내는 폭포
남는 것은 광고의 숫자와 거리가 멀다. 연 약 40%가 미래 참조를 빼자 30.5%, 상장폐지 종목을 넣자 29.8%, 비용과 슬리피지를 넣자 20.9%, L·k를 그때그때 고르게 하자 11.6%가 된다. 미래 참조(하루치였을 뿐인데 연 9%p 넘게), 비용(소형주를 매달 갈아타는 전략은 비용에 가장 약하다), 과최적화가 거의 같은 몫씩 나눠 가졌다. 생존 편향은 이 기간에는 1%p도 되지 않았지만, 기간과 종목에 따라 훨씬 커질 수 있다. 마지막 숫자는 시장 동일가중(약 10.1%)과 비슷하다. 이 가상 유니버스에는 모멘텀이 실제로 조금 있도록 만들었다. 그런데도 남은 초과수익은 앞 절에서 본 표준오차 안에 쉽게 숨는 크기다.
"연 40%" 광고를 해부하다
위성(satellite) 몫으로 무엇을 살지 고민하던 한결에게 "소형주 모멘텀, 백테스트 연 40%" 광고가 떴다. 12장의 골든크로스 때와 달리 이번에는 그래프가 너무 매끈했다. 한결은 이 장의 체크리스트를 들고 광고의 백테스트를 가상 유니버스에서 다시 돌렸다.
광고 그대로면 연 약 40%. 순위 데이터에 섞인 하루치 미래를 빼자 30.5%, 상장폐지 종목을 넣자 29.8%, 비용과 슬리피지를 넣자 20.9%, 마지막으로 L·k를 그때그때 고르게 하자(과최적화 제거) 11.6%가 남았다. 같은 기간 시장 동일가중은 약 10.1%. 남은 1.5%p의 차이는 10년 데이터로는 운과 가려내기 어려운 크기였다. 표본 밖에서 무너진 것은 전략이 아니라 광고였다.
핵심 정리
- 백테스트는 규칙을 과거 데이터에 하루씩 돌려 자산 곡선을 만드는 일이다. 정직한 엔진은 i일 종가까지의 정보로 신호를 내고 i+1일에 체결하며, 비용을 뺀다.
- 미래 참조는 날짜가 어긋나는 실수로 숨어 든다(종가 보고 종가 체결, 공시 전 실적 사용). 하루만 엿봐도 쓸모없는 규칙이 꿈의 전략이 된다. 결과가 너무 좋으면 날짜부터 의심한다.
- 생존 편향은 상장폐지 종목이 빠진 데이터에서 생기며 늘 성과를 부풀린다. 소형주·부실주를 다루는 전략일수록 크다.
- 비용·슬리피지는 매매 횟수에 비례해 수익을 깎는다. 유동성이 적은 종목에서는 백테스트 가격에 그 양을 살 수 없다.
- 성과는 표본 기간과 국면에 크게 의존한다. 기간을 고르는 것만으로 결론을 뒤집을 수 있다.
- 파라미터와 조건을 많이 맞출수록 훈련 성과는 오르고 검증 성과는 나빠진다(과최적화). 많이 시험하면 운만으로도 멋진 결과가 나온다(데이터 스누핑).
- 샤프 비율의 표준오차는 약 √((1+SR²/2)/T)다. 진짜 샤프 0.5도 10년으로는 운과 구분하기 어렵고, 0과 구분하려면 약 18년이 필요하다.
- 대책: 결과 전에 규칙을 정하고, 표본 밖·워크포워드로 확인하고, 봉우리보다 고원을 고르고, 단순한 규칙을 쓰고, 시험 횟수만큼 기준을 올린다(디플레이티드 샤프).
확인 퀴즈
1. 어떤 백테스트가 "오늘 종가가 20일 이동평균을 넘으면 오늘 종가에 산다"고 계산했다. 무엇이 문제인가?
2. 지금 상장되어 있는 종목만으로 10년 전부터 소형주 전략을 백테스트했다. 결과는 실제보다 어떻게 나오기 쉬운가?
3. 파라미터 격자에서 훈련 구간 샤프가 가장 높은 칸 하나가 주변 칸들보다 홀로 높게 솟아 있다. 어떻게 해석하는 것이 가장 알맞은가?
4. 실력이 전혀 없는 무작위 전략 1,000개를 시험해 가장 좋은 것을 골랐다. 그 전략을 새 기간에 돌리면 어떻게 될 가능성이 가장 큰가?
5. 진짜 샤프 비율이 0.5인 전략을 10년 데이터로 잴 때, 관측 샤프 비율의 표준오차로 가장 가까운 것은? (SE ≈ √((1+SR²/2)/T))