筆者は大学での授業と簿記検定で少し会計をかじっただけの学生です。記事の中で何か間違ったことを言っているかもしれません。そのような点を発見されましたら、指摘して頂けると大変助かります。
PDFの有報から数字を見て図を作成...めんどくさいですよね?
データを突っ込むだけで図が作成できたら...楽ですよね?
ということで、EDINETから取得した有価証券報告書を分析し自動的に売上高や営業利益などの値を抽出した上でそれらを可視化して企業の財務分析が簡単にできるようなプログラムを作成していきます。
最終的な目標は財務三表図解分析法に出てくるような図を作成することです。
PLとBSを並べて図で分析することで、企業の財務分析を視覚的に行うことができます。
EDINETからはXBRL形式の有報がダウンロードできますが、初学者の私にとってこれを扱うのは難しかったので今回はCSVからデータを抽出していきます。(XBRLから抽出できないか色々やってかなり時間を取られてしまい、諦めてCSVから抽出することにしたことは秘密)
今回の記事では、CSVファイルから図の作成に必要なデータを抽出するところまでやっていこうと思います。
試しにEDINETからトヨタ自動車の有報(CSV)をダウンロードして中身をのぞいてみる
中身はこんな感じです。列名の要素ID
や項目名
などが何を示しているのか確認するためにEDINET書類閲覧ガイドを確認してみます。
とりあえず売上高の値を確認するには、項目名に売上高
とか入っているものを探せばよさそうですね。
売上高らしきものを見つけました。
要素ID(一番左の列)にはjpcrp_cor:NetSalesSummaryOfBusinessResults
と記されていますね。
そして、コンテキストIDの列も確認すると、CurrentYearDuration_NonConsolidatedMember
とあります。
ここで、EDINETが公開している報告書インスタンス作成ガイドラインを確認してみます。
CurrentYearDuration_NonConsolidatedMember
というコンテキストIDについて、「報告対象となる会計年度の個別の財務情報を報告するために利用します。」と説明されていますね。
つまりこのコンテキストIDがついている値は個別財務諸表の値ということです。
財務分析をするなら、連結財務諸表での値が欲しいですよね。
CurrentYearDuration
というコンテキストIDが連結財務諸表の当期連結期間であることを示すようなので、
要素IDがjpcrp_cor:NetSalesSummaryOfBusinessResults
で
コンテキストIDがCurrentYearDuration
のものを探せばいいだけですね。
しかしここで問題が発生しました。要素IDがjpcrp_cor:NetSalesSummaryOfBusinessResults
である行はこの5つしかなく、5つの行は全て個別財務諸表の値です。
連結での売上高がないなんてことはないと思うので探してみると、jpcrp030000-asr_E02144-000:OperatingRevenuesIFRSKeyFinancialData
という要素IDを発見しました。
項目名は書いてありませんが、国際会計基準(IFRS)での営業収益と言ったところでしょうか。コンテキストIDはCurrentYearDuration
で、営業収益の値は有報(PDF)のものと一致していたので、抽出する値はこれで間違いなさそうです。
ここで、jpcrp030000-asr_E02144-000:OperatingRevenuesIFRSKeyFinancialData
という要素IDがトヨタ自動車固有のものである場合、企業ごとに要素IDを確認しなければなりません。それを確認するために他のIFRS適用済企業の有報CSVを確認してみましょう。
本田技研工業(IFRS適用済企業)の有報と比較してみる
同じ製造業でIFRS適用済企業の本田技研工業の有報CSVでOperatingRevenuesIFRSKeyFinancialData
を検索した結果...
あれ?ない...
あれ??後ろに見えるのは、売上収益(IFRS)??
もしかして、企業によって要素IDの書き方が違う!????
「どの企業の有報でもCSVファイル突っ込むだけで図が出てくる」ようなプログラムを作成したかったのですが、これが本当なら企業ごとの要素IDに合わせて値を抽出する必要があります、これは困りました。
調べてみると企業が独自に定義したタクソノミが、有報に含まれるデータの企業間比較を難しくしていると指摘している論文がありました。
...とりあえず、今回の記事ではトヨタ自動車の要素IDを基準にして売上高, 営業利益, 当期純利益, 資産, 負債, 流動資産, 固定資産の値を抽出します。
CSV形式の有報から必要な値を抽出するプログラム(トヨタ自動車限定)
import pandas as pd
# CSVファイルを読み込む
file_path = "PATH_TO_CSV"
try:
df = pd.read_csv(file_path, encoding='utf-16le', delimiter='\t')
except Exception as e:
print(f"読み込みエラー: {e}")
exit()
# ID_expression_dict の定義
"""
ID_expression_dict dict:
key: (要素ID, コンテキストID)
value: [表示する時の項目名, 値(初期値は-1), 単位(円など、初期値は単位)]
"""
ID_expression_dict = {
('jpcrp030000-asr_E02144-000:OperatingRevenuesIFRSKeyFinancialData', 'CurrentYearDuration'): ['売上高(IFRS)', -1, '単位'],
('jpigp_cor:OperatingProfitLossIFRS', 'CurrentYearDuration'): ['営業利益(IFRS)', -1, '単位'],
('jpcrp_cor:ProfitLossAttributableToOwnersOfParentIFRSSummaryOfBusinessResults', 'CurrentYearDuration'): ['当期純利益(IFRS)', -1, '単位'],
('jpigp_cor:AssetsIFRS', 'CurrentYearInstant'): ['資産(IFRS)', -1, '単位'],
('jpigp_cor:LiabilitiesIFRS', 'CurrentYearInstant'): ['負債(IFRS)', -1, '単位'],
('jpigp_cor:CurrentAssetsIFRS', 'CurrentYearInstant'): ['流動資産(IFRS)', -1, '単位'],
('jpigp_cor:NonCurrentAssetsIFRS', 'CurrentYearInstant'): ['固定資産(IFRS)', -1, '単位']
}
# 行データを処理
for i in range(len(df)):
row = df.iloc[i]
key = (row['要素ID'], row['コンテキストID'])
if key in ID_expression_dict:
try:
ID_expression_dict[key][1] = int(row['値'])
except ValueError:
print(f"数値変換エラー: {row['値']}は数値ではありません")
ID_expression_dict[key][1] = None
ID_expression_dict[key][2] = row['単位']
# 値を表示
for element_name, value, unit in ID_expression_dict.values():
if isinstance(value, int):
formatted_value = f'{value:,}'
else:
formatted_value = value
print(f'{element_name}: {formatted_value}{unit}')
出力:
売上高(IFRS): 45,095,325,000,000円
営業利益(IFRS): 5,352,934,000,000円
当期純利益(IFRS): 4,944,933,000,000円
資産(IFRS): 90,114,296,000,000円
負債(IFRS): 54,874,958,000,000円
流動資産(IFRS): 34,714,279,000,000円
固定資産(IFRS): 55,400,017,000,000円
...はい、力技で実装しました。こういうのをハードコーディングって言うみたいですね。(良くない) 図の作成ができたら書き直します...
次回の記事について
とりあえず必要な値の抽出はできたので、次の記事では図の作成をします。また、それ以降の記事ではどの企業の売上高も取って来ることができるような方法を模索していこうと考えています。