-
[오픈소스] Prophet을 이용한 Stock Prediction 활용 및 후기 (3/3)카테고리 없음 2020. 3. 13. 22:41
자 그럼 colab에 ipynb 파일을 업로드하고 돌려보자
import pandas as pd from fbprophet import Prophet import pandas as pd import matplotlib.pyplot as plt import pandas_ta as ta from alphaVantageAPI.alphavantage import AlphaVantage ##pip install alphaVantage-api##첫 번째로 필요한 모듈들을 불러온다.
AlphaVantage는 설치되어 있지 않을 경우가 많기 때문에 혹시 ModuleNotFound error 가 뜬다면
코멘트 처리된 부분을 복사해서 pip install alphaVantage-api 를 실행시키기 바란다.
ticker='CW' AV = AlphaVantage( api_key='paste your api-key', premium=False, datatype='json', export=False, export_path= '/Users/kimkwangjae/fbprophet-price-prediction', output='csv', output_size='full', clean=True, proxy={}) df = AV.data(symbol=ticker, function='DA') predper = 60 #number of days to predict ahead print(f"Shape: {df.shape}") df.set_index(['date'], inplace=True) df.head()다음으론 AlphaVantage에서 데이터를 불러오기 위해서 api-key를 발급받아야한다.
api-key는 가입만 하면 무료로 발급되므로 https://www.alphavantage.co/에서 발급받으면 된다.
실행 결과가 다음과 같이 뜬다면 데이터가 성공적으로 다운로드된 것이다

계산 에러를 방지하기 위해서 혹시 모를 N/A 값들을 0으로 바꿔주는 코드를 실행한다
df.fillna(0.0, inplace=True)df에 저장된 데이터를 다음에 또 쓸 수도 있기 때문에 csv파일 형식으로 저장한다
그러기 전에 colab에서는 다음과 같은 유용한 기능을 제공한다
from google.colab import drive drive.mount('/content/drive')위 코드를 실행하면 나의 구글 드라이브 폴더에 접속해서 데이터를 저장하고 읽어 올 수 있다
내 pc의 메모리도 안 잡아먹으면서 매우 편리한 기능이다
연동이 되면 아래 코드를 실행해서 가격 데이터를 저장하자
df.to_csv (r'/content/drive/My Drive/pricedataCW.csv', index = 'date', header=True)그리고 데이터를 불러오는 연습도 할 겸, dataframe을 변경할 겸 저장한 csv 파일을 다시 불러온다
df = pd.read_csv('/content/drive/My Drive/pricedataCW.csv', usecols=['date','close']) df.head()아래와 같이 나왔다면 파일을 성공적으로 불러들인 거다!

위에서 저장한 dataframe과의 차이점이 보이는가?
date와 close (종가) 만을 가져와서 전형적인 시계열 데이터 형식으로 변형시켰다
df.columns = ['ds', 'y']여기서 column 이름을 다시 바꿔주는데, Prophet 모델이 원하는 형식을 맞춰주기 위함이다
이제 거의 다 왔다!!
드디어 우리의 주인공 prophet을 사용해서 예측을 할 차례..... 에 앞서,
모델을 fit 시켜준다
m = Prophet( growth="linear", #holidays=holidays, #seasonality_mode="multiplicative", changepoint_prior_scale=30, seasonality_prior_scale=35, ###cap=3.00, ###floor=.65*125, holidays_prior_scale=20, daily_seasonality=False, weekly_seasonality=False, yearly_seasonality=False, ).add_seasonality( name='monthly', period=30.5, fourier_order=55 ).add_seasonality( name='daily', period=1, fourier_order=15 ).add_seasonality( name='weekly', period=7, fourier_order=20 ).add_seasonality( name='yearly', period=365.25, fourier_order=20 ).add_seasonality( name='quarterly', period=365.25/4, fourier_order=5, prior_scale=15) m.fit(df)위의 코드에서 나오듯이 우리는 총 5가지 형태(월, 일, 주, 년, 분기)로 주가를 예측할 계획이다
future = m.make_future_dataframe(periods=predper) future.tail()"predper"에 명시된 days 만큼 주가를 예측하는 것인데, 이 프로젝트에서는 60일이었다.
즉 다음과 같은 형태의 datestamp 가 찍힌다.

이제 진짜 예측을 할 차례이다
forecast = m.predict(future) forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail()
예측 결과를 조금 더 직관적으로 보기 위해 다음 코드를 실행하면 그래프가 나온다
fig1 = m.plot(forecast)
방금 언급한 5가 형태의 예측을 보려면,
fig2 = m.plot_components(forecast)


다음으론 수익률을 평가해 보기 위해한 코드를 설명해 보려고 한다.
df2 = AV.data(symbol=ticker, function='DA') # Daily Adjusted df2.name = ticker df2.set_index(['date'], inplace=True) df2.drop(['dividend', 'split_coefficient'], axis=1, inplace=True) if 'dividend' in df2.columns and 'split_coefficient' in df2.columns else None opendf2 = df2['open'] closedf2 = df2['close'] volumedf2 = df2['volume'] df3 = forecast[['ds','yhat']] df3.tail() df3 = df3.iloc[:-predper] df3.columns = ['date','close'] df3.set_index(['date'], inplace=True) df3.tail() last_ = df2.shape[0] def stratty(cumulative=True, last=last_): """A very basic analysis of the closing price being greater than each moving average""" last = last if last is not None else df2.shape[0] closedf2 = df2['close'] pred = df3['close'] tdf2 = pd.DataFrame({ f"{pred.name} cumlog ret": ta.trend_return(closedf2, pred < .95*closedf2, cumulative=cumulative), }) tdf2.set_index(closedf2.index, inplace=True) window = tdf2.tail(last) title = f"{df2.name}: Prophet Logic Trend Return from {window.index[0]} to {window.index[-1]}" window.plot.area(figsize=(16, 4), color=['green', 'orange', 'yellow'], linewidth=1, alpha=0.25, title=title, stacked=False, grid=True).axhline(y=0, color="black", lw=1.1) stratty(last=2000) #last 2000 days of activity to show in the cumlog return plot
이로써 prophet으로 돌렸을 때 어느 정도의 수익을 예상할 수 있는지에 대한 예측 결과가 나왔다
하지만, 이 코드만을 가지고 실제 투자에서 수익률을 올리려는 시도는 자제하는 것이 좋다
수많은 백테스팅을 거쳐서 안정적인 수익 모델을 만들어내는 것이 중요하기 때문이다
위의 모델을 발전시키기 위해서 여러 가지 parameter들이 있다
그리고 ticker를 변경해서 다른 주식회사들의 historical data로 학습해보기를 권한다
필자는 AAPL (애플)을 넣어서 다음과 같은 결과를 얻어 봤다

후기
먼저 andynorris의 detail한 코드 설명에 감사를 드린다
Prophet을 활용해선 더 많은 사람이 시계열 데이터와 주가 데이터에 관심을 갖게 되는 계기를 제공해줬다
Code Lab 또한 너무나도 소중한 개발환경이라는 것을 다시 한 번 느꼈다
특히 Prophet 모듈을 설치하는 문제가 너무 많았는데 Code Lab에서는 단숨에 해결 됐다.
이번 기회에 블로깅을 꾸준히 해나가는 목표가 생겼다
더 많은 오픈소스 프로젝트를 경험해보면서 나 또한 새로운 오픈소스 프로젝트를 론칭할 수 있는 날이 올 수 있기를 바라며
글을 마친다