【第3回】無尽蔵株価データから銘柄毎の時系列データを生成

December 11, 2020

株価サーバーpython

無一物中Project記事一覧


はじめに

毎日の日本株の株価データを公開している無尽蔵というサイトがあります。

本記事では、無尽蔵サイトから取得した毎日の株価データから、銘柄毎の株価日足時系列データを生成し、チャート表示させてみます。無尽蔵サイトから毎日株の価データを一括ダウンロードする方法はこちらを参照してください。

銘柄毎の株価日足時系列データの生成

無尽蔵サイトの株価データは、以下のような形式のcsvファイルです。

T201201.csv
2020/12/1,1001,11,1001 日経225,26624,26852,26618,26788,1331220000,東証1部
2020/12/1,1002,11,1002 TOPIX,1765,1772,1760,1768,1331220000,東証1部
2020/12/1,1301,11,1301 極洋,2824,2824,2780,2787,17900,東証1部
2020/12/1,1305,11,1305 ダイワTPX,1851,1862,1850,1857,575180,東証1部
2020/12/1,1306,11,1306 TOPIX投,1831,1840,1828,1835,2675730,東証1部
  ...
2020/12/1,1712,31,1712 ダイセキ環境,0,0,0,0,0,名古1部
2020/12/1,1712,11,1712 ダイセキ環境,686,689,682,688,35700,東証1部
  ...
2020/12/1,9996,91,9996 サトー商会,1440,1470,1424,1454,1700,JAQ
2020/12/1,9997,11,9997 ベルーナ,959,962,938,954,154000,東証1部

無尽蔵サイトから、必要な期間の株価データTyymmdd.csvを取得し、それらから銘柄毎の株価日足時系列データを生成します。

生成する株価日足時系列データのcsvファイルの例は以下。

1301.csv
2015/01/05,275,277,274,275,239000000
2015/01/06,274,275,270,272,480000000
2015/01/07,270,273,270,271,217000000
  ...
2020/11/25,2839,2846,2795,2831,27800000
2020/11/26,2820,2826,2801,2809,8700000
2020/11/27,2807,2825,2803,2819,22000000

以下のディレクトリ構成を前提としています。

daily_dataディレクトリには、年毎のサブディレクトリを切り、その中に、無尽蔵サイトから取得したcsvファイルを置きます。

dataディレクトリには、証券コードの1000の桁毎のサブディレクトリを切り、その中に、銘柄毎の株価日足時系列データのcsvファイルが置かれます。

daily_dataディレクトリの中を読んで、dataディレクトリの中にデータを吐き出すスクリプトを作る訳です。

working_root/
    daily_data/
        2015/
            T150105.csv
            ...
        ...
        2020/
            T200106.csv
            T200107.csv
            ...
            T201120.csv
    data/
        1000/
            1001.csv
            1002.csv
            ...
        2000/
        ...
        9000/
            9001.csv
            ...

単なる力業の実装例ということで、スクリプト例は以下です。このスクリプトをそのまま実行する場合は、daily_data/以下のディレクトリとdata/以下のディレクトリは、あらかじめ作っておいてください。 main()の入力ディレクトリの期間も、取得したデータにあわせて調整してください。

import_daily_data.py
# -*- coding: utf-8 -*-
import glob
import os

def add_data(code, date_str, cv1, cv2, cv3, cv4, cvc):
    code_dir = code[0]+"000"
    out_path = "./data/" + code_dir + "/" + code + ".csv"
    line = date_str+','+cv1+','+cv2+','+cv3+','+cv4+','+str(int(float(cvc)*1000))+'\n'
    with open(out_path,'a') as f:
        f.write(line)

def import_daily_data(import_year):
    daily_files = glob.glob('./daily_data/{}/*.csv'.format(import_year))
    for daily_file in daily_files:
        filename = os.path.basename(daily_file)
        yy = 2000 + int(filename[1:3])
        mm = int(filename[3:5])
        dd = int(filename[5:7])
        date_str = '{0:4d}/{1:02d}/{2:02d}'.format(yy, mm, dd)
        with open(daily_file, mode='rb') as fd:
            lines = fd.readlines()
            for i, line in enumerate(lines):
                try:
                    line = line.decode('cp932')
                except:
                    print('error file {}: line {}'.format(daily_file, i))
                    # utf-8でないバイト列が含まれる行はスキップする
                    continue
                line = line.rstrip()
                line_list = line.split(',')
                if len(line_list)==10:
                    if len(line_list[1])==4:
                        code = str(line_list[1])
                        market = line_list[9]
                        if '名古' in market:
                            next_line = lines[i+1]
                            next_line = next_line.decode('cp932')
                            next_line_list = next_line.split(',')
                            next_code = str(next_line_list[1])
                            if next_code!=code:
                                add_data(code, date_str, line_list[4], line_list[5], line_list[6], line_list[7], line_list[8])
                        else:
                            add_data(code, date_str, line_list[4], line_list[5], line_list[6], line_list[7], line_list[8])
                else:
                    print('error file {}: line {} : {}'.format(daily_file, i, line))

def main():
    for year in range(2015, 2021):
        import_daily_data(year)

if __name__ == '__main__':
    main()

以下のように実行します。

$ python import_daily_data.py

以上で、data/ディレクトリ以下に銘柄毎の時系列csvファイルが生成されました。

simple_plot.py
import pandas as pd
import mplfinance as mpf
path = './data/1000/1001.csv'
df = pd.read_csv(path, header=None, names=['Date','Open','High','Low','Close','Volume'], encoding='UTF-8')
df['Date'] = pd.to_datetime(df['Date'])
df = df.set_index("Date")
mpf.plot(df, type='candle', volume=True)
$ python simple_plot.py

結果はこれ。

1001.png

一見、これでよさげだけど、例えば、和製コストコでおなじみの業務スーパーを運営する「3038神戸物産」のチャートを見てみると、

3038-1.pngg

株式分割の調整ができていないんで、このままでは、使い物にならない。

株式分割の調整機能については、こちらを参照のこと。

まとめ

無一物中Project第3回では、無尽蔵サイトから取得した株価データから株価データベース(銘柄毎の時系列データ)を構築するpythonスクリプトを紹介しました。


Written by questions6768 who lives in Uji, Kyoto.