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

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

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

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

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

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

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

3ヵ月くらいかけて調べて、ようやく以下のような決算情報が取得できるようになりました。
pythonでXBRLからJSONに変換し、ブラウザでJSONの中身を表示しています。
![bs.png](https://qiita-image-store.s3.amazonaws.com/0/118740/085a0b3f-72b9-28db-d083-91b6de73e9ba.png)

XBRLにはXML形式の **XBRLインスタンスファイル** と、HTMLファイルの中にXBRLタグを埋め込んだ **インラインXBRLファイル** があります。
インラインXBRLファイルはウェブブラウザでそのまま表示できます。
上の画面で **インラインXBRL表示** ボタンをクリックすると、以下のようにインラインXBRLファイルを見れます。
![inline.png](https://qiita-image-store.s3.amazonaws.com/0/118740/83d9aec8-bc8e-c094-de39-02490b5b0e51.png)

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

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


**この記事の続きをQiitaに書きましたので、そちらも参照ください。**
[全上場企業の過去５年間の決算情報をCSVファイルに変換](https://qiita.com/teatime77/items/e5aa2d9027749768f50d)


# XBRLファイルの取得

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

![edinet1.png](https://qiita-image-store.s3.amazonaws.com/0/118740/19537dc5-fdec-b205-f9b1-c2f8a2a43590.png)


以下のように検索結果画面が表示されますので **XBRL一括ダウンロード** ボタンをクリックするとXBRLのZIPファイルが取得できます。
![edinet2.png](https://qiita-image-store.s3.amazonaws.com/0/118740/b2b9b81f-5270-fa1f-ecf7-add381478c7b.png)


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


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

## フォルダーの構成

解凍したフォルダーには "S100B29E"のような英数字のフォルダーが複数個あり、その下に **XBRL** というフォルダーがあります。
**XBRL** フォルダーの下には **AuditDoc** と **PublicDoc** というフォルダーがあります。
**AuditDoc** は監査法人の監査報告書なので関係ありません。
決算情報は **PublicDoc** にあります。
![public_doc.png](https://qiita-image-store.s3.amazonaws.com/0/118740/54d9b83e-61de-a13a-7a35-71c89abf9812.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](https://disclosure.edinet-fsa.go.jp/EKW0EZ0015.html)

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

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

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


# 会計基準

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

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

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

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

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

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

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

- [2018年版EDINETタクソノミの公表について](https://www.fsa.go.jp/search/20180228.html)
- [2017年版EDINETタクソノミの公表について](https://www.fsa.go.jp/search/20170228.html)
- [2016年版EDINETタクソノミの公表について](https://www.fsa.go.jp/search/20160314.html)
- [2015年版EDINETタクソノミの公表について](https://www.fsa.go.jp/search/20150310.html)
- [2014年版EDINETタクソノミの公表について](https://www.fsa.go.jp/search/20140310.html)
- [次世代EDINETタクソノミの公表について](https://www.fsa.go.jp/search/20130821.html)

**IFRS** のタクソノミは以下からダウンロードできます。
[IFRS Taxonomy](https://www.ifrs.org/issued-standards/ifrs-taxonomy/#annual-taxonomies)

**IFRS** のタクソノミの日本語訳は以下にあります。
[IFRS Taxonomy translations](https://www.ifrs.org/issued-standards/ifrs-taxonomy/ifrs-taxonomy-translations/)

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

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

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

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

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

- **資産 ＝ 流動資産 ＋ 固定資産** のように集計単位でグルーピングします。

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

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


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

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

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

```xml
<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 コンテキストの設定例**にあります。


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

<table>
<thead>
<tr><th></th><th align="center" colspan=3>ディメンション(事業セグメント)</th></tr>
<tr><th></th><th>メンバー(関東)</th><th>メンバー(関西)</th><th>メンバー(四国)</th></tr>
</thead>
<tbody>
<tr><td>売上高</td><td>100</td><td>200</td><td>300</td></tr>
<tr><td>売上原価</td><td>90</td><td>180</td><td>250</td></tr>
</tbody>
</table>

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

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

```xml
<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の命名規約**にあります。

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

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

# XML名前空間

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

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

```xml
<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** になっている行があります。

```xml
<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](https://qiita-image-store.s3.amazonaws.com/0/118740/d0b643d0-b5c2-97fc-dfc5-929f62c50b12.png)

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

```xml
<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"** とあります。

```xml
<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"** とあります。

```xml
<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** の行があり、 **id** は **jppfs_cor_NetSales** であると言われました。
5. このファイルと同じフォルダーに **label** というフォルダーがあり、その中に **jppfs_2018-02-28_lab.xml**というファイルがあります。
6. このファイルを開いて **jppfs_cor_NetSales** で検索したら、**xlink:label** は **NetSales** であると言われました。
7.  **NetSales** で検索したら、**xlink:to** は **label_NetSales** であると言われました。
8.  **label_NetSales** で検索して、ようやく **売上高** のテキストを見つけました。

# 集計方法

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

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

以下の例で説明します。
**売上総利益又は売上総損失（△） ＝ 売上高 － 売上原価**

XMLの要素名で書くと **GrossProfit ＝ NetSales － CostOfSales** です。

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

以下のように **id** は **jppfs_cor_GrossProfit , jppfs_cor_NetSales , jppfs_cor_CostOfSales** でした。

```xml
<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:href** で **jppfs_cor_2018-02-28.xsd** を指す行があり、**xlink:label** は **GrossProfit , NetSales , CostOfSales** です。

```xml
<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"/>
```

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

```xml
<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"/>
```
２行とも **xlink:from** は **GrossProfit** で、**xlink:to** は **NetSales** と **CostOfSales** です。

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

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

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

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

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

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

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

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