* 본 포스트는 개인연구/학습 기록 용도로 작성되고 있습니다.
[Python] Zipline을 이용한 주식 거래 백테스팅
By MK on July 21, 2019
Quantopian
과 함께 사용되는 Zipline!
단점은 한국 상장기업을 대상으로 하기엔 쉽지가 않다.
우선 해외시장을 타겟으로 샘플코드를 실행해보자.
SPY 즉, S&P500 지수를 활용한 투자전략의 백테스팅이다. 해당 코드는 SPY에 대한 csv 형태의 데이터를 로드한 뒤 작업한다.
아래 링크에서 다운 받을 수 있다.
https://pythonprogramming.net/static/downloads/datasets/SPY.csv
필요한 라이브러리
from zipline.api import order, record, symbol, set_benchmark
import zipline
import matplotlib.pyplot as plt
from datetime import datetime
import pandas as pd
from collections import OrderedDict
import pytz
1. 데이터 가져오기
가져온 데이터(data)는 dict 형태임에 유의하자
full_file_path = "SPY.csv"
data = OrderedDict()
data['SPY'] = pd.read_csv(full_file_path, index_col=0, parse_dates=['date'])
data['SPY'] = data['SPY'][["open","high","low","close","volume"]]
print(data['SPY'].head())
date | close |
---|---|
1993-01-29 | 43.9375 |
1993-02-01 | 44.2500 |
1993-02-02 | 44.3437 |
1993-02-03 | 44.8125 |
1993-02-04 | 45.0000 |
pandas의 penel
를 통해 데이터를 becktest에 전달하게 된다.
panel = pd.Panel(data)
panel.minor_axis = ['open','high','low','close','volume']
panel.major_axis = panel.major_axis.tz_localize(pytz.utc) # 2018-01-02 -> 2018-01-02 00:00:00+00:00
print(panel)
2. 벤치마크 설정
벤치마크는 SPY 지수 자체로 설정하였다.
def initialize(context):
set_benchmark(symbol("SPY"))
3. 핸들데이터 셋팅
order
를 통해 각 인터렉션마다 10개 단위의 SPY 지수 주문을 설정한다.
그리고 record
를 통해 각 시점의 가격을 기록한다.
def handle_data(context, data):
order(symbol("SPY"), 10)
record(SPY=data.current(symbol('SPY'), 'price'))
4. 백테스팅 실행
백테스팅할 시작, 종료 시점을 설정하고 시작 자산 규모를 셋팅한다.
# 날짜 유의
perf = zipline.run_algorithm(start=datetime(2017, 1, 5, 0, 0, 0, 0, pytz.utc),
end=datetime(2018, 3, 1, 0, 0, 0, 0, pytz.utc),
initialize=initialize,
capital_base=100000, # 기초자산 설정
handle_data=handle_data,
data=panel)
5. 결과 비교
테스팅 결과와 벤치마크인 SPY 지수의 수익률 비교를 위해 SPY 일일 수익률을 생성한다.
data = OrderedDict()
data['SPY'] = pd.read_csv(full_file_path, index_col=0, parse_dates=['date'])
data['SPY'] = data['SPY'][["open","high","low","close","volume"]]
data['SPY'] = data['SPY'].resample("1d").mean()
data['SPY'].fillna(method="ffill", inplace=True)
print(data['SPY'].head())
이제 그래프를 통해 성과를 비교해보자.
그래프 그리기
import matplotlib.pyplot as plt
from matplotlib import style
style.use("ggplot")
perf.portfolio_value.pct_change().fillna(0).add(1).cumprod().sub(1).plot(label='portfolio')
perf.SPY.pct_change().fillna(0).add(1).cumprod().sub(1).plot(label='benchmark')
plt.legend(loc=2)
plt.show()
알고리즘을 최대로 활용했을 때 누적된 수익률 그래프를 살펴보자. 단, 모든 기회마다 10개의 주식을 살 수 있다는 가정하의 결과이다.
perf.max_leverage.plot()
plt.show()