파이썬 백테스팅 실전 가이드

백테스팅이란?

백테스팅(Backtesting)은 과거 데이터를 기반으로 트레이딩 전략의 성과를 검증하는 과정입니다. 퀀트 투자와 자동매매 시스템을 구축할 때, 실제 자금을 투입하기 전 반드시 거쳐야 할 핵심 단계입니다. 아무리 논리적으로 완벽해 보이는 전략이라도 백테스팅 없이 실전에 투입하면 예상치 못한 손실을 맞을 수 있습니다.

파이썬 백테스팅 프레임워크 비교

파이썬 생태계에는 다양한 백테스팅 프레임워크가 존재합니다. 각각의 특징을 이해하고 목적에 맞는 도구를 선택하는 것이 중요합니다.

Backtrader

가장 널리 사용되는 파이썬 백테스팅 프레임워크입니다. 이벤트 기반(event-driven) 구조로, 실제 매매 흐름과 유사한 방식으로 전략을 테스트할 수 있습니다.

import backtrader as bt

class SmaCross(bt.Strategy):
    params = dict(fast=10, slow=30)

    def __init__(self):
        sma_fast = bt.ind.SMA(period=self.p.fast)
        sma_slow = bt.ind.SMA(period=self.p.slow)
        self.crossover = bt.ind.CrossOver(sma_fast, sma_slow)

    def next(self):
        if self.crossover > 0:
            self.buy()
        elif self.crossover < 0:
            self.sell()

cerebro = bt.Cerebro()
cerebro.addstrategy(SmaCross)
data = bt.feeds.YahooFinanceData(dataname='BTC-USD',
                                  fromdate=datetime(2024, 1, 1),
                                  todate=datetime(2025, 12, 31))
cerebro.adddata(data)
cerebro.run()
cerebro.plot()

Backtrader는 내장 지표가 풍부하고 커뮤니티가 활성화되어 있어 초보자에게 추천합니다. 다만 대규모 데이터에서는 속도가 느릴 수 있습니다.

Vectorbt

벡터 연산 기반으로 동작하여 Backtrader 대비 수십 배 빠른 속도를 제공합니다. NumPy와 Pandas를 활용한 벡터화(vectorized) 백테스팅에 최적화되어 있어, 대량의 파라미터 조합을 빠르게 탐색할 때 유리합니다.

import vectorbt as vbt

price = vbt.YFData.download('BTC-USD',
                             start='2024-01-01',
                             end='2025-12-31').get('Close')

fast_ma = vbt.MA.run(price, window=10)
slow_ma = vbt.MA.run(price, window=30)

entries = fast_ma.ma_crossed_above(slow_ma)
exits = fast_ma.ma_crossed_below(slow_ma)

pf = vbt.Portfolio.from_signals(price, entries, exits, init_cash=10000)
print(pf.stats())

Zipline

Quantopian에서 개발한 프레임워크로, 기관급 백테스팅 환경을 제공합니다. 슬리피지, 수수료, 시장 영향(market impact) 모델링이 정교하여 현실에 가까운 시뮬레이션이 가능합니다.

백테스팅 핵심 지표 해석

백테스팅 결과를 올바르게 해석하려면 다음 지표들을 반드시 확인해야 합니다.

지표 의미 기준값
총 수익률 전체 기간 누적 수익 벤치마크 대비 초과 여부
최대 낙폭(MDD) 고점 대비 최대 하락폭 20% 이하 권장
샤프 비율 위험 대비 수익 효율 1.0 이상 양호
승률 이긴 거래 비율 전략에 따라 다름
손익비(Profit Factor) 총이익 / 총손실 1.5 이상 권장

특히 최대 낙폭(MDD)은 실전 운용 시 심리적으로 견딜 수 있는 수준인지 반드시 점검해야 합니다. 백테스팅에서 MDD 40%인 전략은 실전에서 50% 이상 낙폭이 발생할 수 있습니다.

백테스팅의 함정: 과최적화

백테스팅에서 가장 흔한 실수는 과최적화(Overfitting)입니다. 과거 데이터에 지나치게 맞추면 미래에는 전혀 통하지 않는 전략이 만들어집니다.

과최적화 방지 체크리스트

  • Out-of-Sample 테스트: 데이터를 학습 구간(70%)과 검증 구간(30%)으로 분리합니다. 학습 구간에서 만든 전략이 검증 구간에서도 유효한지 확인합니다.
  • Walk-Forward 분석: 시간을 이동하면서 반복 테스트합니다. 2020-2023 학습 → 2024 검증, 2021-2024 학습 → 2025 검증 식으로 진행합니다.
  • 파라미터 민감도: 파라미터를 조금 바꿨을 때 결과가 크게 변하면 과최적화 가능성이 높습니다. 안정적인 파라미터 영역(plateau)을 찾으세요.
  • 거래 횟수: 최소 100회 이상의 거래가 포함되어야 통계적 신뢰도를 확보할 수 있습니다.

실전 백테스팅 워크플로우

효과적인 백테스팅은 단순히 코드를 돌리는 것이 아닙니다. 체계적인 워크플로우를 따라야 합니다.

1단계: 가설 수립

"이동평균 크로스가 추세 전환을 포착할 수 있다"처럼 명확한 가설을 먼저 세웁니다. 가설 없이 파라미터를 무작위로 탐색하면 과최적화의 늪에 빠집니다.

2단계: 데이터 준비

데이터 품질이 백테스팅 결과의 신뢰도를 결정합니다. 누락된 캔들, 잘못된 가격, 생존자 편향(survivorship bias) 등을 점검해야 합니다.

import pandas as pd

# 데이터 품질 점검
df = pd.read_csv('btc_1h.csv', parse_dates=['timestamp'])
print(f"결측치: {df.isnull().sum().sum()}")
print(f"중복: {df.duplicated().sum()}")
print(f"기간: {df['timestamp'].min()} ~ {df['timestamp'].max()}")

# 캔들 연속성 확인
gaps = df['timestamp'].diff().dt.total_seconds() / 3600
print(f"누락 캔들: {(gaps > 1.5).sum()}개")

3단계: 전략 구현 및 테스트

선택한 프레임워크에서 전략을 구현하고, 수수료와 슬리피지를 반드시 포함하여 테스트합니다. 계좌 생존 규칙을 먼저 숙지한 뒤 백테스팅에 반영하는 것을 권장합니다.

4단계: 결과 분석 및 개선

단순 수익률보다 위험 지표를 우선 확인합니다. 복구매매 패턴에서 다루었듯, 큰 낙폭 이후의 행동이 전략 성과를 좌우합니다.

5단계: 페이퍼 트레이딩

백테스팅 결과가 만족스럽다면 실제 시장에서 가상 자금으로 운용합니다. 최소 1~3개월간 라이브 환경에서 검증한 뒤 실전 투입을 결정합니다.

수수료와 슬리피지: 현실의 벽

많은 초보 퀀트 트레이더가 수수료와 슬리피지를 과소평가합니다. 특히 고빈도 전략에서는 이 비용이 수익을 완전히 잠식할 수 있습니다.

  • 거래소 수수료: 바이낸스 선물 기준 메이커 0.02%, 테이커 0.04%. 하루 10회 거래 시 연간 수수료만 약 100%에 달할 수 있습니다.
  • 슬리피지: 주문 체결 시 예상 가격과 실제 체결 가격의 차이. 유동성이 낮은 시간대나 급변 구간에서 커집니다.
  • 펀딩비: 선물 포지션 유지 시 8시간마다 발생. 장기 보유 전략에서 무시할 수 없는 비용입니다.

백테스팅에서 이 비용들을 현실적으로 반영하지 않으면, 실전 성과는 백테스팅 대비 크게 열화됩니다.

마무리: 백테스팅은 시작일 뿐

파이썬 백테스팅은 퀀트 투자의 필수 관문이지만, 그것만으로 수익이 보장되지는 않습니다. 과최적화를 경계하고, 현실적인 비용을 반영하며, 페이퍼 트레이딩으로 충분히 검증한 뒤에 실전에 나서야 합니다. 도구를 익히는 것보다 중요한 건 전략의 논리와 위험 관리입니다.

위로 스크롤
WordPress Appliance - Powered by TurnKey Linux