반응형
✅ 5단계 개요: 백테스트가 왜 중요한가요?
실시간 매매 전에 반드시 백테스트를 해야 하는 이유:
- 과거 시장에서 전략이 수익이 났는지 확인
- 전략이 폭락장에서 살아남는지 검증
- 실제 자동매매 시 수익률, 손절, 최대 낙폭(MDD) 등 예측 가능
🔁 STEP 1. 과거 데이터 요청하기 (차트데이터 TR: opt10081)
python
kiwoom.SetInputValue("종목코드", "005930")
kiwoom.SetInputValue("기준일자", "20240401") # yyyyMMdd
kiwoom.SetInputValue("수정주가구분", "1")
kiwoom.CommRqData("일봉차트", "opt10081", 0, "1001")
항목 | 설명 |
opt10081 | 일봉차트 요청 |
기준일자 | 오늘 이전 날짜 기준으로 조회 |
수정주가구분 | 1 = 수정주가 기준 |
📷 차트 데이터 예시
text
[일자: 20240401] 시가: 78,100 / 고가: 79,300 / 저가: 77,900 / 종가: 78,900 / 거래량: 3,200,000
🧾 STEP 2. Pandas로 백테스트 프레임 만들기
🔹 데이터프레임 생성 예제
python
import pandas as pd
dates, opens, highs, lows, closes, volumes = [], [], [], [], [], []
for i in range(100): # 100일치 데이터
date = kiwoom.GetCommData("opt10081", "일봉차트", i, "일자").strip()
open_ = kiwoom.GetCommData("opt10081", "일봉차트", i, "시가").strip()
high = kiwoom.GetCommData("opt10081", "일봉차트", i, "고가").strip()
low = kiwoom.GetCommData("opt10081", "일봉차트", i, "저가").strip()
close = kiwoom.GetCommData("opt10081", "일봉차트", i, "현재가").strip()
volume = kiwoom.GetCommData("opt10081", "일봉차트", i, "거래량").strip()
dates.append(date)
opens.append(int(open_))
highs.append(int(high))
lows.append(int(low))
closes.append(int(close))
volumes.append(int(volume))
df = pd.DataFrame({
'date': pd.to_datetime(dates),
'open': opens,
'high': highs,
'low': lows,
'close': closes,
'volume': volumes
})
df.sort_values('date', inplace=True)
df.set_index('date', inplace=True)
📈 STEP 3. 간단한 전략 테스트: 이동평균선 돌파
python
df['ma5'] = df['close'].rolling(5).mean()
df['ma20'] = df['close'].rolling(20).mean()
df['signal'] = (df['ma5'] > df['ma20']).astype(int)
df['position'] = df['signal'].diff()
📷 매매 시점 시각화 (matplotlib)
python
import matplotlib.pyplot as plt
plt.figure(figsize=(12, 6))
plt.plot(df['close'], label='Close')
plt.plot(df['ma5'], label='MA5')
plt.plot(df['ma20'], label='MA20')
plt.scatter(df[df['position'] == 1].index, df[df['position'] == 1]['close'], marker='^', color='green', label='Buy')
plt.scatter(df[df['position'] == -1].index, df[df['position'] == -1]['close'], marker='v', color='red', label='Sell')
plt.title("이동평균선 골든크로스 전략")
plt.legend()
plt.grid()
plt.show()
📊 STEP 4. 수익률 계산 (누적 수익률 / MDD)
python
df['daily_return'] = df['close'].pct_change()
df['strategy_return'] = df['daily_return'] * df['signal'].shift(1)
df['cumulative'] = (1 + df['strategy_return']).cumprod()
plt.figure(figsize=(12, 4))
plt.plot(df['cumulative'], label='Strategy')
plt.title("전략 누적 수익률")
plt.grid()
plt.legend()
plt.show()
📌 옵션: MDD 계산 (최대 낙폭)
python
df['cummax'] = df['cumulative'].cummax()
df['drawdown'] = df['cumulative'] / df['cummax'] - 1
mdd = df['drawdown'].min()
print(f"📉 최대 낙폭(MDD): {mdd:.2%}")
🧠 실전 백테스트 팁
체크항목 | 설명 |
거래 비용 포함 여부 | 매수/매도 수수료, 세금 등 고려해야 신뢰 ↑ |
슬리피지 | 체결 지연, 가격 차이 고려 |
거래 제한 | 매수가능 수량, 시간 제한 조건 등 |
반응형