NVIDIA EPS予測 Phase 8: 計算詳細テーブル追加
概要
ユーザーが設定したパラメータが最終的な株価予測にどのように反映されるかを、Excelのセルのように各計算ステップを可視化するテーブルを追加する。
完了ステータス
Phase 8-1: 事前準備
[x] QoQオーバーライドテーブルを横向きに変更済み
[x] QoQオーバーライドの表示範囲をFY28まで(4Q'26〜4Q'28)に制限済み
[x] 予測期間をFY30まで(FY31削除)に変更済み
[x] FY29〜FY30は内部計算で一律10.7% QoQを使用(UI非表示)
Phase 8-2: 基本テーブル作成
[x] CalculationDetailTable.vue新規作成
[x] index.tsにエクスポート追加
[x] nvidia-eps-forecast.vueに統合
[x] 累積計算行の追加(年度別累計売上、累計純利益、累計株式数)
[x] 動作確認
Phase 8-3: QoQ継承ロジック修正
[x] 4Q'28のQoQ値がFY29以降に継承されるように修正
[x] useNvidiaForecast.tsのgetQoQRate()関数修正
[x] CalculationDetailTable.vueのgetQoQRate()関数修正
[x] 1Q'27〜3Q'28のデフォルトQoQを10%に変更
Phase 8-4: PER/P/S計算タブ追加
[x] タブUI追加(PERベース/P/Sベース切り替え)
[x] PERベース計算(現在の実装)
[x] P/Sベース計算(Forward売上 × P/S倍率 = 時価総額)
[x] $20T目標への到達状況表示(P/Sタブ)
[x] P/S倍率スライダー追加(SensitivityPanel)
[x] 動作確認
Phase 8-5: チャート修正
[x] 年間売上チャートのY軸ラベル修正($1B → $1T)
[x] 動作確認
Phase 8-6: P/S (LTM) 推移チャート追加
[x] koyfin.dbからNVDA P/Sデータ取得(nvda-ps-data.ts作成)
[x] P/S推移チャートコンポーネント作成(PSRatioChart.vue)
[x] 実績P/S(FY2016A〜FY2025A)表示
[x] 修正版P/S(計算詳細テーブルから算出)表示
[x] 25x基準線の追加(psMultipleスライダー連動)
[x] nvidia-eps-forecast.vueに統合
[x] 動作確認
現在の状態
完了済み
- QoQオーバーライドテーブルを横向きに変更済み
- QoQオーバーライドの表示範囲をFY28まで(4Q'26〜4Q'28)に制限済み
- 予測期間をFY30まで(FY31削除)に変更済み
- FY29〜FY30は内部計算で一律10.7% QoQを使用(UI非表示)
- CalculationDetailTable.vue作成済み
- QoQ継承ロジック修正済み
関連ファイル
| ファイル | 役割 |
|---|---|
useNvidiaForecast.ts | ビジネスロジック(composable) |
SensitivityPanel.vue | 感応度パラメータ入力UI |
nvidia-eps-forecast.vue | メインページ |
実装タスク
8-2. CalculationDetailTable.vueコンポーネント新規作成
ファイル: apps/web/app/components/financial-quiz/nvidia-eps-forecast/CalculationDetailTable.vue
表示内容(Excelライクなテーブル):
| 項目 | 計算式 | 備考 |
|---|---|---|
| 四半期 | - | 1Q'26, 2Q'26, ... 4Q'30 |
| 修正版売上 | 前期売上 × (1 + QoQ%) | 四半期ごとのQoQ適用結果 |
| 修正版純利益 | 売上 × 純利益率% | パラメータ連動 |
| 希釈後株式数 | 前年株式数 × (1 + 希釈率%) | 年度ごとに増加 |
| EPS | 純利益 ÷ 株式数 | - |
| 株価 | EPS × PER | パラメータ連動 |
Props:
interface Props {
quarterlyData: QuarterlyForecastItem[]
netProfitMargin: number // 純利益率パラメータ
perMultiple: number // PER倍率パラメータ
dilutionRate: number // 年間希釈率パラメータ
baseShares: number // 基準株式数 (24800M)
}
UI要件:
- 横スクロール可能(四半期が多いため)
- 左端の項目名列は固定(sticky)
- 数値は適切にフォーマット(売上:
XXB, EPS:X.XX, 株価: $XXX) - 実績期間と予測期間で背景色を分ける
8-3. メインページに統合
nvidia-eps-forecast.vueの適切な位置にコンポーネントを追加:
<CalculationDetailTable
:quarterlyData="quarterlyForecastData"
:netProfitMargin="netProfitMargin"
:perMultiple="perMultiple"
:dilutionRate="dilutionRate"
:baseShares="24800"
/>
8-4. 動作確認
Chrome DevTools MCPで以下を確認:
- テーブルが正しく表示される
- スライダー変更時にテーブルが更新される
- 横スクロールが正常に動作する
- モバイルでも見やすい
計算ロジック詳細
現在の計算方法(PERベース - useNvidiaForecast.tsより)
1. 修正版売上予測:
- 四半期ごとにQoQ成長率を適用
- QoQ率 = quarterlyQoQOverrides から取得(FY28まで)
- FY29以降は 4Q'28のQoQ値を継承(デフォルト10%)
2. 修正版純利益:
- 修正版売上 × 純利益率パラメータ (netProfitMargin / 100)
3. 希釈後株式数:
- baseShares × (1 + dilutionRate/100) ^ yearsFromBase
- yearsFromBase = 対象年度 - 2025
4. EPS:
- 修正版純利益 ÷ 希釈後株式数
5. 株価(PERベース):
- Forward EPS × PER倍率パラメータ (perMultiple)
- Forward EPS = 4四半期先のEPS
P/Sベース計算方法(Phase 8-4で追加)
I/O Fund分析ドキュメント(nvidia_20t_analysis_complete.md)との整合性のために追加。
1. Forward売上:
- 4四半期先の売上を合計(Forward 4Q Revenue)
- 例: 現在1Q'26なら、2Q'26+3Q'26+4Q'26+1Q'27の合計
2. 時価総額(P/Sベース):
- Forward売上 × P/S倍率(デフォルト25x)
- 例: Forward売上 $400B × 25 = 時価総額 $10T
3. 株価(P/Sベース):
- 時価総額 ÷ 希釈後株式数
- 例: $10T ÷ 25.4B株 = $394
4. $20T目標到達状況:
- 必要売上: $800B($20T ÷ 25x P/S)
- 現在のForward売上との差額
- 必要成長率の逆算
2つの計算方法の比較
| 項目 | PERベース | P/Sベース |
|---|---|---|
| 主要指標 | EPS(一株当たり利益) | 売上高 |
| 倍率 | PER 25x | P/S 25x |
| 計算式 | 株価 = EPS × PER | 時価総額 = 売上 × P/S |
| 強み | 利益重視、純利益率の影響大 | 売上成長重視、赤字企業にも適用可 |
| 参照 | 一般的な株式評価 | I/O Fund $20T分析 |
P/S倍率に関する注記(LTM vs NTM)
重要: P/S 25xはLTM(過去12ヶ月)ベースの前提。
NVIDIAの過去P/S倍率推移:
| 指標 | 過去レンジ | 直近値 | 25xの評価 |
|---|---|---|---|
| P/S (LTM) | 3.0x〜27.3x | 23.5x | 妥当な範囲内 |
| P/S (NTM) | 2.9x〜20.9x | 14.8x | かなり楽観的(過去最高21x未満) |
I/O Fund $20T分析の前提:
8% QoQ成長(≒36% CAGR)を1Q'27以降適用
↓
FY30末で年間売上 ≒ $800B
↓
LTM P/S 25x × $800B = $20T時価総額
NTMベースで25xを使うと、過去に一度も達したことがない水準となるため、 P/Sベースの計算ではLTM(実績売上)を前提としていることに留意。
パラメータのデフォルト値
| パラメータ | デフォルト | 範囲 |
|---|---|---|
| 純利益率 | 55% | 40-70% |
| PER倍率 | 25x | 15-45x |
| P/S倍率 | 25x | 15-45x(新規追加) |
| 年間希釈率 | 2.5% | 0-5% |
| 基準株式数 | 24,800M | 固定 |
| デフォルトQoQ | 10% | 1Q'27〜3Q'28用 |
| 拡張期間QoQ | 4Q'28の値を継承 | FY29以降用 |
Phase 8-4: PER/P/S計算タブ追加 - 実装計画
概要
CalculationDetailTable.vueにタブ機能を追加し、2つの計算方法を切り替え可能にする:
- PERベース(現在の実装): Forward EPS × PER = 株価
- P/Sベース(新規追加): Forward売上 × P/S = 時価総額 → 株価
UI設計
┌─────────────────────────────────────────────────────────────┐
│ 計算詳細 │
├─────────────────────────────────────────────────────────────┤
│ [PER × Forward EPS] [P/S × Forward売上] ← タブ切り替え │
├─────────────────────────────────────────────────────────────┤
│ │
│ 計算方法: Forward EPS ($X.XX) × PER (25x) = 株価 ($XXX) │
│ │
│ ┌──────────┬─────────┬─────────┬─────────┬───┐ │
│ │ 項目 │ 1Q'26 │ 2Q'26 │ 3Q'26 │...│ │
│ ├──────────┼─────────┼─────────┼─────────┼───┤ │
│ │ QoQ成長率│ 14.9% │ 8.2% │ 5.1% │ │ │
│ │ 売上($B) │ 45.2 │ 48.9 │ 51.4 │ │ │
│ │ ... │ │ │ │ │ │
│ └──────────┴─────────┴─────────┴─────────┴───┘ │
│ │
│ ※ P/Sタブ時は$20T目標への進捗バーを表示 │
└─────────────────────────────────────────────────────────────┘
Props追加
interface Props {
quarterlyData: QuarterlyForecastItem[]
netProfitMargin: number
perMultiple: number
psMultiple: number // 新規追加: P/S倍率
dilutionRate: number
baseShares: number
}
コード実装
1. タブ状態管理
// タブタイプ
type CalculationMethod = 'per' | 'ps'
// 現在のタブ
const activeTab = ref<CalculationMethod>('per')
2. P/S計算ロジック
// Forward売上(4四半期先の合計)
const forwardRevenue = computed(() => {
const currentQuarterIndex = 0 // 現在の四半期インデックス
const forwardQuarters = props.quarterlyData.slice(
currentQuarterIndex + 1,
currentQuarterIndex + 5
)
return forwardQuarters.reduce((sum, q) => sum + q.modifiedRevenue, 0)
})
// P/S方式での時価総額(百万ドル単位)
const marketCapPS = computed(() => {
return forwardRevenue.value * props.psMultiple
})
// P/S方式での株価
const stockPricePS = computed(() => {
const shares = getDilutedShares(/* 対象年度 */)
return marketCapPS.value / shares
})
// $20T目標への進捗
const targetMarketCap = 20_000_000 // $20T = 20,000,000百万ドル
const progressTo20T = computed(() => {
return (marketCapPS.value / targetMarketCap) * 100
})
3. テーブル表示切り替え
<template>
<!-- タブボタン -->
<div class="tabs">
<button
:class="{ active: activeTab === 'per' }"
@click="activeTab = 'per'"
>
PER × Forward EPS
</button>
<button
:class="{ active: activeTab === 'ps' }"
@click="activeTab = 'ps'"
>
P/S × Forward売上
</button>
</div>
<!-- 計算方法の説明 -->
<div v-if="activeTab === 'per'" class="method-description">
計算方法: Forward EPS (${{ forwardEps.toFixed(2) }}) × PER ({{ perMultiple }}x) = 株価 (${{ stockPricePER.toFixed(0) }})
</div>
<div v-else class="method-description">
計算方法: Forward売上 (${{ (forwardRevenue / 1000).toFixed(0) }}B) × P/S ({{ psMultiple }}x) = 時価総額 (${{ (marketCapPS / 1_000_000).toFixed(1) }}T)
<div class="target-progress">
$20T目標: {{ progressTo20T.toFixed(1) }}% 到達
<progress :value="progressTo20T" max="100" />
</div>
</div>
<!-- テーブル本体(共通) -->
<!-- ... 既存のテーブル ... -->
<!-- 結果行(タブによって表示内容切り替え) -->
<tr v-if="activeTab === 'per'">
<td class="row-label">Forward EPS ($)</td>
<!-- ... PERベースの結果 ... -->
</tr>
<tr v-if="activeTab === 'ps'">
<td class="row-label">Forward売上 ($B)</td>
<!-- ... P/Sベースの結果 ... -->
</tr>
</template>
nvidia-eps-forecast.vue変更
P/S倍率パラメータの追加が必要:
// useNvidiaForecast.ts に追加
const psMultiple = ref(25) // P/S倍率、デフォルト25x
// nvidia-eps-forecast.vue でのprops渡し
<CalculationDetailTable
:quarterlyData="quarterlyForecastData"
:netProfitMargin="netProfitMargin"
:perMultiple="perMultiple"
:psMultiple="psMultiple" // 新規追加
:dilutionRate="dilutionRate"
:baseShares="24800"
/>
スタイル
.tabs {
display: flex;
gap: 0.5rem;
margin-bottom: 1rem;
}
.tabs button {
padding: 0.5rem 1rem;
border: 1px solid #ddd;
background: #f5f5f5;
cursor: pointer;
border-radius: 4px 4px 0 0;
}
.tabs button.active {
background: white;
border-bottom-color: white;
font-weight: bold;
}
.method-description {
background: #f0f8ff;
padding: 0.75rem;
border-radius: 4px;
margin-bottom: 1rem;
font-size: 0.9rem;
}
.target-progress {
margin-top: 0.5rem;
}
.target-progress progress {
width: 100%;
height: 8px;
}
Phase 8-5: チャート修正 - 実装計画
問題
年間売上チャートのY軸ラベルが「1B」と表示されているが、実際の値は100B〜800Bなので「1T」表示が適切。
修正箇所
DualSeriesChart.vue のY軸ラベルフォーマット処理
現在のコード(推定)
// Y軸ラベルのフォーマット
const formatYAxisLabel = (value: number) => {
if (isEps) {
return `$${value.toFixed(2)}`
} else {
return `$${value}B` // ← ここが問題
}
}
修正後
const formatYAxisLabel = (value: number) => {
if (isEps) {
return `$${value.toFixed(2)}`
} else {
// 売上高: 1000B以上は$XT表示、それ以下は$XB表示
if (value >= 1000) {
return `$${(value / 1000).toFixed(1)}T`
}
return `$${value}B`
}
}
確認ポイント
- 年間売上チャートのY軸が
0.1T〜0.8T程度で表示される - 四半期売上チャートは
30B〜200B程度なので$XB表示のまま - チャートのデータポイントラベルも同様に修正が必要か確認
Phase 8-6: P/S (LTM) 推移チャート追加 - 実装計画
目的
P/S 25xの妥当性を過去の推移から視覚的に確認できるようにする。 ユーザーがQoQ成長率を変更すると、将来のP/Sがどう変化するかをリアルタイムで確認可能。
データソース
koyfin.db から取得可能なNVDA P/S (LTM) データ:
SELECT p.period_label, e.metric_value, p.is_actual
FROM eac_annual e
JOIN eac_periods p ON e.period_id = p.id
JOIN companies c ON e.company_id = c.id
WHERE c.ticker = 'NVDA'
AND e.metric_name = 'Price-/-Sales'
ORDER BY p.fiscal_year;
結果:
| 年度 | P/S (LTM) | 区分 |
|---|---|---|
| FY 2016A | 3.1x | 実績 |
| FY 2017A | 8.5x | 実績 |
| FY 2018A | 15.3x | 実績 |
| FY 2019A | 7.5x | 実績 |
| FY 2020A | 13.3x | 実績 |
| FY 2021A | 19.3x | 実績 |
| FY 2022A | 22.7x | 実績 |
| FY 2023A | 17.8x | 実績 |
| FY 2024A | 24.9x | 実績 |
| FY 2025A | 22.5x | 実績 |
| FY 2026E | 20.0x | 予測 |
| FY 2027E | 13.5x | 予測 |
| FY 2028E | 10.5x | 予測 |
| FY 2029E | 10.0x | 予測 |
修正版P/Sの計算方法
計算詳細テーブルから算出:
// 年度ごとの修正版P/S (LTM)
const modifiedPS = computed(() => {
// 各年度の年間売上を取得(累計行から)
const annualRevenue = getAnnualRevenue(fiscalYear) // 例: FY26 = $212B
// 時価総額 = 現在株価 × 株式数
// または計算されたmarketCap(PERベースまたはP/Sベース)
const marketCap = stockPrice * dilutedShares
// P/S (LTM) = 時価総額 / 年間売上
return marketCap / annualRevenue
})
チャート設計
P/S (LTM) 推移チャート
┌────────────────────────────────────────────────────────────┐
│ 30x ┼ │
│ │ ● │
│ 25x ┼─────────────────────────────────────────────25x基準─│
│ │ ● ● │
│ 20x ┼ ● ○─○ │
│ │ ● ○ │
│ 15x ┼ ● ○─○─○ │
│ │ ● │
│ 10x ┼ ● │
│ │ │
│ 5x ┼ ● │
│ │● │
│ 0x ┼──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──────────│
│ FY16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 │
│ │
│ ● 実績P/S ○ アナリスト予測P/S ─ 修正版P/S(QoQ連動) │
└────────────────────────────────────────────────────────────┘
コンポーネント設計
新規ファイル: PSRatioChart.vue
interface Props {
historicalPS: Array<{ year: string; ps: number; isActual: boolean }>
modifiedAnnualRevenue: Array<{ year: string; revenue: number }>
currentMarketCap: number // または株価 × 株式数
psMultiple: number // 基準線用(25x)
}
データ生成スクリプト
scripts/generate-nvda-ps-data.mjs を作成:
// koyfin.db から NVDA の P/S データを抽出
// → apps/web/app/composables/nvda-ps-data.ts に出力
export const nvdaPSData = [
{ year: 'FY16', ps: 3.1, isActual: true },
{ year: 'FY17', ps: 8.5, isActual: true },
// ...
]
実装手順
- スクリプト作成:
generate-nvda-ps-data.mjs - データ生成:
node scripts/generate-nvda-ps-data.mjs - チャートコンポーネント作成:
PSRatioChart.vue - 統合:
nvidia-eps-forecast.vueに追加 - 動作確認: QoQ変更時にP/Sラインが動くことを確認
表示位置
計算詳細テーブルの下、または別タブとして追加:
<!-- オプション1: 計算詳細テーブルの下 -->
<CalculationDetailTable ... />
<PSRatioChart
:historicalPS="nvdaPSData"
:modifiedAnnualRevenue="annualRevenueFromTable"
:currentMarketCap="marketCap"
:psMultiple="25"
/>
<!-- オプション2: P/Sタブ内に統合 -->
<div v-if="activeTab === 'ps'">
<!-- テーブル -->
<!-- P/Sチャート -->
</div>
テーブルデザイン案
┌────────────┬─────────┬─────────┬─────────┬─────────┬───┐
│ 項目 │ 1Q'26 │ 2Q'26 │ 3Q'26 │ 4Q'26 │...│
├────────────┼─────────┼─────────┼─────────┼─────────┼───┤
│ QoQ成長率 │ 14.9% │ 8.2% │ 5.1% │ 3.5% │ │
│ 売上 ($B) │ 45.2 │ 48.9 │ 51.4 │ 53.2 │ │
│ 純利益($B) │ 24.9 │ 26.9 │ 28.3 │ 29.3 │ │
│ 株式数(B) │ 24.8 │ 24.8 │ 24.8 │ 24.8 │ │
│ EPS ($) │ 1.00 │ 1.08 │ 1.14 │ 1.18 │ │
│ 株価 ($) │ 25 │ 27 │ 29 │ 30 │ │
└────────────┴─────────┴─────────┴─────────┴─────────┴───┘
※ 実績期間: 背景色薄いグレー
※ 予測期間: 背景色白
※ 項目列: sticky(横スクロール時固定)
作業開始コマンド
cd apps/web
pnpm dev
開発サーバー起動後、http://localhost:3000/financial-quiz/nvidia-eps-forecast で動作確認。
次セッションへの指示
- このドキュメントを読む
- 「完了ステータス」セクションで未完了のPhaseを確認
- Phase 8-4から順に実装を開始
- Chrome DevTools MCPで動作確認
次に実装すべきタスク(優先順)
- Phase 8-4: CalculationDetailTableにPER/P/Sタブ追加
- タブUI追加
- P/S計算ロジック実装
- $20T目標進捗表示
- Phase 8-5: 年間売上チャートの
1B→1T修正- DualSeriesChart.vueのY軸ラベルフォーマット修正
- Phase 8-6: P/S (LTM) 推移チャート追加
generate-nvda-ps-data.mjsスクリプト作成PSRatioChart.vueコンポーネント作成- nvidia-eps-forecast.vueに統合
関連ファイル
| ファイル | 役割 |
|---|---|
CalculationDetailTable.vue | 計算詳細テーブル(タブ追加対象) |
useNvidiaForecast.ts | ビジネスロジック |
DualSeriesChart.vue | チャートコンポーネント(Y軸修正対象) |
koyfin.db | P/Sデータソース |
新規セッション用プロンプト
nvidia-eps-forecast.vueの実装を続けてください。
計画ドキュメント:
apps/web/content/2025-12-18/nvidia-eps-forecast-phase8-calculation-table.md
このドキュメントを読んで、「完了ステータス」を確認し、
Phase 8-4から実装を再開してください。