Python
numpy
scikit-learn
pandas
0

機械学習で明日の株価を予測(Python)

概要

オンライン上からフリーで手に入る金融情報とscikit-learnを用いて、翌日の株価を予測するプログラムを作ります。

データの取得

今回は①株式銘柄の価格、②ドル円などの為替の情報、③NYダウなどのベンチマークの情報を取得します。以下に具体的な取得元を記します。

株式銘柄の価格情報の取得

株式銘柄の取得は、IEX APIというフリーのAPIを用います。こちらの記事こちらの記事で具体的な情報の取得方法を記載しました。簡単にまとめると、https://api.iextrading.com/1.0/stock/aapl/chart/5yのような要求を出すと、

[
  {
      "date":"2013-08-27",
      "open":65.1405,
      "high":65.7304,
      "low":63.6101,
      "close":63.9096,
      "volume":105930335,
      "unadjustedVolume":15132905,
      "change":-1.881,
      "changePercent":-2.859,
      "vwap":64.5862,
      "label":"Aug 27, 13",
      "changeOverTime":0
  },
 ...
]

のようなJSON形式のレスポンスが返ってくるAPIです。この例では、url内の/aapl/でAppleの情報を、/5yで5年分の情報を要求しています。
このAPIから情報を取得し、pandasのデータフレームに格納するコードを書きます。

sklearnTest.py
    def price_Data(stockCode):
        header = {"content-type": "application/json"}
#urlの作成
        url = 'https://api.iextrading.com/1.0/stock/' + stockCode + '/chart/5y'
#情報の取得
        r = requests.get(url,headers=header)
        data = r.json()

#pandasのDataFrameへの格納
                df = pd.DataFrame(columns=['OPEN','HIGH','LOW','CLOSE','CHANGEPERCENT','VOLUME','VWAP','KEY'])
        for i in range(len(data)):
            df_temp = pd.Series([float(data[i]["open"]),
            float(data[i]["high"]),
            float(data[i]["low"]),
            float(data[i]["close"]),
            float(data[i]["changePercent"]),
            float(data[i]["volume"]),
            float(data[i]["vwap"]),
            data[i]['date']],index=df.columns)
            df = df.append(df_temp,ignore_index=True)
        return df

為替情報の取得

為替情報はこちらのウェブサイトから情報を取得します。
Screen Shot 2018-09-04 at 23.05.31.png
「Japanese Yen」を選択することで対円のデータを取得することを、「Start Date」を変更することで取得する範囲を、それぞれ指定しています。日足のデータは4年前までしか取れないことに注意してください。
ここで取得した情報を、以下のように日付を'KEY'、データを'FOREX_VALUE'として、csvファイルにまとめました。
Screen Shot 2018-09-04 at 23.09.24.png
このファイルからデータを読み込むコードを以下に記します。

sklearnTest.py
    def forex_Data():
        data = pd.read_csv('forex.csv')
#IEX APIと日付の表記を合わせる処理
        data['KEY'] = data['KEY'].str.replace('/','-')
        return data

ベンチマーク情報の取得

ベンチマークとしてNYダウの情報を、こちらのウェブサイトから取得します。取得した情報は下の画像のように日付を'KEY'に、それ以外をそれっぽい名前をつけて、csvファイルにまとめました。
Screen Shot 2018-09-04 at 23.17.08.png
このファイルから情報を取得するコードを以下に記します。

sklearnTest.py
    def benchMark_Data():
        data = pd.read_csv('benchMark.csv')
#IEX APIと日付の表記を合わせる処理
        data['KEY'] = data['KEY'].str[:-3]
        return data

コードの作成

今までいくつかコードの断片をお見せしましたが、それらを一つのクラスにまとめます。
そして前日の株価情報、為替情報、ベンチマーク情報から、その翌日の終値を予測するようトレーニングします。

情報取得部分をクラスにまとめる

コンストラクタで銘柄コードを受け取り情報を取得し、getTrainingData()で機械学習のターゲット以外の情報を、getTargetData()でターゲットの情報を返すようにします。

sklearnTest.py
class financialData:
#コンストラクタ
    def __init__(self,stockCode):
#integratedDataという変数にすべての情報を格納する
        self.integratedData = self.integrate_Data(self.price_Data(stockCode),self.forex_Data(),self.benchMark_Data())

#前日のトレーニングデータとその翌日のターゲットデータを対応付けるため、
#トレーニングデータからは先頭の要素を、ターゲットデータからは末尾の要素を取り除く
    def getTrainingData(self):
        return self.integratedData.drop('KEY', axis=1).drop(0)

    def getTargetData(self):
        return self.integratedData['CLOSE'].drop(len(self.integratedData) - 1)

#株式銘柄情報
    def price_Data(self,stockCode):
        header = {"content-type": "application/json"}
        url = 'https://api.iextrading.com/1.0/stock/' + stockCode + '/chart/5y'

        r = requests.get(url,headers=header)
        data = r.json()

        df = pd.DataFrame(columns=['OPEN','HIGH','LOW','CLOSE','CHANGEPERCENT','VOLUME','VWAP','KEY'])
        for i in range(len(data)):
            df_temp = pd.Series([float(data[i]["open"]),
            float(data[i]["high"]),
            float(data[i]["low"]),
            float(data[i]["close"]),
            float(data[i]["changePercent"]),
            float(data[i]["volume"]),
            float(data[i]["vwap"]),
            data[i]['date']],index=df.columns)
            df = df.append(df_temp,ignore_index=True)
        return df

#為替情報
    def forex_Data(self):
        data = pd.read_csv('forex.csv')
        data['KEY'] = data['KEY'].str.replace('/','-')
        return data

#ベンチマーク情報
    def benchMark_Data(self):
        data = pd.read_csv('benchMark.csv')
        data['KEY'] = data['KEY'].str[:-3]
        return data

#三種類の情報を一つにまとめる
    def integrate_Data(self,price,forex,benchMark):
        return pd.merge((pd.merge(price,forex,on="KEY")),benchMark,on='KEY')

機械学習ライブラリを用いる

ライブラリscikit-learnを用いて、簡単な機械学習を行うコードを書きます。基本的に、トレーニング用データとターゲットデータをこのライブラリに渡すことで、できます。以下の例では、世界中にサプライチェーンが広がっており為替の影響を受けやすそう且つ値付かずの日がなさそうなAppleの株で機械学習を試しています。

sklearnTest.py
#情報の取得
fd = financialData("aapl")
X = fd.getTrainingData()
y = fd.getTargetData()
#線形回帰モデルの選択
model=lm.LinearRegression()
#引数(トレーニングデータ、ターゲットデータ)を渡します。
model.fit(X,y)

試してみる

最新の情報で試してみます。

sklearnTest.py
print(model.predict([[226.51,228.87,226,1.155,43340134,227.6902,110.92,25824.47,25916.07,25918.10,25808.44]]))

[[始値、高値、安値、騰落率、売買高、VWAP、為替レート、NYダウ終値、NYダウ始値、NYダウ高値、NYダウ安値]]
の形で情報を渡します。
すると明日(9月4日)のアップルの終値は226.20767092ドルだと出てきました。
本当にあっているでしょうか?明日が楽しみです。

追記

実際の終値が以下です。
Screen Shot 2018-09-05 at 06.16.19.png
228.36ドルでした。まあそう外れてもいないですね。