백테스트를 믿을 수 있게 만드는 네 가지 규칙 — 자체 검증 하네스 설계

백테스트를 믿을 수 있게 만드는 네 가지 규칙

미장봇 만들기 9편 · 자동매매 전략 연구 기록

데이트레이딩 전략을 접은 뒤 남은 질문은 하나였다. “그럼 무엇이 통하는가.” 30가지가 넘는 매매법을 같은 조건에서 비교해 보기로 했는데, 그 전에 먼저 해야 할 일이 있었다. 자를 만드는 일이다. 자가 휘어 있으면 30개를 재도 결과는 전부 쓸모없다. 이 글은 그 자 — 백테스트 하네스 — 를 어떻게 만들었고, 스스로 어떻게 공격했는지에 대한 기록이다.

📌 네 가지 규칙 — ① 신호는 오늘 종가까지만, 체결은 내일 시가에 ② 정수주와 현금 제약을 그대로 강제 ③ 수수료·슬리피지·세금을 자산에서 실제로 차감 ④ 완성된 하네스를 스스로 공격해 통과하지 못한 항목을 그대로 남겨 둔다.

규칙 1 — 신호는 오늘 종가까지, 체결은 내일 시가에

백테스트에서 가장 흔하고 가장 치명적인 실수는 아직 알 수 없는 정보를 쓰는 것이다. 예를 들어 “종가가 200일 이동평균을 넘으면 매수”라는 규칙을 만들고, 그 판정에 쓴 바로 그 종가로 체결시키면 이미 미래를 쓴 셈이다. 실제로는 종가를 확인한 시점에 그 가격으로 살 수 없다. 장이 끝났기 때문이다.

그래서 하네스에 하루의 지연을 구조적으로 강제했다. 신호는 t일 종가까지의 데이터로만 만들고, 그 신호는 t+1일 시가에만 체결된다. 이건 옵션이 아니라 시뮬레이터의 골격이다.

Python

for i, d in enumerate(dates):
    if i > 0:
        tgt = weights.iloc[i - 1]   # ← 전날 종가에 결정된 목표 비중
        ...
        px = opens.loc[d]          # ← 오늘 시가로만 체결

한 줄로 보이지만 이 두 줄이 하네스의 신뢰도를 결정한다. 목표 비중 배열은 항상 하루 전 인덱스에서 가져오고, 체결 가격은 항상 당일 시가 배열에서 가져온다. 종가 배열은 평가(마크투마켓)에만 쓰인다.

mermaid diagram

🔁 다이어그램 요약: 신호는 t일 종가까지의 데이터로만 만들고, 목표 비중이 바뀐 경우에만 t+1일 시가에 정수주·현금제약을 지켜 체결한다. 종가는 평가용으로만 쓰여 체결 가격으로 새어 들어가지 않는다.

지표 계산에도 같은 원칙을 적용했다. 예를 들어 채널 돌파 전략에서 “20일 최고가”를 쓸 때, 오늘을 포함한 최고가를 쓰면 오늘 고가를 미리 아는 셈이 된다. 그래서 채널값은 직전 봉까지의 값으로 한 칸 밀어서 참조한다.

월 1회 리밸런스 전략에서도 함정이 있다. “월말”을 판정하려면 달력이 필요한데, 이때 날짜만 쓰고 가격은 쓰지 않는다. 월말 여부는 미래 가격 정보가 아니므로 안전하고, 그 날짜에 계산되는 모멘텀은 다시 과거 데이터만 참조한다.

규칙 2 — 정수주와 현금 제약을 그대로 강제

대부분의 백테스트는 “자산의 40%를 매수”를 소수점 주식으로 처리한다. 자본이 크면 오차가 무시할 만하지만, $1,000 계좌에서는 이 가정이 결과를 바꾼다. 국내 증권사로 미국주식을 거래하면 소수점 매매가 제한되는 경우가 많고, 계획한 비중과 실제로 살 수 있는 주식 수가 어긋난다.

그래서 하네스는 세 가지를 강제한다.

정수주만 — 목표 주식 수를 내림 처리한다. 남는 돈은 현금으로 남고 수익률 0%로 계산된다.
매도 먼저, 매수 나중 — 실제 계좌처럼 팔아서 현금을 만든 뒤에 산다.
현금 제약 — 매수 가능 수량은 보유 현금을 수수료 포함 단가로 나눈 값까지다. 마이너스 현금은 발생하지 않는다.

이 규칙이 만드는 왜곡은 전략 유형에 따라 방향이 다르다. 자산을 5개로 쪼개는 분산형 전략은 슬롯당 최대 50%까지 유휴현금이 생겨 성과가 8%에서 최대 50%까지 낮게 측정됐다. 반대로 주가가 낮은 레버리지 ETF 하나에 집중하는 전략은 드래그가 1% 수준에 그쳤다. 소액 계좌에서는 “몇 주를 살 수 있는가”가 전략 선택의 변수가 된다는 뜻이다. 이 사실은 하네스에 정수주를 넣지 않았다면 절대 보이지 않았다.

규칙 3 — 비용은 실제 요율로, 자산에서 직접 차감

앞선 글에서 실거래 11건의 수수료가 매매손익의 116%였다는 걸 확인한 뒤로, 비용 모델은 하네스에서 타협하지 않는 항목이 됐다. 국내 증권사로 미국주식을 거래할 때 실제로 빠져나가는 항목을 그대로 넣었다.

비용 항목 요율 적용
거래 수수료 0.25% / 편도 매수·매도 양방향
슬리피지 0.05% / 편도 매수·매도 양방향
미국 증권거래위원회 수수료 매도금액 × 0.0000278 매도만
금융산업규제국 거래활동수수료 주당 $0.000166 매도만
환전 비용 0 달러 잔고 내에서만 거래하는 전제

중요한 건 요율을 적어 두는 게 아니라 그 금액이 실제로 자산에서 빠지는지다. 매수 시에는 현금에서 수수료까지 차감하고, 평균 단가에도 매수 수수료를 포함시켜 나중 손익 계산이 부풀지 않게 했다. 매도 시에는 수령액에서 세 가지 비용을 모두 뺀다. 검증은 단순하다. 같은 전략을 수수료 0%와 0.25%로 각각 돌려 성과가 반드시 단조적으로 나빠지는지 확인하면 된다.

비용 가정 하나가 결론을 뒤집는다

이 규칙이 왜 중요한지는 비교 사례가 가장 잘 보여준다. 7일 최소 변동폭 돌파를 노리는 고빈도 전략은 수수료를 0으로 두면 10년 수익률 +92%가 나온다. 그런데 같은 코드에 0.25%를 넣으면 −64%가 된다. 로직에 엣지가 없어서가 아니라 엣지가 전부 비용으로 나가기 때문이다.

학술 연구에서도 같은 구조를 볼 수 있다. 자라티니와 아지즈가 2024년에 발표한 데이트레이딩 논문은 5분 개장 범위 돌파 전략을 검증해 2016~2023년 누적 1,484%(같은 기간 QQQ 보유는 169%)라는 결과를 제시했다. 인상적인 숫자지만 가정을 함께 읽어야 한다. 이 연구는 수수료를 주당 $0.0005로 두고 매수·매도 스프레드와 슬리피지를 0으로 가정했다.

$50 주식 1주를 거래할 때 주당 $0.0005는 약 0.001%다. 내 계좌의 0.25%와는 200배 이상 차이가 난다. 같은 전략, 같은 데이터라도 이 숫자를 바꾸면 결론의 부호가 바뀐다. 논문이 틀렸다는 게 아니라, 백테스트 결과는 언제나 비용 가정과 함께 읽어야 한다는 뜻이다.

그래서 하네스는 모든 전략의 결과를 수수료 0% · 0.07% · 0.25% 세 가지로 함께 출력하게 만들었다. 어떤 전략이 비용에 민감하고 어떤 전략이 둔감한지가 한눈에 보이면, 내 계좌 요율에 맞는 선택을 할 수 있다.

규칙 4 — 완성된 하네스를 스스로 공격한다

코드를 다 만든 뒤, 결과를 보기 전에 하네스 자체를 검증했다. 세 가지 차원을 각각 독립적으로 “이 하네스는 틀렸다”를 증명하려는 관점에서 점검했다. 결과는 두 개 통과, 하나 탈락이었다.

점검 차원 판정 근거
인과성 (미래 정보 사용) 통과 5일치 합성 데이터로 체결 시점 추적 — 신호일 다음 날 시가에만 체결됨을 확인
비용 모델 통과 상수·매수/매도 계산식·현금 제약을 손으로 재계산해 일치 확인
생존편향·체제의존 탈락 레버리지 ETF는 2010년 이후에만 존재 — 2000~2002·2008년 하락장이 표본에 없음

세 번째 항목은 코드로 고칠 수 있는 문제가 아니다. 데이터 자체가 없기 때문이다. 그래서 결과를 지우거나 감추는 대신 “이 숫자는 2010년 이후 강세장 조건부”라는 단서를 결과 문서에 박아 넣었다. 반대로 고빈도 매매가 비용으로 죽는다는 결론은 체제와 무관하게 강건하다. 비용은 시장 상황과 상관없이 항상 같은 방향으로 빠져나가기 때문이다. 같은 하네스에서 나온 결과라도 신뢰도는 항목마다 다르다는 걸 구분해 두는 게 중요했다.

많이 시도할수록 위험해진다

직전 연구에서 파라미터 81개 조합을 전부 돌렸다는 이야기를 했다. 그런데 조합을 많이 시도하는 행위 자체가 위험하다는 게 이 분야의 정설이다. 베일리·보웨인·로페즈 데 프라도·주가 2014년 미국수학회 회보에 실은 연구는 이 문제를 정면으로 다룬다. 요지는 두 가지다.

시도한 조합 수가 많아질수록 훌륭해 보이는 백테스트를 우연히 얻을 확률이 커진다. 충분히 많이 돌리면 실력 없는 전략도 화려한 성적표를 만들어낸다.
▶ 게다가 과최적화된 전략의 실전 기대수익은 0이 아니라 마이너스가 되기 쉽다. 시장에 기억 효과가 있기 때문이다.

여기서 이 연구가 지적하는 또 하나의 문제가 뼈아프다. 대부분의 보고서는 몇 개의 조합을 시도했는지 밝히지 않는다. 그래서 읽는 사람은 과최적화 정도를 판단할 방법이 없다. 그렇다면 최소한 내 기록에서는 시도 횟수를 밝히고, 표본이 얇은 결과는 얇다고 쓰는 게 맞다고 판단했다.

실무적으로는 두 가지 습관을 하네스 사용 규칙으로 굳혔다. 첫째, 어떤 결과든 상위 1~2거래를 제거하고 다시 계산한다. 이 검증에서 부호가 바뀌면 그 수익은 운이다. 둘째, 서브 기간으로 쪼개 본다. 10년 성적이 좋아도 특정 2년이 전부를 만들었다면 그 전략의 성격은 완전히 다르다.

불리한 방향으로만 남긴 오차

하네스에는 알고도 고치지 않은 부분이 하나 있다. 위험 회피 구간에서 현금을 들고 있는 대신 단기채 ETF로 옮기도록 설계했는데, 이러면 진입·이탈마다 왕복 거래가 한 번 더 생겨 비용이 실제보다 두 배 가까이 과대 계산된다. 추세 전략 하나는 표기된 누적 비용이 약 $1,012였지만, 현금으로 대기했다면 $542 수준이었다.

이 오차를 남겨 둔 이유는 방향이 내 결론에 불리한 쪽이기 때문이다. 추세 전략이 좋다는 결론을 얻고 싶었는데, 이 편의는 추세 전략을 실제보다 나쁘게 보이게 만든다. 결론을 유리하게 만드는 가정은 의심해야 하지만, 불리하게 만드는 가정은 안전 마진으로 남겨 두는 게 낫다. 백테스트에서 지켜야 할 최소한의 정직함은 오차의 방향을 아는 것이라고 생각한다.

하네스 최종 스펙

항목 설정
시작 자본 $1,000, 달러 잔고 내 거래(환전 0)
체결 규칙 t일 종가 신호 → t+1일 시가 체결 (1일 지연 강제)
주식 단위 정수주만 (내림), 잔여는 현금 · 수익률 0%
주문 순서 매도 후 매수, 현금 제약 적용(음수 현금 불가)
비용 수수료 0.25%/편도 + 슬리피지 0.05%/편도 + 매도 시 미국 규제 수수료 2종
유니버스 지수·레버리지·채권·해외·섹터·팩터 ETF와 대형주 등 35종
평가 기간 주 기간 2017~2026, 보조 기간 2011~2026(지표는 그 이전 데이터로 워밍업)
출력 전략별 연복리수익률·최대낙폭·샤프·총비용 + 수수료 3단계 민감도 + 서브 기간

가격 데이터는 배당을 재투자한 총수익 기준으로 받아 캐시에 저장했다. 배당을 빼면 장기 보유 전략이 부당하게 불리해지기 때문이다. 이런 사소해 보이는 선택들이 모여 “전략 간 비교가 공정한가”를 결정한다.

자를 먼저 만들면 남는 것

하네스를 만드는 데 든 시간은 전략 하나를 더 튜닝하는 것보다 훨씬 오래 걸렸다. 그런데 결과적으로는 남는 장사였다. 자가 하나 생기고 나니 30개가 넘는 매매법을 같은 조건에서 줄 세울 수 있었고, 어떤 결론이 강건하고 어떤 결론이 표본에 의존하는지 구분할 수 있게 됐다.

직접 하네스를 만들 계획이라면 순서를 이렇게 권하고 싶다. 먼저 체결 지연을 골격에 박고, 그 다음 비용을 실제 요율로 넣고, 소액이면 정수주를 강제하고, 마지막으로 결과를 보기 전에 하네스를 공격해 본다. 순서를 바꾸면 이미 나온 숫자에 미련이 생겨서 검증이 느슨해진다.

다음 글에서는 이 하네스로 실제로 돌린 결과를 다룬다. $1,000이라는 제약 안에서 30가지 넘는 매매법을 같은 조건으로 비교했을 때 무엇이 살아남았는지, 그리고 그 답이 왜 “더 잘 매매하기”가 아니라 “덜 매매하기”였는지에 대한 이야기다.

📎 이 글의 수치는 개인 자동매매 봇의 자체 백테스트와 실거래 기록에서 나온 것으로, 특정 종목·전략의 미래 성과를 보장하지 않습니다. 과거 데이터에 기반한 검증 결과는 실제 운용 성과와 다를 수 있으며, 레버리지 ETF는 변동성이 크고 장기 보유 시 기초지수와 수익률이 크게 달라질 수 있습니다.

G
GraceMoon
데이터로 보는 시장·일상 기록

공개 데이터(시장·뉴스·실거래)를 모아 직접 정리하고, 올리기 전에 사실관계를 한 번 더 확인합니다.

본 글은 공개된 데이터와 출처를 바탕으로 작성했습니다. 최종 업데이트: 2026-07-30

댓글 달기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

위로 스크롤