반응형
백테스트를 통해 가벼운 전략의 결과를 보았으니
이제 전략을 다듬어가며 나에게 맞는, 더 좋은 결과를 내는 전략을 찾아가는 과정이 필요하겠다.
그러기 위해서 먼저 코드를 구조화 하는 것도 필요하다.
1. 전체 코드 개요
backtest/
├── backtest.py ← 실행 진입점
├── strategy.py ← 전략 정의 (볼린저 밴드, RSI 등)
├── analyzer.py ← 수익률, 승률, 낙폭 계산
├── plotter.py ← 수익곡선 시각화
2. strategy.py – 전략 모듈화
# strategy.py
def calculate_indicators(df):
import pandas as pd
import numpy as np
df['ma20'] = df['close'].rolling(window=20).mean()
std = df['close'].rolling(window=20).std()
df['bb_upper'] = df['ma20'] + 2 * std
df['bb_lower'] = df['ma20'] - 2 * std
delta = df['close'].diff()
gain = delta.where(delta > 0, 0)
loss = -delta.where(delta < 0, 0)
avg_gain = gain.rolling(14).mean()
avg_loss = loss.rolling(14).mean()
rs = avg_gain / avg_loss
df['rsi14'] = 100 - (100 / (1 + rs))
return df
def bollinger_rsi_strategy(df):
position = None
entry_price = 0
trades = []
for i in range(1, len(df)):
row = df.iloc[i]
if position is None:
if row['close'] < row['bb_lower'] and row['rsi14'] < 30:
position = 'long'
entry_price = row['close']
entry_time = row['timestamp']
elif position == 'long':
if row['close'] > row['ma20']:
exit_price = row['close']
exit_time = row['timestamp']
ret = (exit_price - entry_price) / entry_price
trades.append({'entry': entry_time, 'exit': exit_time, 'return': ret})
position = None
return trades
3. analyzer.py – 수익률 분석
# analyzer.py
import pandas as pd
import numpy as np
def analyze_trades(trades):
if not trades:
return None
returns = [t['return'] for t in trades]
cum_returns = pd.Series([1 + r for r in returns]).cumprod() - 1
win_rate = sum(1 for r in returns if r > 0) / len(returns)
avg_return = np.mean(returns)
total_return = cum_returns.iloc[-1]
return {
'count': len(returns),
'win_rate': win_rate,
'avg_return': avg_return,
'total_return': total_return,
'cum_returns': cum_returns
}
4. plotter.py – 수익곡선 그리기
# plotter.py
import matplotlib.pyplot as plt
def plot_cumulative_returns(cum_returns):
plt.figure(figsize=(10, 5))
plt.plot(cum_returns, marker='o')
plt.title('누적 수익률')
plt.xlabel('트레이드 순번')
plt.ylabel('누적 수익률')
plt.grid(True)
plt.tight_layout()
plt.show()
5. backtest.py – 실행 스크립트
# backtest.py
import ccxt
import pandas as pd
from strategy import calculate_indicators, bollinger_rsi_strategy
from analyzer import analyze_trades
from plotter import plot_cumulative_returns
# 데이터 로딩
binance = ccxt.binance({'enableRateLimit': True})
symbol = 'BTC/USDT'
ohlcv = binance.fetch_ohlcv(symbol, timeframe='5m', limit=5000)
df = pd.DataFrame(ohlcv, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')
# 지표 계산 및 전략 실행
df = calculate_indicators(df)
trades = bollinger_rsi_strategy(df)
# 분석 및 시각화
result = analyze_trades(trades)
if result:
print(f"총 거래 수: {result['count']}")
print(f"승률: {result['win_rate']*100:.2f}%")
print(f"평균 수익률: {result['avg_return']*100:.2f}%")
print(f"누적 수익률: {result['total_return']*100:.2f}%")
plot_cumulative_returns(result['cum_returns'])
else:
print("거래 없음")
마무리하며
이번 글에서는 백테스트 코드를 구조화하고,
볼린저 밴드 + RSI 전략을 모듈로 정리해서 확장 가능하고 재사용 가능한 형태로 발전시켰다.
이제 다른 전략도 쉽게 추가할 수 있고, 여러 종목에 동시에 테스트하는 것도 가능하다.
반응형
'코인' 카테고리의 다른 글
| [실전 자동매매] 매매일지 20250826 (0) | 2025.08.27 |
|---|---|
| [실전 자동매매] 로봇 자동매매 실전편. 파일럿 시작 (5) | 2025.08.27 |
| [자동매매로봇 만들기][7편] 백테스트 결과 시각화 – 수익 흐름을 눈으로 확인하기 (0) | 2025.06.11 |
| [자동매매봇 만들기][6편] 백테스트로 전략 검증하기 – 과거 데이터로 수익률 확인하기 (0) | 2025.06.06 |
| [자동매매봇 만들기][5편] 텔레그램 봇 연동 – 매매 시그널 알림 보내기 (0) | 2025.05.17 |