[機械学習・進化計算による株式取引最適化] No.04-02 株価データの選別

このプログラムの目的

make_original_dataset.pyの目的はoriginal_data_2010-01-01_2023-03-01_1dに格納されているデータを一つのデータにまとめることです.また,データ数が少ない銘柄データを除くことも目的とします.

前回と違い,Closeだけでなく,Open, High, Low, Adj Closeのデータも学習で利用できるようにしたいので,今回のデータセット作成ではそれらも出力します.
※Adj Closeは出力しましたが,今後のプログラムでは利用しませんでした.

また,学習期間とテスト期間をこの時点で分けてしまい,タグをつけることで,今後のプログラムでテストデータが混入することを防ぎます.

work_share
├04_get_stock_price_ver2
  ├Dockerfile
  ├docker-compose.yml
  └src
    ├dataset(自動生成)
    ├original_data_2010-01-01_2023-03-01_1d
    ├get_stock_price.py
    ├make_original_data.py (これを作成)
    └stocks_code.xls

使用ライブラリ・グローバル変数

import pandas as pd
import numpy as np
import tqdm
import glob
import os
import datetime

start_date = datetime.datetime.fromisoformat('2017-01-01')
test_start_date = datetime.datetime.fromisoformat('2022-01-01')

株価データのロード

格納済みのデータをロードします.株価データはDate,Open,High,Low,Close,Adj Close,Volumeの7種のデータを保持しています.

ここでは,Dateをindexとして,Keyを保持するデータのみを扱います.keyはOpen,High,Low,Close,Adj Closeの5種です.

def load_stock_price(path, key):
    code = path.split('/')[-1][:-4]
    df = pd.read_csv(path, index_col=0)
    value = df[key]
    return code, value

全ての銘柄データをまとめる

すべての銘柄データをまとめて一つのDataFrameにします.ここではカラム名を銘柄コードとしています.

また,株価データをロードしてきたときにその系列長が1000以上の銘柄のみを扱います.

Key(Open,High,Low,Close,Adj Close)毎にDataFrameを出力するようにします.

def make_all_stock_price_df(dir_path, key):
    csv_path_list = glob.glob(f'{dir_path}/*')
    csv_path_list.sort()
    value_dict = {}
    for path in tqdm.tqdm(csv_path_list):
        code, value = load_stock_price(path, key)
        if len(value) >= 1000:
            value_dict[code] = value
    df = pd.DataFrame(value_dict)
    df = df.astype('float64')
    return df

生成したデータの保存

全銘柄を一つのファイルに保存します.保存形式は何でもよいですが,ここではpandasに組み込まれているpickleを利用します.

pickleはメモリ上のデータをバイナリのまま保存するため,csvなどのデータ形式と比べて軽量かつ高速に読み込めます.ただし,csvと違って,ファイルの中身を閲覧しても人間には読めません.

新たに保存するディレクトリしてdatasetが生成され,その中に以下のファイルが生成されます.

  • original_dataset_Open.dfpkl
  • original_dataset_Close.dfpkl
  • original_dataset_High.dfpkl
  • original_dataset_Low.dfpkl
  • original_dataset_Adj Close.dfpkl

拡張子は必要ありませんが,DataFrameのpickleファイルであることが分かるように.dfpklとしました.

def make_dataset_original(out_path):
    for key in ['Open', 'Close', 'High', 'Low', 'Adj Close']:
        original_data_dir = './original_data_2010-01-01_2023-03-01_1d/stock_price'
        df = make_all_stock_price_df(original_data_dir, key)
        df.index = pd.to_datetime(df.index)

        df = df.loc[start_date:, :]

        valid_counts = df.count()
        drop_codes = []
        for code, count in zip(valid_counts.index, valid_counts):
            if count < 1000:
                drop_codes.append(code)
                print(f'{code} : valid count : {count}')

        df = df.drop(drop_codes, axis=1)

        df['eval_type'] = 'train'
        df.loc[test_start_date:, 'eval_type'] = 'test'

        print(df)
        out_name = f'{out_path}_{key}.dfpkl'
        df.to_pickle(out_name)

if __name__ == '__main__':
    dataset_dir = 'dataset'
    os.makedirs(dataset_dir, exist_ok=True)
    make_dataset_original(f'{dataset_dir}/original_dataset')
タイトルとURLをコピーしました