さて、ご無沙汰してました。
なんか毎年変な時期に忙しくなるんですよね、定例業務ではないいわゆる新規が降ってくるのですが、その新規が大体一癖ある案件ばかりで今年もそんな感じでドタバタの3週間を過ごしていました。そちらに関しては、今回の記事とは全く関係ないのですが、いい勉強になったので後日別記事にしたいなと思っています。
今回はTDNetから自分の欲しい情報だけ取得して通知したいという個人的な願望に答えるための記事になります。
TDnetって何?
TDnetって何?という人のためにまずはTDnetの基本的な話から初めて行きます。
TDnetの概要
東証のHPから引用してきています。
TDnet(Timely Disclosure network)は、より公平・迅速かつ広範な適時開示を実現するために、上場会社が行う適時開示に関する一連のプロセス、すなわち東京証券取引所(以下「東証」という)への事前説明(開示内容の説明)、報道機関への開示(記者クラブや報道機関の本社の端末への開示資料の伝送)、ファイリング(開示資料のデータベース化)、公衆縦覧(開示資料の適時開示情報閲覧サービスへの掲載)を総合的に電子化したシステムです。
上場会社は、有価証券上場規程に基づき会社情報の開示を行う場合は、必ずTDnetを利用することが義務づけられています。また、任意で会社情報を開示する場合においても、投資者への情報の周知性に配慮し、できるだけTDnetにより開示することをお願いしています。
https://www.jpx.co.jp/equities/listing/tdnet/index.html
TDnet(Timely Disclosure network)は、上場会社が適時開示要件に該当する事象が生じた場合に、開示が必要となる適時開示情報という物を集約して集めてくれる開示ツールです。
似たものにEDINETってありますが、あちらは適時開示ではなく法定開示(有価証券報告書や四半期報告書など)書類が集まっています。
TDnetを使うのに便利なAPIの紹介
さて、手取り早いのはスクレイピングなんでしょうが、iframeで作られたTDnetさんのスクレイピングは作るのが少し手間なので、まずはofficialのAPIが提供されていないか確認してみましょう。
TDnet official
パッと見つかるのが以下ですかね、有料だしAPIじゃないし。。。

ThirdParty
これいい感じですね、2016年くらいにXBRLの勉強会で発表されていたやつかと思いますが、まだ動いていました。今回はありがたく以下を使っていきましょう。
なんとこのかたの自作pjはEDINETにも対応し始めているみたいです。そちらもいつか触ってみたいですね。
Yanoshin_APIを使って当日の開示資料を100件取得してみる
ものは試しで100件取得してみます。
import requests
import pprint
import json
"""
web api info
https://webapi.yanoshin.jp/tdnet/
"""
def get_data_from_yanoshin():
"""
yanoshin APIからデータを100件取得してcontentを返す
:return: dict
"""
base_url = "https://webapi.yanoshin.jp/webapi/tdnet/list/"
condition = "today"
format = "json"
query = "limit=100"
res = requests.get(base_url+condition+'.'+format+'?'+query)
res_loads = json.loads(res.content)
pprint.pprint(res_loads)
return res_loads
こんな感じのresponseが返ってきています。(pprintでターミナル上は表示されるので、整形されててもう少しみやすいです汗。したのresponseは貼り付けなので、ご勘弁ください)。
itemsのなかに該当の会社名や証券コード、ドキュメントurlなどが返ってきていることがわかります。
{'actions': ['today'], 'condition_desc': '本日(2020-08-11)の適時開示情報一覧', 'items': [{'Tdnet': {'company_code': '16724', 'company_name': 'E-WisdomTr', 'document_url': 'https://webapi.yanoshin.jp/rd.php?https://www.release.tdnet.info/inbs/140120200811479252.pdf', 'id': '718914', 'markets_string': '東', 'pubdate': '2020-08-11 10:45:00', 'title': '上場ETF(管理会社:WisdomTree、外国投資法人:MSL)に関する日々の開示事項\u3000', 'update_history': None, 'url_report_type_earnings_forecast': None, 'url_report_type_expected_dividends': None, 'url_report_type_fs_consolidated': None, 'url_report_type_fs_non_consolidated': None, 'url_report_type_summary': None, 'url_xbrl': None}}, {'Tdnet': {'company_code': '16724', 'company_name': 'E-WisdomTr', 'document_url': 'https://webapi.yanoshin.jp/rd.php?https://www.release.tdnet.info/inbs/140120200811479262.pdf', 'id': '718915', 'markets_string': '東', 'pubdate': '2020-08-11 10:45:00', 'title': '上場ETF(管理会社:WisdomTree、外国投資法人:CSL)に関する日々の開示事項\u3000', 'update_history': None, 'url_report_type_earnings_forecast': None, 'url_report_type_expected_dividends': None, 'url_report_type_fs_consolidated': None, 'url_report_type_fs_non_consolidated': None, 'url_report_type_summary': None, 'url_xbrl': None}},
成長性説明資料を抽出してメールしてみる
さて、実際に取得したかった成長性の説明資料のデータを抽出してメールしてみます。
import requests
import pprint
import json
"""
web api info
https://webapi.yanoshin.jp/tdnet/
"""
def get_data_from_yanoshin():
"""
yanoshin APIからデータを100件取得してcontentを返す
:return: dict
"""
base_url = "https://webapi.yanoshin.jp/webapi/tdnet/list/"
condition = "today"
format = "json"
query = "limit=100"
res = requests.get(base_url+condition+'.'+format+'?'+query)
res_loads = json.loads(res.content)
pprint.pprint(res_loads)
return res_loads
def pickup_growth_possibility_material(data):
"""
成長可能性に関する説明資料
:param data: dict
:return: list
"""
output = []
for x in data['items']:
if x['Tdnet']['title'] == "成長可能性に関する説明資料":
output.append([x['Tdnet']['company_name'], x['Tdnet']['document_url']])
return output
def send_email(data):
# メール送信関係
import smtplib
from email.mime.text import MIMEText
from email.header import Header
from_adress = "" # 送付もとメールアドレス、gmailを前提
from_adress_pass = "" # Google accountから発行されるアプリパスワードに変更(2要素認証)
to_adress = "" # 受信メールアドレス
string = ""
if len(data):
for i in range(len(data)):
string = string + str(data[i][0]) + "\n" + str(data[i][1])
else:
string = "本日は対象データがありません"
msg = MIMEText("新規成長性説明資料。\n\n" + string, "plain")
msg["Subject"] = Header("from_bot 成長性説明資料")
smtp_obj = smtplib.SMTP("smtp.gmail.com", 587)
smtp_obj.ehlo()
smtp_obj.starttls()
smtp_obj.login(from_adress, from_adress_pass)
smtp_obj.sendmail(from_adress, to_adress, msg.as_string())
smtp_obj.quit()
if __name__ == '__main__':
data = get_data_from_yanoshin()
pickup_data = pickup_growth_possibility_material(data)
pprint.pprint(pickup_data)
send_email(pickup_data)
成長性説明資料Tips
成長性の説明資料は対象の新規上場会社が存在する場合、朝8時にリリースされます。なので、launchedなどで朝8時30分ぐらいに自動化して上記コードを回しておくと、朝一で新規の成長性説明資料がないかわかります。マザーズ新規上場の会社しか公開しない資料なのですが、読んでて楽しいので、いつも一人で暇な時に眺めています。
色々読んだ知見をブログにまとめようとブログの箱だけ作ったのですが、そちらのブログはほぼ更新できていないですね汗

誰か、やって欲しいw リスト化してあるだけでも、結構面白いデータなんだと思うんですけどね。もちろんpdf読み込んで内容分析かけても面白いかもですが、ちょっと画像が多いのでそれだけで学習させるとよくわからないことになるので、ここは人がまだまだがんばるところです。
成長性説明資料以外のユースケース
個人的に抽出しやすいなと思う他のユースケースは以下があります。まぁ要はタイトルが会社ごとに別れず、基本固定されている開示内容ですね。
- 業績予想の修正
- 第三者委員会の報告書
まとめ
今回は成長性説明資料のpickupを行いましたが、タイトルが共通のもの、例えば業績予想の修正とかもタイトル指定してあげれば、抽出して通知することも可能です。株式売買されてる方なら興味ある情報の一つかもしれませんね。
シンプルに日付で取得したり、証券コードで取得したりもできるので、試してみると面白いかと思います。
コメント