開発financial-data

なにをやったか

/earnings-dynamics/MU のページに、アナリスト予想の先4Q合計(NTM, Next Twelve Months)をチャート右上にバッジ表示する仕組みを追加した。 同じ日に、Koyfin から日次で取り込んでいるコンセンサス推定が MU 以外で更新されていない疑惑を調べて、取得スコープの不備を直した。

両方とも apps/web/app/data/earningsDynamics/*.ts 配下のデータと、チャートコンポーネントに関わる作業。

きっかけ

朝、ページを開いて気づいたのが2つ。

  1. 集計欄が欲しい: focusQuarter から先4Qの売上・EPS をチャート上で見られるが、「合計いくらに見直されているか」が一目で分からない。決算までにコンセンサスがどれだけ動いたかは、4Qを足した数字で見たい。
  2. 数字が動かない: MU の予想は毎日少しずつ削れているのに、NVDA や SNDK は数日前のスナップショットからピクリとも動いていない。「日次で取り込むパイプライン」のはずなのに、これはおかしい。

順に潰した。

NTM バッジの実装

EarningsChart 側で、focusQuarter から +3Q 先まで(合計4四半期分)の estimate を sum するロジックを足した。 表示は売上と EPS 両方。

  • 売上: $174.6B 程度の絶対値
  • EPS: 4Q合計 EPS

ユーザーからの当初の希望は EPS だけだったが、売上も並べてみると「売上はあまり動かないが、EPS が大きく見直されている」みたいな構造が一目で読めるので、両方出すことにした。

加えて、初回スナップショット(snapshot_date が最古の日)からの差分もバッジに添えた。

NTM (4Q合計, focus + 3先)
売上: $174.6B  (+12.66B vs 2026-05-19)
EPS : ...

最初は asOf(最新日)と窓開始の差分を出していたが、両者が同点になるケースが多く revision がゼロに見えてしまった。基準日を「該当銘柄で存在する最古のスナップショット日」に切り替えてようやく動きが見える形になった。

実装の要は2つ:

  • focusQuarter のラベル(例: Q2 FY27)から +3Q 先までを nextQuarterFromLabel で順に拾い、estimate 配列を引き当てる
  • NTM 計算は、先4Q全てに estimate が揃っているときだけ表示する(欠損があれば素直に出さない)

取得スコープの不備を直した

NTM の確認をしている途中で、別の問題に気づいた。 NVDA や SNDK の estimates 配列の最新 snapshot 日が数日前で止まっている。MU は 6/23 まで毎日入っている。

ここで一度立ち止まって、取り込みスクリプトの実装を読み直した。 原因はシンプルで、Koyfin から日次バッチで取得するときの対象銘柄リストが MU 系に偏っていて、他の銘柄を回せていなかった。スクリプト側は「日次で全銘柄を取り込めば自然に積み上がる」設計のはずだったが、運用パスのどこかで MU 以外が落ちる経路になっていた。

検証は次の手順:

  1. Chrome の Koyfin タブを開き直して、KID マップから全銘柄分を取得
  2. 取得した JSON をローカルで生成スクリプトに食わせて、各銘柄の snapshot_date 末尾が 2026-06-23 になるか確認
  3. ならない銘柄について、スクリプト側のスコープ条件を直す

ハマったのは .env の置き場所。apps/web/.env.local には Turso の URL/TOKEN が入っていなくて、turso-replicas/.env のほうに本物があった。 Node 22 の --env-file= で turso-replicas 側を直接読ませて実行したら、全銘柄が一発で 6/23 まで反映された。

修正後の TS データを apps/web/app/data/earningsDynamics/*.ts に再生成して、変更をコミットして終了。

学び・気づき

  • 「日次取り込みで自然に積み上がる」設計は、運用時にスコープが欠けていないか目視で確かめないと、サイレントに止まる。MU だけ動いていたのは、たまたま MU が手動確認の対象だったから。
  • NTM バッジの基準日選びは、最新と窓開始が同点になりやすいので、「最古スナップショット起点」のほうが体感に合う。決算前にコンセンサスがどれだけ削れた/積まれたかを読むのが目的なら、これで十分。
  • .env の場所は地味に毎回詰まるので、make-diary のワークフロー側に「TS 再生成ステップは turso-replicas の .env を --env-file で読む」と明文化しておいた。次セッションの自分が同じ場所で詰まらないように。

残課題

  • スクショ撮影と SVG 図解は未対応。NTM バッジは見た目調整の余地あり(バッジの位置・色・revision の正負で色変えるか等)。
  • 取り込みスクリプトの「対象銘柄リストが欠ける」経路は応急処置のみ。根本的にはマニフェスト駆動で「全銘柄を必ず回す」CI に直すべき。今日はそこまでやらず、運用ワークフローに「make-diary 末尾で TS 再生成 + 差分コミット」を入れて、毎朝の検出に振った。