開発mdx-playground

キオクシア決算サマリー記事公開と beat-monitoring/285A の途中対応

2026年6月25日。マイクロン FY26 Q3 のサマリー記事を出したあとで、ユーザーから「同じ形式でキオクシアもまとめてほしい」と依頼が来た。 記事公開までは予定通り進んだが、関連ページ /beat-monitoring/285A にデータを反映するところで「そもそもアナリストコンセンサスが取れていない」という前提崩れにぶつかり、途中で日付が変わった。


やったこと

1. キオクシア FY25 Q4 決算サマリー記事を公開

公式 IR の決算説明資料 PDF と決算短信 PDF を取りに行き、24Q 分のセグメント PL を引き直した。

  • 公開記事: /kioxia-fy25-q4-summary-japanese
  • 図1(売上 vs 売上原価、粗利率折れ線): apps/web/public/images/kioxia-fy25-q4-summary-japanese/figure-01-revenue-cogs-gm.svg
  • マイクロン記事の figure-11 と同形式(積み上げバー + 粗利率折れ線)に揃えて、IFRS データで作り直した

Q4 単独で売上 ¥1兆29億 に到達して、前四半期から +¥4,592億 ほぼ倍増。 売上原価は ¥2,716億 → ¥3,599億 までしか伸びておらず、増分のほぼ全部が粗利に直行している。 マイクロンの Q3 で観測した「売上は伸びる、COGS は据え置き」がそのまま再現されていた。

::: callout ちなみに音声入力で「キオクシア」を喋ったら「記憶視野」と書き起こされていて、最初に読んだとき何のことかしばらく分からなかった。Kioxia の語源は「記憶 + axia(価値)」なので、ある意味当たっている。 :::

2. CEO 発言と市場反応の補完

  • 公式 IR ページから決算説明資料 PDF と社長発言を取得
  • ITmedia は「太田裕雄 社長」と書いていたが、決算短信の代表者欄は 早坂 伸夫 代表取締役社長 CEO で確定。脚注で両説併記
  • x-search で @hibitti @kamiyaf14 @mofmof_investor @apaes53 @kioxiaman 等の市場反応を拾って、記事末尾の「市場の反応」セクションに反映

3. 24四半期分の財務 TS データを整備

IR データブック Excel(00.xlsx)から Q1 FY2020 〜 Q4 FY2025 の 24Q 分 + Q1 FY2026 会社ガイドを構造化。

新規ファイル:

  • apps/web/app/data/memory-makers/kioxiaFinancialsTypes.ts — 型定義
  • apps/web/app/data/memory-makers/kioxiaQuarterlyFinancials.ts — IFRS PL / Non-GAAP PL / BS / CF / アプリ別売上を四半期ごとに保持
  • apps/web/tests/kioxia-financials.test.ts — 7件パス

makers.ts / registry.ts / types.ts / index.tskioxia(subcategory='nand')を登録して、既存の [maker].vue レンダラに kioxiaQuarterlyFinancialsCompat で渡せる形にした。 Excel → TS の自動生成スクリプトはセッション scratchpad に置いて、IR データブック更新時はそこを叩けば再生成できるようにしてある。


ここから先が「明日に持ち越し」になった

発端: /beat-monitoring/285A にデータが反映されていない

記事を公開したあと、ユーザーから「IR ページにガイダンスも実績も載っているのに、なぜ /beat-monitoring/285A には何も入っていないのか」と指摘が入った。 データ反映するだけのつもりで 285A.json を開いたら、想定外の構造が見えた。

{
  "ticker": "285A",
  "quarters": [
    {
      "quarter": "Q3 FY25",
      "actual": { "revenue": 428.5, "eps": ... },
      // consensus が無い
      "guidance": { "revenue": { "company": 445.0 }, ... }
    }
    // ...
  ]
}

ほかの30銘柄(MU / NVDA / GOOGL …)は consensus(Koyfin / SEC EDGAR 由来)と actual を比較する作りになっている。 キオクシアだけ アナリストコンセンサスが空 で、会社ガイダンスしか入っていなかった。 そもそも日本企業のキオクシアに、米国系金融データプロバイダの consensus は十分に揃っていない。

方針転換: Kioxia だけ「会社の前Qガイダンス vs 実績」に切り替える

「アナリスト予想に対するビート率」というフレーム自体が、この銘柄では成立していない。 代わりに「前Q時点で会社が出した自分のガイダンスに対して、実績がどれだけ上振れたか」を見る方が、キオクシアの場合は意味がある。

ここで仕様判断:

  • データ側に consensusSource フィールドを追加する(型: 'analyst-consensus' | 'company-prior-guidance'
  • 285A.json だけ "consensusSource": "company-prior-guidance" を立てる
  • レンダラ (BeatExpectationsChart / TripleBeatTable / [ticker].vue) は consensusSource を見て、ラベルと比較対象を切り替える
    • ❌ 「アナリスト予想(コンセンサス)」 → ⭕ 「前Q時点の会社ガイダンス」
    • ❌ 「売上ビート率」 → ⭕ 「売上 ガイド達成率(前Qガイド比)」
  • ビート率の計算式も (actual - prior_guide) / prior_guide に変える

実装はだいたい入った、けど

ここまでで:

  • types.tsConsensusSource 型と TripleBeatData.consensusSource? を追加
  • 285A.json に consensusSource 追加
  • BeatExpectationsChart.vue のメインチャート est バーを quarters[i-1].guidance.X.company から引くように変更
  • 凡例とチャート見出しを動的化
  • TripleBeatTable.vue の行ラベルと値も Kioxia 限定で切替
  • vue-tsc --noEmit パス、ユニットテスト 7件パス、既存 36件もパス

ここで時計を見たら深夜2時で、ブラウザでの目視確認に入る前に手が止まった。 ユーザーが chrome-devtools MCP を一度 reject したのもあって、明日の朝にログイン済み Chrome を繋ぎ直してから確認することにした。

計算上の「埋まり方」だけは机上で確認した

実装の正しさだけはコード上で詰めた。実際に DOM に出る数字はこうなるはず:

四半期rev 実績前Qガイド達成率
Q3 FY254,285億— (最古行)
Q4 FY253,471億— (前Qガイド無)
Q1 FY263,428億— (前Qガイド無)
Q2 FY264,483億4,450億+0.7%
Q3 FY265,436億5,250億+3.5%
Q4 FY2610,029億— (Q3 は FY guide のみ)

最後の Q4 FY26 が「会社が次Qガイドを出さず、通期ガイドだけ出した」パターンで空欄になる。 これを 通期ガイド - (Q1+Q2+Q3 実績) で implied guide として埋めるかは、明日の判断対象に積んだ。


学び

「ベンチマーク」を1個の指標に固定すると、それが取れない銘柄が落ちる

これまで /beat-monitoring/* は「アナリストコンセンサスに対する実績のビート率」一本で来ていた。 日本企業を入れた瞬間、その前提が崩れた。 「比較対象は何か」をデータ側で宣言させて、レンダラが切り替える という設計にしておけば、別ベンチマーク(セルサイドアナリスト / 自社前Qガイド / バイサイドホエール期待値 など)の銘柄が混在しても破綻しない。

今日はとりあえず2種類(analyst-consensus / company-prior-guidance)に閉じたが、将来 NVDA の「whisper number」とか別のソースを足すことになっても、enum を増やすだけで済む形にできた。

「比較対象が無い」は「データが無い」と区別する

ビート率カラムが空のとき、「データが無いから空」なのか「比較対象がそもそも無いから空」なのかは、UI 上で区別できる必要がある。 今日の実装では前者は のまま、後者は明示的に (前Qガイド無) を出すようにした。 ユーザー側で「いつデータが入るか」と「永久に入らないか」を見分けられるのが、ファクトベースの UI として正しい振る舞い。


明日やること(持ち越し)

進捗の詳細は memo/2026-06-25/kioxia-data-and-beat-monitoring-progress.md に積んである。最優先は以下。

  • chrome-devtools MCP をログイン済み Chrome に繋いで、/beat-monitoring/285A/memory-makers/kioxia/kioxia-fy25-q4-summary-japanese の3ページをスクショ取得して目視確認する
  • Q4 FY26 の implied guide 補完(通期ガイド − Q1+Q2+Q3 累計)を BeatExpectationsChart.vue の priorRevGuide / priorEpsGuide ヘルパーに追加するかどうかを決める
  • 公開記事 /kioxia-fy25-q4-summary-japanese から /beat-monitoring/285A/memory-makers/kioxia への導線を callout で2本追加する
  • /code-review を1パス回して致命的指摘だけ拾う(CLAUDE.md の post-implementation-checklist Step 5)
  • 未コミットの差分を3つの粒度に分けて commit する(公開記事 / memory-makers データ / beat-monitoring 拡張)

関連リンク