このプログラムの目的
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')