edinet-pit: 日本株のポイント・イン・タイム財務データ
Raspberry Piのスクリーナーの記事で、バックテストが「近似PIT(ポイント・イン・タイム)」止まりだと書きました。その限界を、今回edinet-pitという形で潰しにいきました。
過去の財務データが抱える問題
yfinanceなどで過去の財務を取得すると、返ってくるのは後から修正された最新の値です。 当時の投資家が見ていた数字とは別物です。開示日でフィルタしても解決しません。数値その ものがすでに書き換わっているからです。これをバックテストに使うと、当時は知り得なかった 情報を戦略にこっそり渡すことになります。これが、効いていない戦略が効いているように 見えてしまう、よくある原因です。
開示された当時の数字をそのまま読む
EDINETは金融庁が運営する、日本版のSEC EDGARにあたる開示システムで、各年度の有価証券 報告書をXBRL形式で無料で公開しています。各報告書には当年度の数値(CurrentYear*)と、 前年度を修正した数値(Prior1Year*)の両方がタグ付けされていて、edinet-pitはCurrentYear* だけを読みます。つまり各年度の数字は、それを最初に開示した報告書から取ってくることに なります。よくあるやり方は、決算期末から一定の日数が経てば開示されると仮定することです。 edinet-pitは実際の提出日をそのまま記録するので、バックテストの各時点でその数字が 知り得たかどうかを確認できます。
使い方
import datetime as dt
import edinet_pit as ep
docs = ep.find_annual_reports(dt.date(2023, 6, 1), dt.date(2023, 6, 30), codes={"7203"})
periods = [ep.fetch_period_for_doc(d["docID"], fallback_period_end=d["period_end"])
for d in docs["7203"]]
fin, bs, cf = ep.build_frames([p for p in periods if p])
出力はyfinanceの行ラベルに合わせているので、yfinance前提で組んだパイプラインにそのまま 差し込めます。
できないこと
対応しているのは売上・利益・EPS・純資産などバックテストによく使う主要項目だけで、 ニッチな項目はまだ拾えません。有利子負債も近似値です。単一のタグが存在しないため、 借入・社債・リースの主要タグを足し合わせています。EDINETのAPI自体が2016年あたりより 前は遡れません。対象も有価証券報告書(年次)のみで、四半期報告書は含まれず、訂正報告書 もあえて対象外にしています。開示当時の、まだ修正されていない数字をそのまま残しています。
デフォルトは依存ゼロで、標準ライブラリのみで動きます(DataFrame出力を使うならpandasは 任意)。ライセンスはMITです。もともとはスクリーナーのパイプラインから切り出したもので、 数字を取り出すコード自体は独立したライブラリになる前から実戦で使われてきています。 修正後の財務やサバイバーシップバイアスがバックテストをどれだけ歪めるか、実際の数字で 見せる詳しい記事も準備中です。