튜토리얼약 5분 읽기

백테스트 과최적화 피하는 법 — 학습·검증 구간을 나누는 워크포워드 검증

백테스트 성과가 좋았는데 실전은 왜 다를까

이전 글 백테스팅이란 무엇인가에서 과최적화라는 함정의 존재를 짚었다. 문제는 함정이 있다는 걸 아는 것과, 실제로 그 함정에 빠졌는지 확인하는 방법을 아는 것이 다르다는 점이다. 파라미터를 이리저리 바꿔가며 백테스트 성과를 끌어올렸는데, 막상 실거래로 넘어가면 그 좋은 성과가 재현되지 않는 경우를 겪고 나서야 이 차이를 실감하게 된다.

이 글은 과최적화 개념 자체보다 "지금 이 전략이 과최적화됐는지 어떻게 확인하나"에 초점을 맞춘다. 코드는 이번에도 특정 전략 로직이 아닌 검증 절차를 다루는 의사코드다.

학습 구간과 검증 구간을 나눈다

파라미터(이동평균 기간, 손절 기준 등)를 조정하는 구간과 그 성과를 평가하는 구간을 반드시 분리해야 한다. 이를 각각 학습 구간(in-sample)과 검증 구간(out-of-sample)이라 부른다. 파라미터 튜닝은 학습 구간에서만 하고, 성과 평가는 검증 구간에서 한다. 검증 구간 성과가 학습 구간보다 크게 떨어진다면 과최적화를 의심해야 한다.

워크포워드 검증 — 구간을 옮겨가며 반복 검증한다

학습·검증 구간을 한 번만 나누는 것으로는 부족하다. 시간 축을 따라 구간을 계속 옮겨가며 같은 절차를 반복하는 방법이 워크포워드(Walk-forward) 검증이다.

python 코드 보기
def walk_forward_validate(prices, param_grid, train_size, test_size):
    results = []
    start = 0

    while start + train_size + test_size <= len(prices):
        train = prices[start : start + train_size]
        test = prices[start + train_size : start + train_size + test_size]

        best_params = tune_on_training_data(train, param_grid)
        test_performance = backtest(test, best_params)

        results.append({
            "train_range": (start, start + train_size),
            "params": best_params,
            "test_performance": test_performance,
        })

        start += test_size

    return results

여기서 중요한 건 튜닝은 항상 train에서만 이루어지고, 성과 평가는 그 파라미터를 한 번도 보지 않은 test 구간에서 측정한다는 점이다. 구간을 옮겨가며 여러 번 반복해, 특정 구간에만 맞는 우연의 결과가 아닌지 확인한다.

검증 결과를 해석하는 법 — 구간마다 파라미터가 다르다면

워크포워드마다 최적 파라미터가 크게 요동친다면(예: 어떤 구간은 짧은 이동평균이 최적, 다른 구간은 훨씬 긴 이동평균이 최적), 이는 전략이 특정 시장 상황에만 의존한다는 신호다. 안정적인 전략이라면 구간이 바뀌어도 최적 파라미터가 어느 정도 비슷한 범위에 머무는 경향을 보인다.

자주 하는 실수

  1. 학습 구간에서 나온 최고 성과를 그대로 실전 기대치로 삼는다. 학습 구간 성과는 그 구간에 맞춰진 결과일 뿐, 실전 기대치가 아니다.
  2. 검증 구간 성과가 나쁘게 나오면 검증 구간을 슬쩍 바꿔서 다시 돌린다. 이러면 검증 구간도 사실상 학습 구간이 되어버려 검증의 의미가 사라진다.
  3. 워크포워드를 한 번만 돌리고 끝낸다. 최소 여러 구간을 반복해야 우연인지 아닌지 구분할 수 있다.

오늘의 정리

  1. 과최적화를 예방하려면 파라미터 튜닝은 학습 구간에서만, 성과 평가는 검증 구간에서 분리해서 진행해야 한다.
  2. 워크포워드 검증은 학습·검증 구간을 시간순으로 옮겨가며 반복해, 특정 구간에만 맞는 우연의 결과인지 확인하는 방법이다.
  3. 구간마다 최적 파라미터가 크게 다르면 전략이 특정 시장 상황에 과도하게 의존한다는 신호로 봐야 한다.
  4. 검증 구간 성과가 나쁘다고 검증 구간 자체를 바꿔 다시 돌리면, 검증의 의미가 사라진다.

이 글의 코드는 검증 절차를 설명하기 위한 의사코드이며 특정 전략이나 실거래 시스템의 구현이 아닙니다. 이 글은 투자 조언이 아니며 특정 종목이나 매매기법을 추천하지 않습니다. 백테스트나 워크포워드 검증 결과가 좋다고 해서 미래 수익을 보장하지 않으며, 투자 손실에 대한 책임은 투자자 본인에게 있습니다.

← 전체 글 목록