[Python] 백트레이더(Backtrader) 로 Pandas Dataframe import 하기
프로젝트/[ing]_백테스팅_툴

[Python] 백트레이더(Backtrader) 로 Pandas Dataframe import 하기

728x90
반응형

안녕하세요.

백트레이더 (Backtrader) 로 Pandas Dataframe import 하는 과정을 소개해볼까 합니다.

 

이미 많은 분들이 다뤄 주셨지만, 그래도 제 글을 통해 부가적인 도움이 되었으면 합니다.

 

Backtrader 는 퀀트 투자의 백테스트 (일종의 시뮬레이션이라 생각하시면 되겠습니다.) 를 쉽게 해줄 수 있는 python

패키지입니다. 

 

내장된 메서드로 Yahoo finance 를 사용할 수 있지만, 국내 주식 정보의 경우 다소 부정확한 부분과 업데이트 속도에 있어 실제 트레이딩에 활용하긴 어렵습니다. 

 

그래서 개인 DB 를 가지고 있단 전제하에, 아래의 네이버 일간시세 2020-07-31 부터 2021-07-31 까지의 데이터 프레임을 백트레이더에 적용해보겠습니다. 

 

먼저 제가 가진 데이터 프레임의 유형입니다.

              code        date    open    high     low   close   diff   volume
date
2020-07-31  035420  2020-07-31  299000  303000  296500  301000   7000  1567503
2020-08-03  035420  2020-08-03  301500  314500  299000  314500  13500  1341104
2020-08-04  035420  2020-08-04  317500  322000  307500  311000   3500  1330818
2020-08-05  035420  2020-08-05  312000  314500  306500  313500   2500   809939
2020-08-06  035420  2020-08-06  313000  322000  310500  322000   8500  1032045
...            ...         ...     ...     ...     ...     ...    ...      ...
2021-07-29  035420  2021-07-29  444000  445000  438500  439500   2500   556532
2021-07-30  035420  2021-07-30  438000  440500  433000  433500   6000   628812
2021-08-02  035420  2021-08-02  429000  437000  428500  433500      0   551937
2021-08-03  035420  2021-08-03  439000  439000  422000  428000   5500   830841
2021-08-04  035420  2021-08-04  425000  434500  423000  433000   5000   544512

date 를 인덱스로 쓰고, 순서대로 종목코드, 날짜, 시가, 고가, 저가, 종가, 전일비, 거래량 입니다.

 

이제 이 데이터 프레임을 백트레이더에선 어떻게 처리하는지 확인이 필요합니다.

백트레이더는 pandafeed.py 란 파일에서 이를 처리하므로 해당 파일을 열어봅시다.

저의 경우, 경로는 아래와 같습니다. 

C:\Users\username\AppData\Local\Programs\Python\Python39\lib\site-packages\backtrader\feeds\pandafeed.py

 

(아니면, Visual Studio Code 같은 편집기를 사용하시는 경우, 코드 작성시 백트레이더를 import 하신 후 

data = bt.feeds.PandasData(dataname = df) 에서 PandasData에 커서를 올리고 ctrl+좌클릭 하셔도 됩니다.)

 

이렇게 pandafeed.py 를 열어서 136 번째 줄에 가면 아래와 같은 코드가 보입니다.

백트레이더 Pandas Dateframe import 하는 부분 (pandafeed.py)

이 코드를 통해 백트레이더에서 어떻게 Pandas Dataframe 을 받고 있는지 알 수 있습니다. 

datetime 은 index 로 쓰고 있으므로 None, openinterest 는 사용하지 않을 것이므로 None 으로 바꿔줍시다.

 

그리고 159번째 줄을 보면 데이터필드가 어떻게 표출되는지 확인이 가능합니다. 

 

이제 원래의 코드로 돌아와서, 데이터프레임을 백트레이더가 알아듣게끔 가공하는 과정이 필요하겠죠.

(위의 데이터프레임 변수명은 df 입니다.)

 

# date 의 경우 str 타입이므로 datetime 형태로 자료변환을 하자
df['date'] = pd.to_datetime(df['date']) 
# date column 을 datetime 으로 명명하며, column 순서를 backtrader 가 보기 편하게 작성한다.
df.columns = ['code', 'datetime', 'open', 'high', 'low', 'close', 'diff', 'volume'] 
df.drop(['code', 'diff'], axis=1, inplace=True) # 이 중 맞지 않는 열은 삭제한다.

 

1. date 칼럼은 datetime 형태로 자료형 변환을 하고

2. 백트레이더가 요구하는 거에 맞게 데이터 이름을 바꾸며,

3. 원래 데이터프레임이 가진 종목코드명과 전일비 칼럼을 삭제하여 백트레이더와 동일하게 칼럼수를 맞췄습니다.

 

이렇게 하면 개인 DB 의 데이터프레임 자료도 백트레이더에서 원활하게 사용 가능하실 것입니다.

 

이해를 돕기위해 예제 코드를 첨부합니다. 

(DB 관련 코드는 김황후 님의 '파이썬 증권데이터 분석' (2020) 을 참고했음을 말씀드립니다.)

from datetime import datetime, timedelta
import backtrader as bt
from backtrader import cerebro
from pandas.io.formats import style
import Analyzer
import pandas as pd

# RSI 가 40 미만이면 매수하고 60 초과이면 매도하는 전략
class MyStrategy(bt.Strategy):
    def __init__(self):
        self.rsi = bt.indicators.RSI(self.data.close)

    def next(self):
        if not self.position:
            if self.rsi < 40:
                self.order = self.buy()
        else:
            if self.rsi > 60:
                self.order = self.sell()

mk = Analyzer.MarketDB()
# DB에서 데이터를 불러온다.
df = mk.get_daily_price('NAVER', '2020-07-31', '2021-07-31') 
# date 의 경우 str 타입이므로 datetime 형태로 자료변환을 하자
df['date'] = pd.to_datetime(df['date']) 
# date column 을 datetime 으로 명명하며, column 순서를 backtrader 가 보기 편하게 작성한다.
df.columns = ['code', 'datetime', 'open', 'high', 'low', 'close', 'diff', 'volume'] 
df.drop(['code', 'diff'], axis=1, inplace=True) # 이 중 맞지 않는 열은 삭제한다. 

data = bt.feeds.PandasData(dataname=df) # Pandas Dataframe 입력
cerebro = bt.Cerebro() 
cerebro.adddata(data)
cerebro.addstrategy(MyStrategy)
cerebro.broker.setcash(10000000) # 초기 투자 자금 : 천만원
cerebro.addsizer(bt.sizers.SizerFix, stake=30) # 주식 매매단위: 30주.

cerebro.run() # Cerebro 클래스로 백테스트 실행
cerebro.plot(style='candlestick') # 백테스트 결과 차트 출력

 

이렇게 해서 되시는 분들도 있을 것이고, matplotlib 의 import warning error 가 나시는 분들도 있을 것입니다.

import warning 에러를 수정하는 방법은 그 다음 포스트에서 다뤄보겠습니다.

728x90
반응형