3.7.4.2 파이썬 코드 구현
볼린저 밴드 변동성 돌파 전략을 파이썬 코드로 구현합니다. 이 섹션에서는 실제 코드를 통해 전략을 구체화합니다. 데이터 획득부터 백테스팅까지 전 과정을 다룹니다. 3.8 섹션에서 다룰 백테스팅 환경 구축을 염두에 둡니다.
1단계: 라이브러리 임포트
자동매매 시스템에 필요한 라이브러리를 가져옵니다. pandas
는 데이터 처리를 담당합니다. talib
은 볼린저 밴드 계산에 사용됩니다. pyupbit
은 업비트 API 연동을 지원합니다.
import pandas as pd
import talib
import pyupbit
2단계: 데이터 획득
업비트 API를 통해 가상화폐 데이터를 가져옵니다. pyupbit.get_ohlcv()
함수를 사용합니다. KRW-BTC
티커의 60분봉 데이터를 500개 가져옵니다. 필요에 따라 티커, 시간 간격, 데이터 개수를 조절합니다.
# 업비트 API를 통해 데이터 가져오기
df = pyupbit.get_ohlcv("KRW-BTC", interval="minute60", count=500)
3단계: 데이터 전처리
데이터프레임 컬럼명을 통일합니다. open
, high
, low
, close
, volume
으로 변경합니다. 이미 컬럼명이 일치하면 이 단계를 생략합니다.
# 컬럼명 변경 (필요한 경우)
df.rename(columns={'open': 'Open', 'high': 'High', 'low': 'Low', 'close': 'Close', 'volume': 'Volume'}, inplace=True)
4단계: 볼린저 밴드 계산
TA-Lib을 사용하여 볼린저 밴드를 계산합니다. talib.BBANDS()
함수를 사용합니다. 기간(timeperiod)은 20으로 설정합니다. 표준편차 배수(nbdevup, nbdevdn)는 2로 설정합니다. 이동평균 종류(matype)는 0 (SMA)으로 설정합니다.
# 볼린저 밴드 계산
df['BB_UPPER'], df['BB_MIDDLE'], df['BB_LOWER'] = talib.BBANDS(df['Close'], timeperiod=20, nbdevup=2, nbdevdn=2, matype=0)
5단계: 매매 신호 생성 함수 정의
볼린저 밴드 기준으로 매매 신호를 생성하는 함수를 정의합니다. 상단 밴드 돌파 시 매수 신호(1)를 발생시킵니다. 하단 밴드 돌파 시 매도 신호(-1)를 발생시킵니다. 중심선 돌파 시 손절매 신호를 발생시킵니다. 포지션 상태를 추적하여 중복 진입을 방지합니다.
def generate_bb_signals(df):
"""볼린저 밴드 활용 변동성 돌파 전략 매매 신호 생성
Args:
df (pd.DataFrame): OHLCV 데이터프레임, BB_UPPER, BB_MIDDLE, BB_LOWER, Close 컬럼 필요
Returns:
pd.DataFrame: 'signal' 컬럼이 추가된 데이터프레임 (1: 매수, -1: 매도, 0: 유지)
"""
signals = [0] * len(df)
position = 0 # 0: No position, 1: Long, -1: Short
for i in range(1, len(df)):
# 매수 신호 (상단 밴드 돌파 and No Position)
if df['Close'][i] > df['BB_UPPER'][i] and position == 0:
signals[i] = 1
position = 1
# 매도 신호 (하단 밴드 돌파 and No Position)
elif df['Close'][i] < df['BB_LOWER'][i] and position == 0:
signals[i] = -1
position = -1
# 손절매 (Long Position and 중심선 하향 돌파)
elif df['Close'][i] < df['BB_MIDDLE'][i] and position == 1:
signals[i] = -1
position = 0
# 손절매 (Short Position and 중심선 상향 돌파)
elif df['Close'][i] > df['BB_MIDDLE'][i] and position == -1:
signals[i] = 1
position = 0
else:
signals[i] = 0
df['signal'] = signals
return df
df = generate_bb_signals(df)
print(df[['Close', 'BB_UPPER', 'BB_LOWER', 'signal']].tail())
6단계: 백테스팅 함수 정의
생성된 매매 신호를 기반으로 백테스팅을 수행하는 함수를 정의합니다. 초기 자본과 거래 수수료를 설정합니다. 각 신호에 따라 매수/매도 시뮬레이션을 진행합니다. 최종 자산을 계산하여 전략의 수익성을 평가합니다.
def bb_backtest(df, initial_balance=1000000, fee=0.0005):
"""볼린저 밴드 활용 변동성 돌파 전략 백테스팅
Args:
df (pd.DataFrame): OHLCV 데이터프레임, Close, signal 컬럼 필요
initial_balance (float): 초기 자본
fee (float): 거래 수수료
Returns:
float: 최종 자산
"""
balance = initial_balance
position = 0 # 0: No position, 1: Long, -1: Short
buy_price = 0
for i in range(1, len(df)):
if df['signal'][i] == 1 and position == 0: # 매수 신호 and No Position
buy_price = df['Close'][i]
balance *= (1 - fee)
position = 1
print(f"{df.index[i]}: Buy at {buy_price}")
elif df['signal'][i] == -1 and position == 1: # 매도 신호 and Long Position (손절 or 청산)
sell_price = df['Close'][i]
profit = (sell_price - buy_price) / buy_price
balance += balance * profit * (1 - fee)
position = 0
print(f"{df.index[i]}: Sell at {sell_price}, Profit: {profit:.4f}")
elif df['signal'][i] == -1 and position == 0: # 매도 신호 and No Position
buy_price = df['Close'][i]
balance *= (1 - fee)
position = -1
print(f"{df.index[i]}: Short at {buy_price}")
elif df['signal'][i] == 1 and position == -1: # 매수 신호 and Short Position (손절 or 청산)
sell_price = df['Close'][i]
profit = (buy_price - sell_price) / buy_price
balance += balance * profit * (1 - fee)
position = 0
print(f"{df.index[i]}: Cover at {sell_price}, Profit: {profit:.4f}")
if position != 0:
last_price = df['Close'][len(df) - 1]
if position == 1:
profit = (last_price - buy_price) / buy_price
else:
profit = (buy_price - last_price) / buy_price
balance += balance * profit * (1 - fee)
print(f"마지막 청산: {last_price}, 수익률: {profit:.4f}")
print(f"최종 자산: {balance:.0f}")
return balance
bb_backtest(df)
7단계: 결과 분석 및 파라미터 최적화
백테스팅 결과를 분석합니다. 수익률, 최대 낙폭(MDD) 등을 확인합니다. 볼린저 밴드 기간, 표준편차 배수 등을 조정하여 전략을 최적화합니다. 3.8 섹션에서 백테스팅 결과 분석 지표를 자세히 다룹니다.
주의 사항:
- 위 코드는 교육 목적으로 제공되며, 실제 투자에 사용하기 전에 충분한 검증이 필요합니다.
- 과거 데이터 기반의 백테스팅 결과는 미래 수익을 보장하지 않습니다.
- 수수료, 슬리피지, 시장 상황 등을 고려하여 전략을 최적화해야 합니다.
- 실제 자동