[ データ基盤 ]

決算短信 XBRL パーサの設計 — IFRS と JGAAP を統一スキーマに収める

上場企業の決算データを構造化するには、銘柄ごとに異なる XBRL タクソノミと会計基準の差異を吸収する仕組みが必要だ。tse-ed-t タクソノミ準拠のパーサ設計と IFRS/JGAAP の統一スキーマ、ファイルパスからのメタデータ抽出規則を解説する。

著者: 森本拓見
#claude-code #ai-driven-dev #xbrl #financial-data

はじめに

上場企業の決算データは TDnet(適時開示情報閲覧サービス)を通じて XBRL 形式で公開されている。機械可読を前提とした規格だが、「機械で読める」と「構造化して使える」はまったく別の話だ。

XBRL は XML ベースで、タクソノミ(要素定義)と実データ(インスタンス)が分離している。タクソノミは会計基準(JGAAP / IFRS / US-GAAP)ごとに異なり、さらに各社が独自の拡張タクソノミを持つこともある。売上高ひとつとっても、JGAAP では jppfs_cor:NetSales、IFRS では ifrs-full:Revenue と別の要素名で定義されている。全社を同一のスプレッドシートに落とすためには、この差異を吸収する変換層が必要になる。

medalion(八雲の金融データ収集基盤)でこの問題に向き合い、JGAAP と IFRS を統一スキーマに収めるパーサを実装した。その設計の考え方を書く。


課題: 銘柄ごとに XBRL タクソノミ・形式・項目が違う

XBRL のどの要素に何の数値が入っているかは、会計基準とタクソノミのバージョンによって変わる。実際に複数銘柄の XBRL を解析してみるといくつかのパターンに気づく。

会計基準による要素名の違いが最も大きな障壁だ。JGAAP の 経常利益 は IFRS には存在しない概念で、代わりに 税引前利益 が使われる。逆に IFRS の EBITDA は JGAAP の標準タクソノミには定義されていない。これを同一のスキーマ列に収めようとすると、「JGAAP なら A、IFRS なら B」という分岐が至る所に必要になる。

拡張タクソノミの存在も厄介だ。ある銘柄はセグメント情報を標準タクソノミの要素で報告するが、別の銘柄は独自要素 {company-ns}:SegmentRevenue を定義している。セグメントパーサを汎用化しようとすると、この独自要素を無視するか、銘柄ごとに対応表を持つかの選択を迫られる。

XBRL ファイルの構成も ZIP の展開構造・コンテキスト ID の命名規則・単位定義など細部が銘柄によって微妙に異なる。正規表現で要素を引いても拾えないケースが出る。


アプローチ: tse-ed-t タクソノミに準拠したパーサ

東証が定める決算短信タクソノミ(tse-ed-t)に絞ることで、バラツキの問題を大幅に削減できる。上場企業が TDnet に提出する決算短信は、この標準タクソノミに準拠することが義務付けられているため、主要な財務項目の要素名はある程度統一されている。

kessan_xbrl.py のパーサは次の方針で動作する。

  1. ZIP を展開し、.xbrl(インスタンス文書)と *.xsd(スキーマ定義)を識別する
  2. インスタンス文書のルート名前空間から会計基準(JGAAP / IFRS / US-GAAP)を判定する
  3. 会計基準に応じた要素名マップを使って財務項目を抽出する
  4. 抽出した数値を統一 JSON 構造(schema.pymap_to_*_row が参照するキー)に変換する

ライブラリは arelle を優先し、インポートに失敗した場合は xml.etree.ElementTree にフォールバックする。arelle はタクソノミの解決とコンテキスト管理を自動で行うため精度が高いが、環境によって導入が難しい場面があるため、ETL の堅牢性を優先してフォールバックを用意している。


IFRS と JGAAP の統一スキーマ設計

出力スキーマの設計方針は「会計基準の差異を列レベルで明示する」だ。

損益計算書(pl タブ)を例に取ると、経常利益(JGAAP 固有)と税引前利益(IFRS/US-GAAP)は別列として定義している。

Ordinary_Income     — 経常利益(JGAAP のみ。IFRS/US-GAAP は空)
Pretax_Income       — 税引前利益(IFRS/US-GAAP のみ。JGAAP は空)

どちらかを「上位概念に丸める」設計も考えられたが、意味の異なる数値を同一列に入れると後からの分析で誤りが生じやすい。欠損列は空のまま残し、会計基準は master.meta タブの Accounting_Std 列で一元管理することで、分析側が適切に補正できるようにした。

IFRS と JGAAP の両方に共通する項目——売上高・営業利益・純利益・総資産・純資産——は同一列に収めている。ただし XBRL 上の要素名は会計基準によって異なるため、パーサ内に次のようなマップを持つ。

ELEMENT_MAP = {
    "JGAAP": {
        "Revenue":      "jppfs_cor:NetSales",
        "Op_Income":    "jppfs_cor:OperatingIncome",
        "Net_Income":   "jppfs_cor:ProfitLossAttributableToOwnersOfParent",
        "Ordinary_Income": "jppfs_cor:OrdinaryIncome",
    },
    "IFRS": {
        "Revenue":      "ifrs-full:Revenue",
        "Op_Income":    "ifrs-full:ProfitLossFromOperatingActivities",
        "Net_Income":   "ifrs-full:ProfitLossAttributableToOwnersOfParent",
        "Pretax_Income": "ifrs-full:ProfitLossBeforeTax",
    },
}

このマップを通すことで、会計基準の違いをパーサ内部に閉じ込め、呼び出し側は統一キー(RevenueOp_Income など)だけを扱えばよい構造になっている。


ファイルパスからメタデータを抽出する規則

TDnet から取得した XBRL ZIP のファイル名には、証券コード・決算期・四半期区分などのメタデータが埋め込まれている。パーサはこれを正規表現で解析し、スキーマの Period 列(2024.03-Q1 など)を生成する。

典型的なファイル名パターン:

{doc_id}_{ticker}_FR_{yyyymm}_{quarter}_xbrl.zip

{quarter}1q(第1四半期)・2q3q0 または 4q(通期)の形式で入っている。これを Period フォーマット(2024.03-Q12024.03-FY など)に変換する規則は kessan_xbrl.py 内の parse_period_from_path() 関数に集約している。

QUARTER_MAP = {"1q": "Q1", "2q": "Q2", "3q": "Q3", "0": "FY", "4q": "FY"}

ファイルパスから取れない情報——決算月(Fiscal_Month)や会計基準(Accounting_Std)——は master.meta タブを参照する設計にした。データの SSOT を一箇所に集約し、パーサが外部参照できるようにすることで、同じ情報をファイルパスとスプレッドシートで二重管理する事態を避けている。


運用してわかった効果と落とし穴

実際にある銘柄(トヨタ・ソニーなど大型株を含む複数社)で検証して気づいたことをまとめる。

効果として大きかったのは処理速度だ。 PDF パーサ(kessan_pdf.py)と比較して、XBRL パーサは数値抽出の精度が高く後処理が少ない。PDF では「百万円」単位の誤認識や改行をまたいだ数値の結合ミスが発生するが、XBRL では単位(unitRef)とスケール(decimals)が要素属性として明示されているため、この問題がほぼ発生しない。

落とし穴として頻出したのは、コンテキスト ID のバラツキだ。 XBRL のコンテキストは「どの期間の数値か」を定義するが、通期・前期・累計期間の区別に使うコンテキスト ID の命名が銘柄によって異なる。FilingDateInstant を使う銘柄もあれば、CurrentYearDuration を使う銘柄もある。現在はコンテキスト期間の開始日・終了日を直接解析して Period を決定する方式に切り替え、ID 名への依存を排除している。

もうひとつの落とし穴は セグメント注記の非標準性だ。セグメント数が多い企業では、標準タクソノミの範囲に収まらず独自要素を使うケースがある。現時点では segments タブへのデータ流し込みは基本パターンに対応しており、独自要素の解析は未解決の残課題として残っている。


まとめ + 関連記事

XBRL パーサの設計で学んだ最大の教訓は、規格があっても実装はバラつくという事実だ。tse-ed-t タクソノミという共通規格があっても、その適用方法には銘柄ごとの差異が生じる。パーサはその差異を吸収する変換層として機能し、後段のスプレッドシートや分析コードを規格の差から守る役割を持つ。

設計のポイントを整理すると:

  • 会計基準ごとの要素名マップをパーサ内部に閉じ込め、呼び出し側は統一キーを使う
  • JGAAP 固有列と IFRS 固有列は別列に定義し、欠損は空のまま残す
  • ファイルパスからメタデータを抽出し、SSOT は master.meta タブに集約する
  • コンテキスト ID 名への依存は排除し、期間の開始日・終了日から Period を決定する

medallion の全体像——株式決算データの収集・蓄積から montage への提供まで——はYakumo の AI 駆動開発のリアルで触れている。パーサの出力を受け取る側のスキーマ設計方針についてはBlock Schema と Zod — 生成 AI 出力をバリデーションする型安全パイプラインが参考になる。データの型を境界で守るという発想は、XBRL パーサとパイプラインバリデーションで共通している。

ShareX でシェア