반응형
지금까지는 실시간 데이터를 기반으로 전략을 만들고, 매매 시그널도 만들었다.
하지만 아직 전략의 "신뢰성"은 검증되지 않았다.
그 전략이 과거에도 통했는지, 어느 정도 수익이나 손실을 냈는지를 확인해야 한다.
그게 바로 **백테스트(Backtest)**다.
1. 백테스트 개념 정리
백테스트란?
과거의 시세 데이터에 내 전략을 그대로 적용해보고,
그 전략이 매수/매도 신호를 얼마나 정확하게 냈는지,
얼마의 수익 또는 손실을 냈는지를 계산해보는 작업이다.
2. 준비: OHLCV 데이터 불러오기
이번에는 실시간 API가 아니라, 백테스트용으로 저장된 데이터를 사용할 수도 있다.
하지만 간단히 하기 위해서, 바이낸스에서 가져온 5분봉 최근 500개의 데이터로 테스트하자.
import ccxt
import pandas as pd
binance = ccxt.binance({'enableRateLimit': True})
symbol = 'BTC/USDT'
ohlcv = binance.fetch_ohlcv(symbol, timeframe='5m', limit=500)
df = pd.DataFrame(ohlcv, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')
3. 지표 계산
RSI와 볼린저 밴드 중심 전략을 다시 구현한다.
# RSI 계산
def calculate_rsi(series, period=14):
delta = series.diff()
gain = delta.where(delta > 0, 0)
loss = -delta.where(delta < 0, 0)
avg_gain = gain.rolling(window=period).mean()
avg_loss = loss.rolling(window=period).mean()
rs = avg_gain / avg_loss
return 100 - (100 / (1 + rs))
df['rsi14'] = calculate_rsi(df['close'])
# 볼린저 밴드
period = 20
df['ma20'] = df['close'].rolling(window=period).mean()
std = df['close'].rolling(window=period).std()
df['bb_upper'] = df['ma20'] + 2 * std
df['bb_lower'] = df['ma20'] - 2 * std
4. 전략 로직 (간단한 매수/매도 조건)
- 매수 진입 조건: 종가가 볼린저 밴드 하단보다 낮고, RSI가 30 미만
- 청산 조건: 종가가 볼린저 중심선을 회복할 때 매도 (익절 or 손절)
position = None
entry_price = 0
returns = []
for i in range(1, len(df)):
row = df.iloc[i]
prev = df.iloc[i-1]
# 진입
if position is None:
if row['close'] < row['bb_lower'] and row['rsi14'] < 30:
position = 'long'
entry_price = row['close']
# 청산
elif position == 'long':
if row['close'] > row['ma20']: # 볼밴 중심선 회복 시 청산
exit_price = row['close']
ret = (exit_price - entry_price) / entry_price
returns.append(ret)
position = None
5. 수익률 분석
import numpy as np
if returns:
total_return = np.prod([1 + r for r in returns]) - 1
win_rate = sum(1 for r in returns if r > 0) / len(returns)
avg_profit = np.mean(returns)
print(f"총 거래 횟수: {len(returns)}")
print(f"승률: {win_rate * 100:.2f}%")
print(f"평균 수익률: {avg_profit * 100:.2f}%")
print(f"누적 수익률: {total_return * 100:.2f}%")
else:
print("거래 없음")
예시 출력:
총 거래 횟수: 8
승률: 62.50%
평균 수익률: 1.12%
누적 수익률: 9.37%
마무리하며
지표를 활용한 전략을 단순히 이론으로 만들고 끝나는 게 아니라,
실제로 수익이 났는지 수치로 확인하는 백테스트는 반드시 필요한 단계다.
지금은 아주 기본적인 전략과 조건으로 테스트했지만,
이걸 기반으로 더 정교한 전략으로 발전시킬 수 있다.
다.
반응형
'코인' 카테고리의 다른 글
[자동매매로봇 만들기] [8편] 전략 고도화 – 백테스트 구조화 & 볼린저 밴드 전략 모듈화 (0) | 2025.06.12 |
---|---|
[자동매매로봇 만들기][7편] 백테스트 결과 시각화 – 수익 흐름을 눈으로 확인하기 (0) | 2025.06.11 |
[자동매매봇 만들기][5편] 텔레그램 봇 연동 – 매매 시그널 알림 보내기 (0) | 2025.05.17 |
[자동매매봇 만들기][4편] 기술적 지표와 단순 매매 조건 구현하기 (0) | 2025.05.16 |
[자동매매봇 만들기][3편] 바이낸스에서 실시간 시세와 캔들 데이터 가져오기 (API 키 없이) (2) | 2025.05.14 |