見出し画像

pythonで日本株スクリーニング①

概要

こんにちは~じゅんじゅんです🔥
数々の投資コミュニティに出入りをはじめた中で、地合いやファンダを見ていると日本株これから面白いかもしれない… と思い始めた。

エミン・ユルマズさんのようなこれから日本でのインフレ、バブルを予測する人も出始めたし、無関心ではいられないかもしれないと思いつつ、でも四季報を一から細部まで読む時間もない。
まずは、時間をかけずに投資対象になる銘柄をpythonでスクリーニングするコードを他のサイトから引用しつつ作ったので共有する。

JPXから日本株証券コード一覧の取得

上記を参照しつつ、JPXが公開している東証上場銘柄一覧2022年6月末版をrequestモジュールを使って取得し、取得したい証券コードの範囲を指定できる関数を定義した。

まずデータの中身を確認しよう。以下は2001~2010番のデータをソートした図である。データにはコード、銘柄名、市場、商品区分、業種コード、企画区分などのデータが収納されていることが分かった。

例えば、各種経済指標とセクターや業種ごとの株価の連動の分析を行いたいときに、このデータは活用しやすそうである。

https://www.jpx.co.jp/markets/statistics-equities/misc/01.html
からダウンロードしたcsvファイルの中身


stock_code_list(code1, code2)関数のcode1とcode2に取得したい証券コード範囲を入力しよう。

例えば、2001~2010の企業を調べたい場合、以下のようなコードを作成した。

*一部コードは上記サイトを引用しました。

import requests
import datetime
import time
import pandas as pd
from bs4 import BeautifulSoup

now = datetime.datetime.now()

def stock_code_list(code1, code2):
    url = "https://www.jpx.co.jp/markets/statistics-equities/misc/tvdivq0000001vg2-att/data_j.xls"
    r = requests.get(url)
    with open('data_j.xls', 'wb') as output:
        output.write(r.content)

    stocklist = pd.read_excel("./data_j.xls")
    stocklist.loc[stocklist["市場・商品区分"]=="市場第一部(内国株)",
                ["コード","銘柄名","33業種コード","33業種区分","規模コード","規模区分"]
                
    #指定したいコードの範囲
    stocklist = stocklist[(stocklist["コード"] >= code1) & (stocklist["コード"] <= code2)]
    stocklist = stocklist.reset_index()
    stocklist.to_csv(now.strftime('%Y%m%d_%H%M')+"_jpx_stock_data.csv", encoding='utf_8_sig')

    #コード一覧を取得し、リストを出力
    stock_No = stocklist["コード"].tolist()
    return stock_No, stocklist

stock_No, stocklist = stock_code_list(2000, 2010)
print(stock_No)
stocklist

出力結果として以下のコードのリストと、特定の銘柄のData Frameが表示されれば成功である。

[2001, 2002, 2003, 2004, 2009]
index	日付	コード	銘柄名	市場・商品区分	33業種コード	33業種区分	17業種コード	17業種区分	規模コード	規模区分
0	350	20220630	2001	ニップン	プライム(内国株式)	3050	食料品	1	食品	6	TOPIX Small 1
1	351	20220630	2002	日清製粉グループ本社	プライム(内国株式)	3050	食料品	1	食品	4	TOPIX Mid400
2	352	20220630	2003	日東富士製粉	スタンダード(内国株式)	3050	食料品	1	食品	7	TOPIX Small 2
3	353	20220630	2004	昭和産業	プライム(内国株式)	3050	食料品	1	食品	7	TOPIX Small 2
4	354	20220630	2009	鳥越製粉	スタンダード(内国株式)	3050	食料品	1	食品	7	TOPIX Small 2

しかし残念なことにッ!JPXのエクセルファイルには、PBRや時価総額などの情報が反映されておらず、このデータからだけでは有望な投資対象のスクリーニングなどは到底できない。

まずは基礎スクリーニングに必要なデータとしてPBR、時価総額、株主優待や配当利回りなどの情報が欲しいので、その情報はほかのサイトから取得することにした。

みんかぶからの銘柄情報スクレイピング

上記を参照して、JPXから取得した銘柄一覧と連動した形で各種指標をスクレイピングしていこう。

イメージとして、JPXデータから抽出した銘柄データ一つ一つに対してみんかぶのサイトから赤枠部分のデータを抽出して、一覧化とcsv保存を行い、のちのスクリーニングに資するデータパッケージを作るのである。

https://minkabu.jp/stock/2001
を参照。

関数 minkabu_data(stock_code)のstock_codeの部分に先ほどJPXデータから取得したstock_Noリストを入れ、みんかぶから対応した銘柄の情報を取得しよう。

例えば、全株式データの情報を一度にスクレイピングするとサーバーへの攻撃としてみなされてしまうので、time.sleep(1)を入れ、一秒ごとにサイトにアクセスし、情報を取得することにしよう。
*一部のコードは上記のリンクから引用させていただきました。

def minkabu_data(stock_code):
    url_list = stock_code
    df = pd.DataFrame()
    basic_info = {}

    for i in url_list:
        # 指定URLのHTMLデータを取得
        url = "https://minkabu.jp/stock/" + str(i)
        html = requests.get(url)

        # BeautifulSoupのHTMLパーサーを生成
        soup = BeautifulSoup(html.content, "html.parser")

        # 全<li>要素を抽出
        li_all = soup.find_all('li')
        for li in li_all:
            
            # <li>要素内の<dt>要素を抽出
            dt = li.find('dt')
            if dt is None:
                # <dt>要素がなければ処理不要
                continue
            
            # <li>要素内の<dd>要素を抽出
            dd = li.find('dd')
            
            # <dt><dd>要素から文字列を取得
            key = dt.text
            value = dd.text
            
            # ディクショナリに格納
            basic_info[key] = value
        
        df = df.append([basic_info])
        time.sleep(1)
    df = df.reset_index()
    #余計なindex行を削除
    df = df.drop("index", axis=1)
    df.to_csv(now.strftime('%Y%m%d_%H%M')+"_minkabudata.csv", encoding='utf_8_sig')
    return df

df1 = minkabu_data(stock_No)
df1

outputとしてJPXデータから取得した銘柄コードと連動した値が取得できていれば成功だ。

各銘柄の配当利回りや株主優待内容も一覧で表示できた✨ので
四季報を調べなおしたり、サイトに何度もアクセスする時間をこれにより削減できると考える。


 PBR	PER(調整後)	PSR	出来高	単元株数	始値	安値	時価総額	株主優待	発行済株数	購入金額	配当利回り	高値
0	0.72倍	13.53倍	0.40倍	88,100株	100株	1,643.0円	1,629.0円	129,744百万円	自社商品詰合せ	78,824千株	最安---	2.30%	1,648.0円
1	1.08倍	27.78倍	0.73倍	618,600株	100株	1,650.0円	1,621.0円	497,929百万円	自社製品	304,357千株	最安---	2.38%	1,652.0円
2	1.03倍	11.27倍	0.72倍	2,700株	100株	4,640.0円	4,590.0円	43,122百万円	---	9,384千株	最安---	---	4,665.0円
3	0.80倍	21.31倍	0.30倍	24,300株	100株	2,568.0円	2,545.0円	87,376百万円	自社製品	33,985千株	最安---	2.33%	2,585.0円
4	0.53倍	18.24倍	0.74倍	13,300株	100株	650.0円	649.0円	16,975百万円	自社製品	26,036千株	最安---	2.14%	657.0

取得したデータの連結

目次のJPXから取得した日本株証券コードデータと、みんかぶから取得した銘柄情報スクレイピングのデータを連結して、JPXのデータとみんかぶから取得した情報を横並びして、さらなる解析の準備をしよう!!

#2つのデータを横方向に連結する
df_concat = pd.concat([stocklist, df1], axis=1)
df_concat.to_csv(now.strftime('%Y%m%d_%H%M') + "_data_concat.csv", encoding='utf_8_sig')
df_concat.head(5)

outputとしては当然今まで取得したデータが横並びで表示される。

index	日付	コード	銘柄名	市場・商品区分	33業種コード	33業種区分	17業種コード	17業種区分	規模コード	...	出来高	単元株数	始値	安値	時価総額	株主優待	発行済株数	購入金額	配当利回り	高値
0	350	20220630	2001	ニップン	プライム(内国株式)	3050	食料品	1	食品	6	...	88,100株	100株	1,643.0円	1,629.0円	129,744百万円	自社商品詰合せ	78,824千株	最安---	2.30%	1,648.0円
1	351	20220630	2002	日清製粉グループ本社	プライム(内国株式)	3050	食料品	1	食品	4	...	618,600株	100株	1,650.0円	1,621.0円	497,929百万円	自社製品	304,357千株	最安---	2.38%	1,652.0円
2	352	20220630	2003	日東富士製粉	スタンダード(内国株式)	3050	食料品	1	食品	7	...	2,700株	100株	4,640.0円	4,590.0円	43,122百万円	---	9,384千株	最安---	---	4,665.0円
3	353	20220630	2004	昭和産業	プライム(内国株式)	3050	食料品	1	食品	7	...	24,300株	100株	2,568.0円	2,545.0円	87,376百万円	自社製品	33,985千株	最安---	2.33%	2,585.0円
4	354	20220630	2009	鳥越製粉	スタンダード(内国株式)	3050	食料品	1	食品	7	...	13,300株	100株	650.0円	649.0円	16,975百万円	自社製品	26,036千株	最安---	2.14%	657.0

outputされた日時+data_concat.csvファイルも確認しよう。
JPXから取得したデータとみんかぶから取得されたデータがひとまとめになったオリジナルデータが作成できた!!(どんどんパフパフ~~✨)

日時+data_concat.csvファイルの中身

今回は、証券コード、銘柄名の一覧から各種データのスクレイピングを行いました。このプログラムを用いればすべての証券コードの情報が人間が調べる100倍速で網羅されるはずッ!!!

次回からはこのデータを分析できるように前処理して、実際に銘柄の選定をしていこうと思うのでお楽しみに✨

ここまで読んでいただいた方、ありがとうございました。
本日も経済研究、頑張っていきまっしょい!


この記事が気に入ったらサポートをしてみませんか?