[PYTHON] Follow the XBRL taxonomy display link using the OSS Arrele API

Nice to meet you, I am member O of the development committee of XBRL Japan.

The taxonomy of XBRL contains useful information, but it is quite difficult to analyze it in detail. This time, I will introduce how to use the taxonomy of XBRL using OSS called Arelle.

1.First of all

In a previous article, I showed you how to extract a specific subject from the financial information of a company published in XBRL. ・ Let's automatically extract employee information such as average salary from the XBRL data disclosed by EDINET (5/10)

If you know the subject you want to retrieve as data, you can extract the value of that subject directly from the XBRL instance.

However, the XBRL instance only contains the value of the item and similar information. Subject definitions and display relationships are defined in the subject dictionary called XBRL Taxonomy.

In this article, I will use Arelle's API to extract the structural relationships contained in the XBRL taxonomy presentation link.

Please refer to the following article for an explanation of the basic structure of XBRL and the XBRL taxonomy. ・ Learn more about XBRL (9/10)

2 Advance preparation

2.1 Preparing Arelle

Install the XBRL Parser called Arelle.

The installation method is as follows.

  1. Download the source code of arelle from https://github.com/Arelle/Arelle
  2. Pass the path to the downloaded source code

In addition, if you look at other articles, installation using the pip command is introduced, but please note that Arelle's API is not supported by pip and it is not the latest (confirmed by the developer) ). If you use the one installed with pip, you may get an unexpected error.

2.2 Download XBRL data

Download the appropriate company's securities report from EDINET. This time, I am using the 2020 securities report of a major IT company.

3 Introduction of display links

The display link defines the display relationship between items. If you take a look at the consolidated management indicators, etc. of the securities report downloaded above, you can see that the subjects included in the consolidated management indicators, etc. are listed. The figure below is an example. presentationLinkDetail.png Relationships between such items are defined in groups called extended link roles. By the way, order is an attribute for defining the display order, and arcrole is an attribute for defining the relationship. Although arcrole is displayed as pareht-child in the figure, the actual value is http://www.xbrl.org/2003/arcrole/parent-child, which clearly indicates that it is a parent-child relationship. I will.

presentationLink.png

By analyzing the relationship between these items, it is possible to automatically create tables and the like.

4 program

Introducing a program that traces the parent-child relationship of items defined in consolidated management indicators. That's why it's a sample code. For the file path, etc., specify an appropriate value according to the environment.

Code


#!/usr/bin/env python
# -*- coding: utf-8 -*-

from arelle import ModelManager
from arelle import Cntlr
from arelle import ModelDtsObject
from arelle import ModelValue
from arelle import XbrlConst

import sys

#Input file specification(Included here in the downloaded securities report.Please specify the xbrl file.
filePath = './data/sample.xbrl'

#Specifying the output file
fo = open('./output.txt', 'w', encoding='utf-8')


#A function that recursively outputs while following the display link
def printLink(linkrole, modelObject, indent, relModels):
    
    indentStr = "  ";
    for i in range(indent):
        indentStr += "  ";
    
    for relModel in relModels.fromModelObject(modelObject):
        if relModel.linkrole == linkrole:
            print(indentStr, "from: ", relModel.fromModelObject.qname)
            print(indentStr, "to: ", relModel.toModelObject.qname)
            print("\n")
            #Follow the link recursively
            printLink(linkrole, relModel.toModelObject, indent+1, relModels)

sys.stdout = fo

ctrl = Cntlr.Cntlr()

#Create a model of XBRL
modelManager = ModelManager.initialize(ctrl)
modelXbrl = modelManager.load(filePath)

#Get parentchild of presentationLink
parentChilds = modelXbrl.relationshipSet(XbrlConst.parentChild)

#This time use a specific extended link role
targetLinkrole = "http://disclosure.edinet-fsa.go.jp/role/jpcrp/rol_BusinessResultsOfGroup"
rootElementName = "jpcrp_cor:BusinessResultsOfGroupHeading"

for i, modelObject in enumerate(modelXbrl.modelObjects):
    if type(modelObject) is ModelDtsObject.ModelConcept and str(modelObject.qname) == rootElementName:
        print(modelObject.qname)
        printLink(targetLinkrole, modelObject, 0, parentChilds)


The result is as follows.

Result


jpcrp_cor:BusinessResultsOfGroupHeading
   from:  jpcrp_cor:BusinessResultsOfGroupHeading
   to:  jpcrp_cor:BusinessResultsOfGroupTable


     from:  jpcrp_cor:BusinessResultsOfGroupTable
     to:  jppfs_cor:ConsolidatedOrNonConsolidatedAxis


       from:  jppfs_cor:ConsolidatedOrNonConsolidatedAxis
       to:  jppfs_cor:ConsolidatedMember


   from:  jpcrp_cor:BusinessResultsOfGroupHeading
   to:  jpcrp_cor:BusinessResultsOfGroupLineItems


     from:  jpcrp_cor:BusinessResultsOfGroupLineItems
     to:  jpcrp_cor:RevenueIFRSSummaryOfBusinessResults


     from:  jpcrp_cor:BusinessResultsOfGroupLineItems
     to:  jpcrp030000-asr_E01766-000:OperatingProfitIFRSSummaryOfBusinessResults


     from:  jpcrp_cor:BusinessResultsOfGroupLineItems
     to:  jpcrp_cor:ProfitLossBeforeTaxIFRSSummaryOfBusinessResults


     from:  jpcrp_cor:BusinessResultsOfGroupLineItems
     to:  jpcrp_cor:ProfitLossIFRSSummaryOfBusinessResults


     from:  jpcrp_cor:BusinessResultsOfGroupLineItems
     to:  jpcrp_cor:ProfitLossAttributableToOwnersOfParentIFRSSummaryOfBusinessResults


     from:  jpcrp_cor:BusinessResultsOfGroupLineItems
     to:  jpcrp_cor:ComprehensiveIncomeIFRSSummaryOfBusinessResults


     from:  jpcrp_cor:BusinessResultsOfGroupLineItems
     to:  jpcrp_cor:ComprehensiveIncomeAttributableToOwnersOfParentIFRSSummaryOfBusinessResults


     from:  jpcrp_cor:BusinessResultsOfGroupLineItems
     to:  jpcrp030000-asr_E01766-000:TotalEquityIFRSSummaryOfBusinessResults


     from:  jpcrp_cor:BusinessResultsOfGroupLineItems
     to:  jpcrp_cor:TotalAssetsIFRSSummaryOfBusinessResults


     from:  jpcrp_cor:BusinessResultsOfGroupLineItems
     to:  jpcrp_cor:EquityToAssetRatioIFRSSummaryOfBusinessResults


     from:  jpcrp_cor:BusinessResultsOfGroupLineItems
     to:  jpcrp_cor:BasicEarningsLossPerShareIFRSSummaryOfBusinessResults


     from:  jpcrp_cor:BusinessResultsOfGroupLineItems
     to:  jpcrp_cor:DilutedEarningsLossPerShareIFRSSummaryOfBusinessResults


     from:  jpcrp_cor:BusinessResultsOfGroupLineItems
     to:  jpcrp_cor:EquityAttributableToOwnersOfParentIFRSSummaryOfBusinessResults


     from:  jpcrp_cor:BusinessResultsOfGroupLineItems
     to:  jpcrp_cor:RatioOfOwnersEquityToGrossAssetsIFRSSummaryOfBusinessResults


     from:  jpcrp_cor:BusinessResultsOfGroupLineItems
     to:  jpcrp_cor:RateOfReturnOnEquityIFRSSummaryOfBusinessResults


     from:  jpcrp_cor:BusinessResultsOfGroupLineItems
     to:  jpcrp_cor:PriceEarningsRatioIFRSSummaryOfBusinessResults


     from:  jpcrp_cor:BusinessResultsOfGroupLineItems
     to:  jpcrp_cor:CashFlowsFromUsedInOperatingActivitiesIFRSSummaryOfBusinessResults


     from:  jpcrp_cor:BusinessResultsOfGroupLineItems
     to:  jpcrp_cor:CashFlowsFromUsedInInvestingActivitiesIFRSSummaryOfBusinessResults


     from:  jpcrp_cor:BusinessResultsOfGroupLineItems
     to:  jpcrp_cor:CashFlowsFromUsedInFinancingActivitiesIFRSSummaryOfBusinessResults


     from:  jpcrp_cor:BusinessResultsOfGroupLineItems
     to:  jpcrp_cor:CashAndCashEquivalentsIFRSSummaryOfBusinessResults


     from:  jpcrp_cor:BusinessResultsOfGroupLineItems
     to:  jpcrp_cor:NumberOfEmployees


     from:  jpcrp_cor:BusinessResultsOfGroupLineItems
     to:  jpcrp_cor:AverageNumberOfTemporaryWorkers

5 Finally

In the sample program, the parent-child relationship between items was extracted, but if the elements are known, labels (Japanese and English labels are defined in EDINET) can also be extracted. The XBRL taxonomy contains a lot of useful information for displaying the data contained in the instance, so please consider using it.

6 Inquiries

For inquiries regarding this article, please contact the following e-mail address. e-mail:[email protected] (Of course, comments on qiita are also welcome)

This e-mail address will be the contact point for inquiries about the development committee of XBRL Japan, which writes the article on qiita. Therefore, we cannot answer general inquiries about the organization depending on the content, but please feel free to contact us with any technical questions, opinions, requests, advice, etc. regarding XBRL. Please note that it may take some time to respond because the committee members are volunteers.

Recommended Posts

Follow the XBRL taxonomy display link using the OSS Arrele API
Try using the Twitter API
Try using the Twitter API
Try using the PeeringDB 2.0 API
Let's automatically collect company information (XBRL data) using the EDINET API (4/10)
Let's display the map using Basemap
I tried using the checkio API
Display the result of video analysis using Cloud Video Intelligence API from Colaboratory.
Try using the Wunderlist API in Python
Try using the Kraken API in Python
Tweet using the Twitter API in Python
Create an application using the Spotify API
Play with puns using the COTOHA API
Record custom events using the Shotgun API
I tried using the BigQuery Storage API