キオクシア(285A) beat-monitoring の EPS フィールドが営業利益で埋まっていた話
/beat-monitoring/285A のページを眺めていたら、コンセンサスバーがほとんど n/a になっていて寂しい絵面だった。キオクシア(285A) は日本企業なので、米国・韓国勢のように分析者コンセンサスが秒で揃わない。代わりに「会社が前Qに出したガイダンス」と「実績」を並べれば、ビート/ミスを同じ尺度で見られるはず。今日はその尺度をきちんと埋め直す作業をやった。
途中で、チャートに見覚えのない 701 という数字がドンと立っていることに気づいた。自分が入れた数値ではない。データ設計のミスマッチを掘り当てるところまで連れていかれて、結局その方が今日の本丸になった。
まずモードの確認 ― キオクシアは「会社の前Qガイダンス vs 実績」
apps/web/app/data/tripleBeat/285A.json の consensusSource は既に company-prior-guidance になっていて、画面側の BeatExpectationsChart.vue / TripleBeatTable.vue も、quarters[i].revenue.actual を quarters[i-1].guidance.revenue.company と比較する実装になっていた。ここは触らなくていい。
足りないのは中身、つまり過去のガイダンス値そのものだった。X-search/FactSet 経由でかき集めた歯抜けの状態で止まっていて、決算説明会資料を見に行けばもっと埋まる、という素直な話。
キオクシア IR から決算説明会資料 PDF を取りに行く
まずは直近の Q3 FY26 決算説明会資料 (2026/2/12 開示) を取得しに IR ページを叩いた。HTML が動的レンダリングで PDF URL が直接見えない罠を1回踏んでから raw HTML 経由で URL を引き当てた。
p.16 に「2026年3月期 第4四半期ガイダンス」スライドがあり、会社が直接出しているレンジが揃っていた:
- 売上: 8,450 〜 9,350 億円(中央値 8,900 億円)
- Non-GAAP 営業利益: 1,150 〜 1,650 億円(中央値 1,400 億円)
- Non-GAAP 1株EPS: 569 〜 679 円(中央値 624 円)
レンジで開示されているガイダンスは、中央値で取って guidance.revenue.company / guidance.eps.company に入れる方針で進めた。
ここまでは順調だった。
ブラウザを開き直して、いきなり 701 が立っていた
更新した JSON を読み込ませた状態で /beat-monitoring/285A を開き直すと、EPS チャートの Q4 FY26 のコンセンサスバーに 701 が立っていた。自分が入れたのは中央値 624 円のはずで、701 という数字に心当たりがない。
最初は「ガイドレンジの上端を拾っているのか、計算式のどこかでズレているのか」と疑ったが、コードを追ってみると、impliedQ4Guide フォールバック計算という別経路が動いていた。eps フィールドの数値を一度パースし直して別の係数を掛けて出していて、その結果が 701 だった。
なぜそんなフォールバックがあるのか、と parseCurrencyToNumber の挙動と一緒に追っていって、ようやく根本原因に行き当たった。
根本原因: EPS フィールドに「営業利益(億円)」が入っていた
キオクシアの 285A.json は、eps フィールドに 1株EPS ではなく、Non-GAAP 営業利益(億円) を入れる設計になっていた。tableNotes には「韓国勢と同じ方式」と書いてあったが、実際には韓国勢は 1株EPS(ウォン) で揃っており、キオクシアだけが営業利益のスケールで埋まっていた。
つまり同じ eps というフィールド名で、
- 米国勢: 1株EPS (USD)
- 韓国勢: 1株EPS (KRW)
- キオクシア: 営業利益 (億円)
という単位混在が起きていて、チャート側がスケールを揃えようと頑張った末に、見覚えのない 701 が立つに至った、という構図だった。フォールバック計算は、この単位ズレを実装側で吸収しようとした副作用だったらしい。
eps という名前のフィールドに営業利益を詰めるな、というだけの話ではあるが、tableNotes のコメントが事実と食い違ったまま放置されていたのが致命傷で、後から触る自分自身(あるいは未来の Claude Code)を混乱させていた。
案A vs 案B ― キオクシアの数値を 1株EPS に揃える
修正方針は2択あった。
- 案A: キオクシアの
epsフィールドを 1株EPS(円) に統一する。memory-makers側にkioxiaQuarterlyFinancials.tsが既にあり、1株EPS の実績はそこから拾える - 案B: チャート側を「キオクシアだけは営業利益スケール」として個別分岐させる
案B は実装が分散して複雑になるし、何より「同名フィールドで単位が違う」という構造の歪みを温存することになる。tableNotes の嘘も解消できない。
案A で進めた。kioxiaQuarterlyFinancials.ts から各 Q の 1株EPS 実績を拾い、285A.json の quarters[*].eps.actual を全件 1株EPS(円) に書き換える。guidance.eps.company も同じスケールに合わせる。
ガイダンス値の換算 ― 既存の数字が間違っていた件
ガイダンス側の 1株EPS を埋めるため、Q1 FY26 (2025/8/8) と Q2 FY26 (2025/11/?) の決算説明会資料 PDF も追加で取りに行った。
ハマったのは、Q1 FY26 (2025/8/8) のガイダンスには Non-GAAP 1株EPS のレンジが開示されていなかったこと(売上・営業利益・当期純利益まで)。なので Q1 FY26 の guidance.eps は素直に null に倒すしかない。
Q2 FY26 の方は PDF の p.12 に Q3 FY26 ガイダンスが載っていて:
- 売上: 5,000 〜 5,500(中央値 5,250 ← 既存と一致)
- Non-GAAP 営業利益: 1,000 〜 1,400(中央値 1,200 ← 既存値 1,250 は誤り)
つまり既存の 285A.json は、ガイダンスの営業利益中央値の段階で既に 50億円ズレていた。EPS フィールドに営業利益を入れる設計だったので、当然 1株EPS への換算もズレていく。換算ミスをそのまま放置して案B で帳尻だけ合わせていたら、構造の歪みも嘘も両方残ったまま月次で増えていたところだった。
差分の核心 ― JSON の数値とテストの前提値
JSON 側は EPS フィールドを全件 1株EPS(円) に揃えるだけ。サンプルとしては:
"epsLabel": "Non-GAAP 1株EPS(円)",
"quarters": [
{
"quarter": "Q2 FY26",
- "eps": { "actual": "¥872億" },
+ "eps": { "actual": "¥77.22" },
"guidance": {
- "eps": { "company": "¥1,250億" }
+ "eps": { "company": "¥138.96" }
}
}
]
(実際の対応は全 Q 分。guidance.eps.company は会社の前Qガイドの 1株EPS 中央値、actual は 実績の 1株EPS。)
テスト側 (apps/web/tests/kioxia-consensus-source.test.ts) は、前提値を 1株EPS スケールに書き換えるだけで通る。
- it('Q3 FY26 EPS のコンセンサスは Q2 FY26 の eps ガイド (¥1,250億)', () => {
+ it('Q3 FY26 EPS のコンセンサスは Q2 FY26 の 1株EPS ガイド (¥138.96)', () => {
const guide = parseCurrencyToNumber(q2.guidance!.eps!.company)
const actual = parseCurrencyToNumber(q3.eps.actual)
- expect(guide).toBe(1.250e11)
- expect(actual).toBe(1.447e11)
+ expect(guide).toBe(138.96)
+ expect(actual).toBe(165.28)
})
冒頭にも一文コメントを追加した。「2026-06-29: EPS フィールドを『営業利益(億円)』→『Non-GAAP 1株EPS(円)』に統一。米国勢($/株)・韓国勢(W/株) と同じスケールに揃えた」と。tableNotes の嘘もここで上書きしておかないと、同じ罠を別の誰かが踏みなおす。
pnpm test:run apps/web/tests/kioxia-consensus-source.test.ts で 9 tests pass。
今日の教訓 ― フィールド名と中身の不一致は数か月単位で人を惑わせる
epsという名前のフィールドに営業利益を詰めるな。事故は確定で起きる- データ設計のミスマッチは、画面の違和感(見覚えのない 701)として出てくる。チャート側のロジックを疑う前に、データの単位を一回疑う
tableNotesに「韓国勢と同じ方式」と書いてあっても、コメントは嘘をつく。実データを並べて確かめる- 案A(構造を正す)と案B(個別分岐で吸収する)の選択は、長期で見るとほぼ案A 一択。分岐は数か月後の自分を確実に殺しに来る
- 日本企業の決算ガイダンスを取り込むときは、IR の PDF を直接見にいくのが結局いちばん早い。X-search 経由のサマリーは抜けが多い
beat-monitoring 全 30 銘柄のうち、日本企業はキオクシアだけなので、この単位混在は今のところ他の銘柄には波及していない。今後 日本銘柄を追加するときは、最初から 1株EPS(円) スケールで埋めて、epsLabel で単位を明示することにする。