最近株について興味があり調べたりしています。ここでは、Pythonによるデータ収集と整理の方法の覚書としてまとめました。
以下のpythonのコードは、jupyter notebook を想定しています。
株価データの取得
以下で、企業コードと期間を指定して株価の情報が得られます。
import pandas_datareader as pdr
code = 9434 # ソフトバンクの銘柄コード
start = "2016-01-01"
end = "2023-02-24"
df = pdr.DataReader(f"{code}.JP", "stooq", start, end).sort_index()
df
Openは始値、Highは高値、Lowは安値、Closeは終値、Volumeは出来高です。
分析にはCloseを良く用います。
全銘柄コードの取得
上の方法は、会社の銘柄コードを知っていないと使えませんが、下のコードで、銘柄コードの表を日本取引グループから取得し、ローカルに”stock_j.xls”として保存できます。
import requests
import pandas as pd
url = "https://www.jpx.co.jp/markets/statistics-equities/misc/tvdivq0000001vg2-att/data_j.xls"
r = requests.get(url)
with open('stock_j.xls', 'wb') as output:
output.write(r.content)
stock_j.xlsを読み込むときには、以下のようにします。
stocklist = pd.read_excel("./stock_j.xls")
stocklist
なんと、4244もの企業が登録されています。
初めから全ての企業に対して分析するよりは、まずは、代表的な企業に絞って分析した方がよさそうです。
TOPIXコア30の株価データをまとめてDLする
TOPIXコア30とは、東証1部銘柄で、時価総額、流動性の特に高い30銘柄。この企業に絞ってデータベースを作ります。
以降、Core30と呼ぶことにします。
# CORE30の銘柄チャートの取得と保存 ----------
import pandas_datareader as pdr
import pandas as pd
import os
# to_excel()でworningが出るので非表示にする
import warnings
warnings.simplefilter("ignore")
# 設定 -----
target_type = "TOPIX Core30" # 絞り込む銘柄の規模区分
dir_name = "./dat_core30" # 保存ディレクトリ
start = "2016-01-01"
end = "2023-02-24"
# 取得関数の定義 -----
def get_stock_data(code, start, end):
return pdr.DataReader(f"{code}.JP", "stooq", start=start, end=end).sort_index()
# ターゲット銘柄の抽出 -----
stocklist = pd.read_excel("./stock_j.xls")
df = stocklist.query(f"規模区分 == '{target_type}'")
# 保存ディレクトリ(dir_name)の作成 -----
if not os.path.exists(dir_name):
os.makedirs(dir_name)
# 各株価データを"番号_コード_銘柄名_17業種区分.xls"のファイル名で保存
for i, code in enumerate(df["コード"]):
print(f"{i}:{code}, ", end="")
code = df.iloc[i, df.columns.get_loc("コード")]
cname =df.iloc[i, df.columns.get_loc("銘柄名")]
cclass =df.iloc[i, df.columns.get_loc("17業種区分")]
fname = f"{dir_name}/{i:05d}_{code}_{cname}_{cclass}.xls"
data = get_stock_data(code, start=start, end=end)
data.to_excel(fname, index=True, header=True)
データが保存されたディレクトリ。大企業の名前がずらりと並んでいます。
Core30のCloseデータを1つのデータフレームdf_allにまとめて保存
以下のコードで、30社のcloseデータを1つの表にまとめて”all_close.xls” として保存します。
import pandas as pd
import glob
# 設定
dir_name = "./dat_core30" # 保存ディレクトリ
# 通し番号のみを指定してデータを読み込む関数の定義
def get_saved_data(idx, dirname):
fname = glob.glob(f"{dir_name}/{idx:05d}_*.xls")[0]
df = pd.read_excel(fname, index_col=0)
return fname, df
# データのまとめ
df_all = pd.DataFrame()
n_file = 30
for idx in range(n_file):
fname, df = get_saved_data(idx, dir_name)
df_all = pd.concat([df_all, df["Close"]], axis=1)
df_all.rename(columns={"Close": f"c{idx}"}, inplace=True)
# df_allの保存 "all_close.xls"
df_all.to_excel(f"{dir_name}/all_close.xls", index=True, header=True)
df_all
しかし、以下で欠損値の数を確かめると、758個もあります。
print(df_all.isnull().sum().sum()) # 758
調べてみると、c28に730個の欠損値があり、2016-06-15にすべての銘柄で欠損値が起きていました。
よってc28は除去、2016-06-15の行も除去します。
# 欠損値が730もあるc28を削除
df_all.drop("c28", axis=1, inplace=True)
# 全てがNaNとなっている2016-06-15 を削除
df_nan = df_all.query("c0.isnull()", engine="python")
for idx in df_nan.index:
df_all.drop(idx, axis=0, inplace=True)
欠損値がなくなったdf_allを”all_close.xls”として保存します。
print(df_all.isnull().sum().sum()) # 0になっている
df_all.to_excel(f"{dir_name}/all_close.xls", index=True, header=True)
グラフ
pandas は、以下のようにしてデータを簡単にグラフで描画することができます。
df_all[["c0", "c2"]].plot()





コメントを残す