edinet-lens

Japanese corporate financial disclosure, in a format you can actually use.

Six lines

Real figures, fetched and parsed at runtime. Nothing bundled or cached.

from edinet_lens import EdinetClient, parse, normalize, interest_bearing_debt

client = EdinetClient(api_key="...")
docs = client.find_annual_reports("E04430", fiscal_year_end=(3, 31), years_back=1)
facts = parse(client.fetch_csv(docs[-1].doc_id))

nt = normalize(facts)
nt.get("operating_revenue")      # Decimal('14409121000000')
nt.get("operating_profit")       # Decimal('1706221000000')
interest_bearing_debt(facts)     # Decimal('16919540000000')

sorted(nt.segments)
# ['GlobalSolutionsBusiness', 'IntegratedICTBusiness',
#  'OthersRealEstateEnergyAndOthers', 'RegionalCommunicationsBusiness']

Why this is not a weekend project

Every number below is measured, not estimated.

The CSVs are UTF-16 LE, tab-separated

Not UTF-8. Not commas. pd.read_csv(path) raises UnicodeDecodeError.

means "not applicable" — and it is not a hyphen

U+FF0D, a full-width dash. NTT's filing contains 245 of them. Read them as 0 and your screen fills with debt-free companies that are not debt-free.

The column named "consolidated / non-consolidated" does not tell you whether a figure is consolidated

In NTT's annual report, that column contains:

ValueCount
その他 ("other")1,703
個別 ("non-consolidated")382
連結 ("consolidated")0

Zero — in a document whose purpose is to report consolidated results. Filter on that column and you discard every consolidated figure in the filing, get nothing back, and conclude your parser is broken.

The truth is in the context ID. There is no ConsolidatedMember.

The same element appears seven times

OperatingRevenuesIFRS shows up once for the company, once per segment, once for eliminations, and once again. Sum them and you get 43,227,363 — exactly three times the real revenue.

You cannot search EDINET by company

Only by date. Ten years of filings for one company is 3,650 requests. edinet-lens uses the statutory filing deadline instead: 500 requests instead of 1,825 for five years.

Verified against real filings

Both accounting standards. Four different fiscal year ends.

CompanyStandardYear end Revenue (JPY)
NTTIFRSMar14,409,121,000,000
Fast RetailingIFRSAug3,400,539,000,000
ShiseidoIFRSDec969,992,000,000
AsicsJGAAPDec810,916,000,000
Oriental LandJGAAPMar704,539,000,000

Reproduce it: python tests/verify_live.py

Install

pip install edinet-lens              # core, one dependency (requests)
pip install 'edinet-lens[pandas]'    # + DataFrame output

Python 3.10+. MIT licence. Free.

What this is not

This software does not provide investment advice. 本ソフトウェアは投資助言を行いません。売買推奨・目標株価・銘柄選定を出力しません。

It does not generate signals, scores, rankings, valuations, price targets, or recommendations of any kind.

It reads public filings and returns the numbers that are in them. What you conclude from those numbers is entirely your own business.