3.7.4.2. 파이썬 코드 구현

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 섹션에서 백테스팅 결과 분석 지표를 자세히 다룹니다.

주의 사항:

  • 위 코드는 교육 목적으로 제공되며, 실제 투자에 사용하기 전에 충분한 검증이 필요합니다.
  • 과거 데이터 기반의 백테스팅 결과는 미래 수익을 보장하지 않습니다.
  • 수수료, 슬리피지, 시장 상황 등을 고려하여 전략을 최적화해야 합니다.
  • 실제 자동
위로 스크롤