XBRLの勘定科目タグには日付が設定されています。全上場企業・全期間の勘定科目の決算データベースを作るにあたって、この日付をもとに時系列を整理します。とても重要な情報です。その取得方法です。
contextタグの辞書を作る
勘定科目には「contextRef」という属性がありますが、それを「id」にして日付を定義しているのが「context」タグです。その中の「period」タグに日付が入っています。
日付は「startDate(開始日)」、「endDate(終了日)」、「instant(期末日)」というタグに入っています。
XBRLを読み込むときに、contextタグのid属性をキーにして日付の辞書を作っておけば、勘定科目を取得すると同時に日付も取得できます。そのプログラム例を示します。
XBRLクラスの作成と初期化
XBRLファイルを読み込むためのクラスを作ります。初期化の部分です。
ファイルの読み込み、名前空間の定義、contextのタグ名と属性名を定義します。
"""xbrl_jpcrp.py"""
from lxml.etree import fromstring as etree_fromstring
from collections import OrderedDict
class parser:
def __init__(self, xbrl_file):
# XMLファイルを読み込む
self.xbrl_file = xbrl_file
self.root = self.get_etree_obj_from_file(self.xbrl_file)
# 名前空間取得
self.nsmap = self.root.nsmap
# 名前空間(ns:NameSpace)の接頭辞を定義
self.pre_xbrli = 'xbrli'
# タグ名/属性名定義
self.xbrli_context = '{%s}context' % self.nsmap[self.pre_xbrli]
self.xbrli_period = '{%s}period' % self.nsmap[self.pre_xbrli]
self.xbrli_start_date = '{%s}startDate' % self.nsmap[self.pre_xbrli]
self.xbrli_end_date = '{%s}endDate' % self.nsmap[self.pre_xbrli]
self.xbrli_instant = '{%s}instant' % self.nsmap[self.pre_xbrli]
return
XBRLファイル読み込みメソッドを追加
lxml.etreeでXBRLのテキストを読み込む部分です。これは「xbrl」の他に「xsd」、「lab」などを読み込むのにも使えます。ファイルを決め打ちしないので、selfは不要です。なので、「@staticmethod」でデコレートしてます。
@staticmethod
def get_etree_obj_from_file(file):
"""XMLファイルを読み込む"""
with open(file, 'rb') as f:
return etree_fromstring(f.read())
contextタグ読み込みメソッドを追加
id属性をキーにして、periodタグとその下の日付タグの辞書を作るメソッドです。
def get_context_tags(self):
"""contextタグ取得"""
od = OrderedDict()
for etree in self.root.findall('.//%s' % self.xbrli_context):
# id属性の値を取得
key_id = etree.get('id')
# id属性をキーにして辞書を作成
od.update({key_id:OrderedDict()})
# periodタグ取得
period = OrderedDict()
et_period = etree.find('.//%s' % self.xbrli_period)
# startDate, endDate, instantタグ取得
period.update(self.get_date_tags(et_period))
od[key_id].update({'period':period})
return od
OrderedDict()を使うと、キーがXBRLファイルと同じ順番に並ぶので、何かとデバッグしやすいです。普通の辞書「{}とかdict()」でも動きます。
startDate・endDate・instantを読み込むメソッドを追加
開始日、終了日、期末日を読み込むメソッドです。
def get_date_tags(self, etree):
"""日付タグ取得"""
od = OrderedDict()
# 開始日を検索
et_start_date = etree.find('.//%s' % self.xbrli_start_date)
if et_start_date is not None:
# 開始日を追加
od.update({'startDate':et_start_date.text})
# 終了日を検索
et_end_date = etree.find('.//%s' % self.xbrli_end_date)
# 終了日を追加
od.update({'endDate':et_end_date.text})
else:
# 期末日を検索
et_instant = etree.find('.//%s' % self.xbrli_instant)
# 期末日を追加
od.update({'instant':et_instant.text})
return od
これでcontextの辞書が作れますので、実際に使ってみます。
勘定科目のcontextRefから日付を取得する
先ほど作った「xbrl_jpcrp.py」をインポートしてXBRLファイルを読み込みます。
contextの辞書を取得して、勘定科目のcontextRefを入れます。
日付情報が取得できます。
import xbrl_jpcrp
def proc_xbrl(file):
"""XBRLからデータ取得"""
# ファイル読み込み
xbrl = xbrl_jpcrp.parser(file)
# contextタグ取得
# id属性(contextRef)をキーにして日付の辞書を作成
context_tags = xbrl.get_context_tags()
# 【データ取得例】
# 名前空間(ns:NameSpace)から名前を取得します。
namespace = xbrl.root.nsmap['jpcrp_cor']
# タグ名の大文字小文字は保存されます。
tag = 'NetSalesSummaryOfBusinessResults'
# 属性名の大文字小文字も保存されます。
attr = 'contextRef'
value = 'CurrentYearDuration'
# 検索(XPATHのように指定します)
xpath = './/{%s}%s[@%s="%s"]' % (namespace, tag, attr, value)
data = xbrl.root.find(xpath)
# contextRef属性取得
context_ref = data.get(attr)
# contextタグから日付を取得
date = context_tags[context_ref]['period']
# 表示
print('検索文字列: %s' % xpath)
print('日付(開始日): %s' % date['startDate'])
print('日付(終了日): %s' % date['endDate'])
print('金額: {value:,} {unit}'.format(
value=int(data.text), unit=data.get('unitRef')))
return
表示例です。
検索文字列: .//{http://disclosure.edinet-fsa.go.jp/taxonomy/jpcrp/2017-02-28/jpcrp_cor}NetSalesSummaryOfBusinessResults[@contextRef=”CurrentYearDuration”]
日付(開始日): 2016-04-01
日付(終了日): 2017-03-31
金額: 11,720,041,000,000 JPY
以上です。