Help us understand the problem. What is going on with this article?

XBRLから上場企業の決算書の情報を得る。

XBRLとは

XBRL は企業の決算書などのビジネスレポートを XML 形式で記述するための国際標準の仕様です。

日本ではすべての上場企業はXBRLの形式で有価証券報告書や四半期報告書などの決算書を金融庁に提出する義務があります。

決算書には貸借対照表、損益計算書、キャッシュ・フロー計算書など、企業活動を知るための重要な情報が含まれています。

XBRLファイルは金融庁のEDINETというウェブサイトで公開されていて、過去5年分くらいのデータが無料でダウンロードできます。

3600社ある上場企業の過去5年分の決算情報は膨大なデータなのでXBRLファイルが読めれば、株価予想とか色々なことに活用できそうです。

ただ、このXBRLの構造が非常に難解です。

3ヵ月くらいかけて調べて、ようやく以下のような決算情報が取得できるようになりました。
pythonでXBRLからJSONに変換し、ブラウザでJSONの中身を表示しています。
bs.png

XBRLにはXML形式の XBRLインスタンスファイル と、HTMLファイルの中にXBRLタグを埋め込んだ インラインXBRLファイル があります。
インラインXBRLファイルはウェブブラウザでそのまま表示できます。
上の画面で インラインXBRL表示 ボタンをクリックすると、以下のようにインラインXBRLファイルを見れます。
inline.png

以下のページにサンプルがありますので、XBRLからどんな情報が取得できるか確認できます。
http://lang.main.jp/xbrl/

プログラムは以下のGitHubで公開しています。
https://github.com/teatime77/xbrl-reader
プログラムのインストール方法や使い方はGitHubのページをご覧ください。

この記事の続きをQiitaに書きましたので、そちらも参照ください。
全上場企業の過去5年間の決算情報をCSVファイルに変換

XBRLファイルの取得

XBRLファイルはEDINETから以下の手順でダウンロードできます。
この例では、トヨタ自動車の有価証券報告書と四半期報告書の全期間のXBRLをダウンロードしています。
1. EDINETのホームページの 書類検索をクリックします。
2. 書類詳細検索をクリックします。
3. トヨタ自動車のEDINETコード(E02144)を入力します。EDINETコードが分からない場合は提出者名称に会社名を入力してから 検索ボタンをクリックすると一覧が出てきます。
4. 書類種別を指定する を選択します。
5. 有価証券報告書四半期報告書をチェックします。
6. 全期間を選択します。
7. 検索ボタンをクリックします。

edinet1.png

以下のように検索結果画面が表示されますので XBRL一括ダウンロード ボタンをクリックするとXBRLのZIPファイルが取得できます。
edinet2.png

ZIPファイルを解凍したら、pythonでXBRLからJSONに変換し、ブラウザでJSONの中身を表示できます。
プログラムの使い方はGitHubをご覧ください。
https://github.com/teatime77/xbrl-reader

以下では XBRLの内容を説明していきます。

フォルダーの構成

解凍したフォルダーには "S100B29E"のような英数字のフォルダーが複数個あり、その下に XBRL というフォルダーがあります。
XBRL フォルダーの下には AuditDocPublicDoc というフォルダーがあります。
AuditDoc は監査法人の監査報告書なので関係ありません。
決算情報は PublicDoc にあります。
public_doc.png

ファイルの種類

PublicDocには以下のファイルがあります。

  • インラインXBRLファイル
    ファイル拡張子は .htm です。
    HTMLファイルの中にXBRLタグが埋め込んであり、ウェブブラウザで開くと決算書の内容が見れます。

  • XBRLインスタンスファイル
    ファイル拡張子は .xbrl です。
    売上高や利益などの数値が書かれているXMLファイルです。

  • マニフェストファイル
    manifest_PublicDoc.xml というファイルです。
    インラインXBRLファイルやXBRLインスタンスファイルのファイル名が書かれています。

  • 提出者別タクソノミファイル
    ファイル拡張子が .xsd のファイルと,マニフェストファイル以外で拡張子が .xml のファイルです。
    各企業(提出者)に特有の項目の属性や日本語名などが定義されています。
    例えば、製薬会社の 新薬開発費 などです。

参考になる資料

XBRLについて説明した本やウェブサイトはいくつかありますが、最終的な拠り所はEDINETの操作ガイドにある文書です。

EDINET 操作ガイド
https://disclosure.edinet-fsa.go.jp/EKW0EZ0015.html

このページの以下の文書が特に重要です。

  • XBRL関連技術資料
    • EDINETタクソノミの設定規約書
  • 2018年版EDINETタクソノミ対応(平成30年2月28日公表)
    • EDINETタクソノミの概要説明
    • 提出者別タクソノミ作成ガイドライン
    • 報告書インスタンス作成ガイドライン

ただし、非常に分かりづらい文書で、わたしもほんの一部しか理解できていません。

会計基準

XBRLは国際標準の仕様ですが、決算書の作成のルール(会計基準)は国によって違います。

EUなど多くの国では国際財務報告基準( IFRS )を使いますが、日本の多くの企業では日本独自の会計基準( Japan GAAP )を使っています。
アメリカは US GAAP というのを使っています。
ただ、今後は日本もアメリカも徐々に IFRS になっていきそうです。

日本にも会計基準が IFRS の企業はありますが、EDINETにXBRLを提出する場合は金融庁の規則に従ってXBRLファイルを作成しています。
今回作ったプログラムは、この規則に従ったXBRLファイルを読めるようになっています。

金融庁のタクソノミと提出者別タクソノミ

PublicDocフォルダーにある提出者別タクソノミは各企業(提出者)に特有の項目を定義します。
売上高 などの一般的な項目は、金融庁が公開しているタクソノミで定義されています。

タクソノミは毎年少しずつ修正されるので、年度ごとのタクソノミが公開されています。

Japan GAAP のタクソノミは以下からダウンロードできます。
各ページの EDINETタクソノミ本体(ZIP:xxxKB)のリンクがタクソノミです。

IFRS のタクソノミは以下からダウンロードできます。
IFRS Taxonomy

IFRS のタクソノミの日本語訳は以下にあります。
IFRS Taxonomy translations

これらのファイルをダウンロードして1つにまとめたZIPファイルが以下にあります。
http://lang.main.jp/xbrl/data.zip

アプリの機能

XBRLの仕様は複雑なのですべての内容を解析できたわけではありません。

実装したのは以下の機能です。

  • コンテキストの処理をします。
    たとえば売上高と言っても今期の売上高や前期の売上高など文脈(コンテキスト)によって意味が違うのでコンテキストで区別します。

  • 英語の項目名を日本語のラベルに変換します。例 : NetSales → 売上高

  • 資産 = 流動資産 + 固定資産 のように集計単位でグルーピングします。

以下で詳しく説明します。
- コンテキスト
- ラベル
- 集計方法

※ アプリはXBRLインスタンスファイルとインラインXBRLファイルの両方を扱えますが、以下ではXBRLインスタンスファイルの場合について説明します。
※ アプリを実行した時もデフォルトではXBRLインスタンスファイルを読んでいます。

コンテキスト

コンテキストは日本語にすると文脈ですが、XBRLファイルの中の各インスタンスがどの文脈に含まれるかを示します。

例えば、売上高 だけでは、それが今期なのか前期なのか前々期なのか分かりません。

また、大企業では セグメント と言って事業ごとに 売上高 を計算するので、どの セグメント なのかも指定する必要があります。
実際XBRLファイルの中には以下のように 売上高(NetSales) の項目がたくさんあり、コンテキストの参照( contextRef )で区別しています。

<jppfs_cor:NetSales contextRef="Prior1YearDuration" unitRef="JPY" decimals="-6">8737320000000</jppfs_cor:NetSales>
<jppfs_cor:NetSales contextRef="CurrentYearDuration" unitRef="JPY" decimals="-6">10482520000000</jppfs_cor:NetSales>
<jppfs_cor:NetSales contextRef="Prior1YearDuration_ReportableSegmentsMember" unitRef="JPY" decimals="-6">8822296000000</jppfs_cor:NetSales>
<jppfs_cor:NetSales contextRef="CurrentYearDuration_ReportableSegmentsMember" unitRef="JPY" decimals="-6">10580416000000</jppfs_cor:NetSales>
<jppfs_cor:NetSales id="fact53" contextRef="Prior1YearDuration_NonConsolidatedMember" unitRef="JPY" decimals="-6">3526252000000</jppfs_cor:NetSales>
<jppfs_cor:NetSales id="fact54" contextRef="CurrentYearDuration_NonConsolidatedMember" unitRef="JPY" decimals="-6">3737844000000</jppfs_cor:NetSales>

このように時期や事業セグメントなどの文脈を指定するのが コンテキスト です。

時期と時点

コンテキストの中で重要なのが時期と時点です。
以下は時期と時点の例です。

  • 提出日時点
    会社名、本店の所在の場所、当会計期間終了日などの情報が入ります。

  • 当期連結時点, 前期連結時点, 当四半期会計期間連結時点
    資産、負債、純資産など貸借対照表の情報が入ります。

  • 当期連結期間, 前期連結期間, 当四半期会計期間連結期間
    売上高などの損益計算書の項目やキャッシュ・フロー計算書の情報が入ります。

※ 時期と時点のコンテキストの説明は 報告書インスタンス作成ガイドライン5-4-5 コンテキストの設定例にあります。

ディメンションとメンバー

ディメンションとメンバーは以下のような表形式のコンテキストを表現するのに使います。

ディメンション(事業セグメント)
メンバー(関東) メンバー(関西) メンバー(四国)
売上高 100 200 300
売上原価 90 180 250

関東、関西、四国などの事業セグメントのメンバーは、売上高売上原価 が違うのでコンテキストで指定する必要があるわけです。

以下は、今期の関東のコンテキストの簡略化した記述です。
2行目の dimension="jpcrp_cor:OperatingSegmentsAxis" は事業セグメントを表します。

<xbrli:context id="CurrentYearDuration_KantoSegmentsMember">
    <xbrldi:explicitMember dimension="jpcrp_cor:OperatingSegmentsAxis">KantoSegmentsMember</xbrldi:explicitMember>
</xbrli:context>

1行目のidは CurrentYearDuration_KantoSegmentsMemberとなっていて、idの先頭で期間が当期連結期間( CurrentYearDuration )であることを示しています。
※ idの命名規約の説明は 報告書インスタンス作成ガイドライン5-4-1 コンテキストIDの命名規約にあります。

以下は、関東の売上高の記述です。contextRefCurrentYearDuration_KantoSegmentsMemberのコンテキストを参照しています。
jppfs_cor:NetSalesは売上高です。

<jppfs_cor:NetSales contextRef="CurrentYearDuration_KantoSegmentsMember" >100</jppfs_cor:NetSales>

XML名前空間

jppfs_cor:NetSalesは売上高と書きましたが、なぜそれが分かったのでしょう?

実はXBRLファイルの先頭でjppfs_corの名前空間のURIが以下のように指定されていました。

<xbrli:xbrl  xmlns:jppfs_cor="http://disclosure.edinet-fsa.go.jp/taxonomy/jppfs/2018-02-28/jppfs_cor" >

つまり、このURIの名前空間の中の NetSales を調べればよいということです。

ただし、このURIは単にユニークなIDという意味しかなく、実際のスキーマ定義ファイルの場所を指してるわけではありません。

EDINETからダウンロードした金融庁のタクソノミの中の jppfs_cor_2018-02-28.xsd がスキーマ定義ファイルです。
※ URIとスキーマ定義ファイルの対応の説明は EDINET タクソノミの設定規約書3-2-1 語彙層のファイル にあります。

このファイルを適当なテキストエディタで開いてNetSales で検索すると、 name の値が NetSales になっている行があります。

<xsd:element name="NetSales" id="jppfs_cor_NetSales" type="xbrli:monetaryItemType" substitutionGroup="xbrli:item" abstract="false" nillable="true" xbrli:balance="credit" xbrli:periodType="duration"/>

色んな属性が書いてありますが、type="xbrli:monetaryItemType" とあり、 NetSales のデータ型が金額であることが分かります。
※ データ型の説明は EDINETタクソノミの設定規約書3-2-3 データ型 にあります。

また、 id="jppfs_cor_NetSales" とありますが、これが次で説明するラベルを取得するためのキーになります。

ラベル

jppfs_cor_2018-02-28.xsd があるフォルダーに label というフォルダーがあり、その中に jppfs_2018-02-28_lab.xmlというファイルがあります。
※ このファイルの記述は EDINETタクソノミの設定規約書図表3-2-6 名称リンクベースファイル名 にあります。
taxonomy.png

jppfs_2018-02-28_lab.xml をテキストエディタで開き、 jppfs_cor_NetSales で検索すると、以下の行があります。

<link:loc xlink:type="locator" xlink:href="../jppfs_cor_2018-02-28.xsd#jppfs_cor_NetSales" xlink:label="NetSales"/>

xlink:href="../jppfs_cor_2018-02-28.xsd#jppfs_cor_NetSales" とあります。
つまり、一つ上のフォルダーにある jppfs_cor_2018-02-28.xsd で定義されている jppfs_cor_NetSales についての情報だと言っています。

xlink:label="NetSales" とあるので NetSales で検索すると、以下の行で xlink:from="NetSales" とあります。

<link:labelArc xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/concept-label" xlink:from="NetSales" xlink:to="label_NetSales"/>

xlink:to="label_NetSales" とあるので label_NetSales で検索すると、以下の行で xlink:label="label_NetSales" とあります。

<link:label xlink:type="resource" xlink:label="label_NetSales" xlink:role="http://www.xbrl.org/2003/role/label" xml:lang="ja" id="label_NetSales">売上高</link:label>

ついに、ここで 売上高 のテキストを見つけました !

ラベルの取得は複雑ですが XLink の仕様に従っています。

  • 最初の行の xlink:type="locator" はラベル付けされる要素を指します。
  • 2番目の行の xlink:type="arc" は最初の行と3番目の行をつなげる働きをします。
  • 3番目の行の xlink:type="resource" に日本語のテキストがあります。

これで、複雑なジグソーパズルのすべてのピースがそろいました。
整理すると以下のようになります。

  1. 始まりはXBRLファイルの中の jppfs_cor:NetSales でした。
  2. XBRLファイルの先頭で jppfs_cor の 名前空間のURIは http://disclosure.edinet-fsa.go.jp/taxonomy/jppfs/2018-02-28/jppfs_cor であると言われました。
  3. このURIには何もありません。金融庁のタクソノミの中の jppfs_cor_2018-02-28.xsd がスキーマ定義ファイルです。
  4. そのファイルの中に name の値が NetSales の行があり、 idjppfs_cor_NetSales であると言われました。
  5. このファイルと同じフォルダーに label というフォルダーがあり、その中に jppfs_2018-02-28_lab.xmlというファイルがあります。
  6. このファイルを開いて jppfs_cor_NetSales で検索したら、xlink:labelNetSales であると言われました。
  7. NetSales で検索したら、xlink:tolabel_NetSales であると言われました。
  8. label_NetSales で検索して、ようやく 売上高 のテキストを見つけました。

集計方法

通常の決算書のように集計単位にグルーピングすると、わかりやすくなります。

要領はラベルの取得と同じです。

以下の例で説明します。
売上総利益又は売上総損失(△) = 売上高 - 売上原価

XMLの要素名で書くと GrossProfit = NetSales - CostOfSales です。

金融庁のタクソノミの中の jppfs_cor_2018-02-28.xsd というファイルの中で、 name の値が GrossProfit , NetSales , CostOfSales の行を探すところまでは同じです。

以下のように idjppfs_cor_GrossProfit , jppfs_cor_NetSales , jppfs_cor_CostOfSales でした。

<xsd:element name="GrossProfit" id="jppfs_cor_GrossProfit" type="xbrli:monetaryItemType" substitutionGroup="xbrli:item" abstract="false" nillable="true" xbrli:balance="credit" xbrli:periodType="duration"/>
<xsd:element name="NetSales" id="jppfs_cor_NetSales" type="xbrli:monetaryItemType" substitutionGroup="xbrli:item" abstract="false" nillable="true" xbrli:balance="credit" xbrli:periodType="duration"/>
<xsd:element name="CostOfSales" id="jppfs_cor_CostOfSales" type="xbrli:monetaryItemType" substitutionGroup="xbrli:item" abstract="false" nillable="true" xbrli:balance="debit" xbrli:periodType="duration"/>

さっきは label フォルダーの中の jppfs_2018-02-28_lab.xml を調べましたが、集計では r というフォルダーの下でファイル名が *_cal_*.xml のパターンのファイルを調べます。

ラベルの場合と同様にXLinkの仕様に従って xlink:type="locator"xlink:type="arc" の要素を使います。

以下のように xlink:hrefjppfs_cor_2018-02-28.xsd を指す行があり、xlink:labelGrossProfit , NetSales , CostOfSales です。

<link:loc xlink:type="locator" xlink:href="../../jppfs_cor_2018-02-28.xsd#jppfs_cor_GrossProfit" xlink:label="GrossProfit"/>
<link:loc xlink:type="locator" xlink:href="../../jppfs_cor_2018-02-28.xsd#jppfs_cor_NetSales" xlink:label="NetSales"/>
<link:loc xlink:type="locator" xlink:href="../../jppfs_cor_2018-02-28.xsd#jppfs_cor_CostOfSales" xlink:label="CostOfSales"/>

同じファイルに以下の2行があります。

<link:calculationArc xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/summation-item" xlink:from="GrossProfit" xlink:to="NetSales" order="1.0" weight="1"/>
<link:calculationArc xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/summation-item" xlink:from="GrossProfit" xlink:to="CostOfSales" order="2.0" weight="-1"/>

2行とも xlink:fromGrossProfit で、xlink:toNetSalesCostOfSales です。

xlink:arcrole="http://www.xbrl.org/2003/arcrole/summation-item" とあるので、 NetSalesCostOfSalesGrossProfit に加算(summation)することを指定しています。

weight は足し算するときの重みです。 CostOfSalesweight-1 なので、 引き算せよ ということです。

order は表示順の指定です。 NetSales , CostOfSales の順で表示せよということです。

おわりに

3ヵ月くらい前に機械学習の勉強のためのテストデータとしてXBRLから決算情報を得ようとしたのが始まりでした。

しかし、予想以上に手間取ってしまい、その間まったく機械学習の勉強ができず、これでは本末転倒なのでとりあえず今の段階のものを公開することにしました。

いろいろ不具合もあるかと思いますが、すみません。

今後、少しずつデバッグしていく予定です。

ここまで読んでいただき、ありがとうございました。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした