여러분, 이런 경험 있으시죠? "기막힌" 거래 전략을 떠올리고 실제 자금을 투입했는데, 결과적으로 전혀 수익이 안 났던 경험이요.
실제 돈을 넣기 전에 전략이 유효한지 미리 검증하는 방법이 있습니다. 바로 백테스트(Backtesting)예요.
오늘은 올바르게 전략 백테스트를 하는 방법을 이야기해 보겠습니다.
백테스트란?
백테스트는 과거 데이터를 사용하여 거래 전략의 실행을 시뮬레이션하는 것입니다. 과거에 이 전략대로 거래했다면 결과가 어땠을지 확인하는 거죠.
비유하자면, 새로운 바둑 전법을 개발했을 때 과거의 기보를 꺼내서 검증하는 것과 같아요. 내 전법으로 두었다면 이겼을지 졌을지?
물론 과거 성과가 미래 결과를 보장하지는 않습니다. 하지만 최소한, 과거 데이터에서도 돈을 벌지 못하는 전략이 실전에서 돈을 벌 확률은 더 낮죠.
왜 백테스트를 해야 하나요?
1. 전략 유효성 검증
이동평균선 골든크로스에서 매수해야 한다고 생각하시나요? 백테스트를 해보면 이 전략이 정말 수익을 낼 수 있는지 알 수 있습니다.
2. 전략 성과 수치화
백테스트는 구체적인 데이터를 제공합니다: 연간 수익률, 최대 낙폭, 승률, 손익비 등. 이 데이터가 있어야 전략의 좋고 나쁨을 객관적으로 평가할 수 있어요.
3. 파라미터 최적화
같은 이평선 전략이라도 7일과 25일 이평선이 좋을지, 10일과 50일 이평선이 좋을지? 백테스트가 최적 파라미터를 찾아줍니다.
4. 자신감 구축
자신의 전략이 과거 5년 데이터에서 양호한 성과를 보였음을 알면, 실전에서 더 자신감을 가지고 단기 변동에 쉽게 포기하지 않게 됩니다.
5. 문제 발견
어떤 전략은 겉보기에 좋지만 숨겨진 리스크가 있을 수 있어요. 예를 들어 승률 99%인데 그 1%의 손실이 치명적인 경우. 백테스트가 이런 문제를 발견해줍니다.
백테스트의 기본 절차
1단계: 전략 규칙 명확화
백테스트 전에 전략의 모든 규칙을 명확히 적어야 합니다:
- 진입 조건: 어떤 상황에서 매수?
- 청산 조건: 어떤 상황에서 매도?
- 포지션 관리: 매번 얼마나 매수?
- 손절 규칙: 얼마 손실에서 청산?
- 익절 규칙: 얼마 수익에서 청산?
- 기타 제약: 최대 보유 포지션 수, 거래 시간 제한 등
규칙은 구체적일수록 좋습니다. 규칙에 "느낌", "대략" 같은 단어가 있다면 아직 충분히 구체적이지 않은 겁니다.
2단계: 과거 데이터 수집
백테스트할 거래쌍의 과거 캔들 데이터가 필요합니다.
바이낸스에서 수집:
from binance.client import Client
client = Client(api_key, api_secret)
# BTC/USDT 2020년부터 현재까지 일봉 데이터 수집
klines = client.get_historical_klines(
"BTCUSDT",
Client.KLINE_INTERVAL_1DAY,
"1 Jan 2020",
"1 Jan 2026"
)
데이터 품질이 중요합니다:
- 데이터가 충분히 길어야 함(최소 하나의 완전한 상승·하락 사이클 포함)
- 데이터가 정확해야 함(시가, 고가, 저가, 종가, 거래량)
- 시간 정밀도가 전략에 맞아야 함(일봉 전략은 일봉 데이터, 분봉 전략은 분봉 데이터)
3단계: 백테스트 코드 작성
코드로 전략의 실행 과정을 시뮬레이션합니다.
간단한 예시(Python):
import pandas as pd
# 데이터 로드
df = pd.DataFrame(klines, columns=[
'timestamp', 'open', 'high', 'low', 'close',
'volume', 'close_time', 'quote_volume', 'trades',
'buy_base', 'buy_quote', 'ignore'
])
df['close'] = df['close'].astype(float)
df['ma7'] = df['close'].rolling(7).mean()
df['ma25'] = df['close'].rolling(25).mean()
# 거래 시뮬레이션
position = 0 # 0=무포지션, 1=보유
entry_price = 0
trades = []
for i in range(25, len(df)):
# 골든크로스 매수
if df['ma7'].iloc[i] > df['ma25'].iloc[i] and \
df['ma7'].iloc[i-1] <= df['ma25'].iloc[i-1] and \
position == 0:
position = 1
entry_price = df['close'].iloc[i]
# 데드크로스 매도
elif df['ma7'].iloc[i] < df['ma25'].iloc[i] and \
df['ma7'].iloc[i-1] >= df['ma25'].iloc[i-1] and \
position == 1:
position = 0
exit_price = df['close'].iloc[i]
profit = (exit_price - entry_price) / entry_price
trades.append(profit)
# 결과 통계
if trades:
wins = [t for t in trades if t > 0]
losses = [t for t in trades if t <= 0]
print(f"총 거래 횟수: {len(trades)}")
print(f"승률: {len(wins)/len(trades)*100:.1f}%")
print(f"평균 수익: {sum(wins)/len(wins)*100:.2f}%" if wins else "수익 없음")
print(f"평균 손실: {sum(losses)/len(losses)*100:.2f}%" if losses else "손실 없음")
print(f"총 수익: {(1+sum(trades)/len(trades))**len(trades)-1:.2%}")
4단계: 백테스트 결과 분석
백테스트 완료 후 다음 핵심 지표를 분석해야 합니다:
연간 수익률: 전략의 연간 수익. 단순 보유(Buy & Hold)와 비교.
최대 낙폭: 최고점에서 최저점까지의 최대 하락폭. 낙폭이 너무 큰 전략은 실전에서 버티기 힘듦.
샤프 비율: 리스크 대비 수익률 측정. 샤프 비율 1 이상은 수용 가능, 2 이상은 우수.
승률: 수익 거래가 전체에서 차지하는 비율. 승률만 높다고 좋은 게 아니라 손익비와의 조합이 핵심.
손익비: 평균 수익/평균 손실. 1.5 이상이 바람직.
거래 빈도: 거래 횟수가 적절한지? 너무 잦으면 수수료 과다, 너무 적으면 데이터 신뢰성 부족.
수익 곡선: 자금 곡선 그래프를 그려 완만한 상승인지 큰 기복인지 확인.
5단계: 최적화 및 검증
백테스트 결과를 바탕으로 파라미터를 조정하고 재백테스트. 하지만 여기에 큰 함정이 있습니다 -- 과적합.
흔한 백테스트 함정
함정 1: 과적합(Overfitting)
가장 흔하고 위험한 함정입니다.
과적합이란: 파라미터를 계속 조정하여 전략이 과거 데이터에서 완벽하게 동작하도록 만들었지만, 이 파라미터는 과거 데이터에만 맞고 새 데이터에서는 전혀 작동하지 않을 수 있습니다.
방지법:
- 데이터를 "학습 세트"와 "테스트 세트"로 나누어, 학습 세트로 최적화하고 테스트 세트로 검증
- 파라미터를 너무 많이 두지 않기. 파라미터가 많을수록 과적합 가능성 증가
- 전략 로직에 시장 논리가 뒷받침되어야 함, 순수 데이터 피팅은 금지
함정 2: 선행 편향(Look-Ahead Bias)
백테스트에서 당시에는 알 수 없었던 정보를 사용하는 것.
예시: 오늘의 종가를 기준으로 오늘의 거래를 결정 -- 실제 거래에서는 거래 시점에 종가를 알 수 없음.
방지법: 모든 거래 결정이 해당 시점 이전의 데이터만 사용하도록 보장.
함정 3: 거래 비용 무시
백테스트에서 수수료, 슬리피지 등 비용을 고려하지 않는 것.
수익률 30%로 보이는 전략이 수수료를 빼면 10%만 되거나 오히려 손실일 수 있습니다. 특히 고빈도 전략에서 수수료의 영향이 매우 큽니다.
방지법: 백테스트에 실제 수수료율(본인의 VIP 등급 참고)을 넣고, 슬리피지 비용도 고려.
함정 4: 생존 편향(Survivorship Bias)
현재 존재하는 코인만 백테스트하고, 이미 0이 되어 상장 폐지된 코인을 무시하는 것.
현재 시총 상위 20개 코인만 백테스트하면 결과가 당연히 좋습니다 -- 그들은 "생존자"니까요. 하지만 몇 년 전에는 어떤 코인이 살아남을지 알 수 없었죠.
함정 5: 시장 환경 무시
2021년 상승장에서는 거의 모든 전략이 수익을 냅니다. 백테스트가 상승장만 포함했다면, 하락장에서 전략 성과가 매우 나쁠 수 있어요.
방지법: 백테스트 데이터가 최소 하나의 완전한 상승·하락 사이클을 포함하도록.
백테스트 도구 추천
TradingView Pine Script
프로그래밍에 익숙하지 않다면 TradingView의 Pine Script가 가장 쉬운 입문 도구입니다.
- 차트에서 직접 전략 작성 및 실행
- 내장 전략 테스터가 자동으로 백테스트 보고서 생성
- 시각화 효과 우수
- 중저빈도 전략 백테스트에 적합
Python + Backtrader
Backtrader는 Python에서 가장 인기 있는 백테스트 프레임워크 중 하나입니다.
- 기능 강력, 다양한 전략 유형 지원
- 지표와 거래 로직 커스텀 가능
- 다종목, 다전략 지원
- 학습 곡선이 다소 가파름
Python + Zipline
Quantopian(폐쇄됨)이 개발한 백테스트 프레임워크.
- 코드 구조가 깔끔
- 커뮤니티 리소스 풍부
- 주식 시장에 적합하지만 암호화폐에도 사용 가능
바이낸스 과거 데이터
바이낸스는 완전한 과거 캔들 데이터 다운로드를 제공합니다:
- API를 통한 데이터 수집
- 또는 바이낸스 데이터 페이지에서 직접 CSV 파일 다운로드
백테스트에서 실전으로
백테스트를 통과했다고 바로 큰 자금으로 실전에 돌입하지 마세요. 다음 순서를 추천합니다:
1. 모의 거래 테스트
먼저 모의 자금으로 전략을 최소 1~3개월 실행. 실제 성과가 백테스트와 일치하는지 관찰.
2. 소액 실전
총 자금의 5~10%로 실전 운영. 실전에서는 백테스트에 없던 문제들(슬리피지, API 지연, 네트워크 문제 등)이 발생하므로 이 단계가 매우 중요합니다.
3. 점진적 증액
소액 실전이 3개월 이상 안정적이면 점차 자금을 늘립니다.
4. 지속 모니터링
실전 운영 후 전략 성과를 지속 모니터링. 실제 성과가 백테스트 예상치에서 계속 벗어나면 전략을 재평가해야 합니다.
실전 조언
-
단순한 전략이 더 좋은 경우가 많습니다. 파라미터가 적고 로직이 명확한 전략일수록 과적합하기 어렵습니다.
-
완벽한 백테스트를 추구하지 마세요. 연 20% 수익, 최대 낙폭 10%의 전략이 연 100% 수익, 최대 낙폭 50%의 전략보다 더 신뢰할 만합니다.
-
다기간 검증. 다른 시간대에서도 백테스트하여 전략의 안정성을 확인하세요.
-
실제 실행 가능성 고려. 백테스트에서는 가능하지만 실제로는 비현실적인 전략(예: 1초 안에 조작 완료가 필요한 경우)도 있습니다.
-
백테스트 습관 형성. 새로운 거래 아이디어가 생길 때마다 먼저 백테스트하고 실행하세요. 이 습관이 많은 충동적 거래를 방지해줍니다.
정리
백테스트는 거래 시스템 구축의 기초 단계입니다. 미래 수익을 보장하지는 못하지만, 최소한 명확히 실행 불가능한 전략을 걸러낼 수 있어요.
백테스트의 핵심 원칙을 기억하세요:
- 규칙은 명확하고 구체적이어야 함
- 데이터는 충분히 길고 정확해야 함
- 과적합을 경계
- 모든 거래 비용을 고려
- 백테스트에서 실전으로 점진적으로 이행
시간을 들여 백테스트를 배우는 것이 시장에서 "학비"를 내는 것보다 훨씬 효율적입니다.
전략을 검증할 준비가 되셨나요? 먼저 바이낸스 계정을 등록하여 과거 데이터를 수집하세요.