DCF 法(Discounted Cash Flow、割引キャッシュフロー法)は、企業の 理論株価 を将来キャッシュフローの現在価値の合計として求める手法です。本記事では、最小構成の DCF を Python の関数で再現し、仮定の壊れやすさを整理します。

目次

  1. DCF の発想
  2. DCF の式(2 段階モデル)
  3. 仮定が結果を強く左右する
  4. Python で最小 DCF を書く
  5. 株主価値・1 株あたり理論価値に変換する
  6. 感応度分析(センシティビティ)
  7. 「正解の理論株価」は出ない
  8. DCF を使うときのチェックリスト
  9. DCF を使わないほうが良いケース

DCF の発想

DCF の根っこは「1 年後の 100 円より、いま手元にある 100 円のほうが価値が高い」という時間価値の発想です。将来のお金は、いまの価値に 割り引いて 評価します。

割り引くときに使う率を 割引率(r) と呼びます。1 年後の 100 円は、現在価値で

1001+r\frac{100}{1 + r}

になります。nn 年後なら、

100(1+r)n\frac{100}{(1 + r)^n}

です。これを将来の各年について合計したものが、企業の理論価値の核になります。

DCF の式(2 段階モデル)

最小構成として、よく使われる 2 段階モデル を紹介します。

  1. 予測期間(数年〜10 年)の各年のフリーキャッシュフロー(FCF)を成長率 g1g_1 で外挿
  2. 予測期間の終わり以降は、永久成長率 g2g_2 で永続するとして ターミナルバリュー(TV) を計算
  3. それぞれを割引率 rr で現在価値に割り引いて合計

予測期間 nn 年・初年度 FCF FCF0\text{FCF}_0・成長率 g1g_1・永久成長率 g2g_2・割引率 rr のとき、

企業価値=t=1nFCF0(1+g1)t(1+r)t+TV(1+r)n\text{企業価値} = \sum_{t=1}^{n} \frac{\text{FCF}_0 (1+g_1)^t}{(1+r)^t} + \frac{\text{TV}}{(1+r)^n}

ターミナルバリューはゴードンモデルで、

TV=FCFn(1+g2)rg2\text{TV} = \frac{\text{FCF}_n (1+g_2)}{r - g_2}

として求めます。

ここから 1 株あたり理論価値を出すには、企業価値から 有利子負債 を差し引いた 株主価値 を、発行済株式数で割ります。

仮定が結果を強く左右する

DCF は「式は単純、仮定が結果を強く左右する」のが特徴です。次のパラメータをわずかに動かすだけで、理論株価は大きく変わります。

  • 初年度 FCF の確からしさ
  • 予測期間中の成長率 g1g_1
  • 永久成長率 g2g_2(マクロ経済成長率の上限を超えない)
  • 割引率 rr(WACC として算出することが多い)

「仮定の壊れやすさ」を理解しておくのが、DCF を使ううえで一番重要なポイントです。

Python で最小 DCF を書く

最小構成の DCF を関数として実装します。

def dcf_two_stage(
fcf0: float,
g1: float,
g2: float,
r: float,
years: int = 5,
) -> dict:
"""2 段階 DCF で企業価値を返す(教育目的の最小実装)。
Args:
fcf0: 初年度 FCF。
g1: 予測期間中の成長率(0.05 = 5%)。
g2: 永久成長率(0.01 = 1%)。
r: 割引率(0.08 = 8%)。
years: 予測期間の年数。
Returns:
各構成要素を含む dict。
"""
if r <= g2:
raise ValueError("割引率 r は永久成長率 g2 より大きい必要があります")
# 予測期間中の FCF の現在価値合計
pv_explicit = 0.0
fcf_t = fcf0
for t in range(1, years + 1):
fcf_t = fcf0 * (1 + g1) ** t
pv_explicit += fcf_t / (1 + r) ** t
# ターミナルバリューの現在価値
tv = fcf_t * (1 + g2) / (r - g2)
pv_tv = tv / (1 + r) ** years
return {
"pv_explicit": round(pv_explicit, 2),
"tv": round(tv, 2),
"pv_tv": round(pv_tv, 2),
"enterprise_value": round(pv_explicit + pv_tv, 2),
}
result = dcf_two_stage(fcf0=100, g1=0.05, g2=0.01, r=0.08, years=5)
print(result)

実行すると、予測期間の現在価値合計・ターミナルバリュー・その現在価値・企業価値の合計が返ります。r <= g2 のとき式が破綻するので、明示的にエラーを出すようにしています。

DCF の各年 FCF 現在価値の積み上げ

株主価値・1 株あたり理論価値に変換する

企業価値から有利子負債を差し引き、現預金を足し戻すと、株主価値 に近づきます。

def fair_value_per_share(
enterprise_value: float,
interest_debt: float,
cash: float,
shares: int,
) -> float:
"""企業価値から 1 株あたり理論価値を返す。"""
if shares <= 0:
raise ValueError("発行済株式数は正の値である必要があります")
equity_value = enterprise_value - interest_debt + cash
return equity_value / shares
ev = result["enterprise_value"] # 億円単位の想定
fv = fair_value_per_share(ev, interest_debt=500, cash=200, shares=10_000_000)
print(round(fv, 2))

サンプル値は単位の整合さえ取れていれば動きます。実データでは円・百万円・億円の単位を 入力時点で統一 しておくのが安全です。

感応度分析(センシティビティ)

DCF はパラメータに敏感です。感応度表 を作って、仮定が動いたときに理論株価がどう変わるかを見せると、結果の頑健さが分かります。

import pandas as pd
g1_grid = [0.02, 0.04, 0.06, 0.08, 0.10]
r_grid = [0.06, 0.07, 0.08, 0.09, 0.10]
rows = []
for r_val in r_grid:
row = {"r": r_val}
for g1_val in g1_grid:
ev = dcf_two_stage(
fcf0=100, g1=g1_val, g2=0.01, r=r_val, years=5
)["enterprise_value"]
row[f"g1={g1_val:.0%}"] = round(ev, 1)
rows.append(row)
table = pd.DataFrame(rows).set_index("r")
print(table)

「割引率 r が 1% 動いた時」と「成長率 g1 が 2% 動いた時」では、企業価値が桁違いに動くことが珍しくありません。感応度表は 仮定が結果を強く左右する ことを視覚的に示してくれます。

「正解の理論株価」は出ない

DCF を使ううえで誤解しやすいのは「精密に計算すれば正しい株価が出る」と考えてしまうことです。

実際は次のような構造です。

  • 仮定がぶれれば結果もぶれる
  • 仮定の妥当性は 誰にも完全には分からない(将来の話だから)
  • DCF が示すのは「この仮定が正しいなら 理論株価はこれ」という 条件付きの数字

DCF 法は「決定的な答えを出す道具」ではなく、「仮定を整理して議論するための共通言語」と捉えるほうが、実用上は正確です。

DCF を使うときのチェックリスト

実用するときに最低限確認したい点を並べます。

  • 予測期間の FCF は、過去実績と整合しているか
  • 成長率 g1g_1 は、その業種の現実的な水準を超えていないか
  • 永久成長率 g2g_2 は、マクロ成長率(2〜3% 程度)を超えていないか
  • 割引率 rrg2g_2 より大きいか(等号や逆転は破綻)
  • 単位(円 / 百万円 / 億円)が混在していないか
  • 感応度表で、結果がパラメータにどれだけ敏感かを確認したか
  • FCF の定義(営業 CF − 設備投資 / 別の式)を統一したか

これらを通せば、最低限「自分の仮定で計算した結果」と言える段階になります。

DCF を使わないほうが良いケース

DCF が苦手とする領域もあります。

  • 赤字 / FCF がマイナスのスタートアップ
  • ライフサイクルが短い事業(ゲーム / 流行系)
  • M&A の影響が大きい時期(過去 FCF からの外挿が効かない)
  • 規制 / 政策で需要構造が大きく変わる業種

これらの領域では、PER / PBR / 比較企業法など別の枠組みも併用します。

生成AI へのプロンプト例

DCF の感応度ヒートマップを描く依頼の例です。

入力:
- fcf0 (float): 初年度 FCF
- years (int): 予測期間の年数
- g2 (float): 永久成長率(固定)
依頼: g1 と r の組み合わせで企業価値を計算し、ヒートマップで描画する関数を書いてください。
仕様:
- g1 は 0.00 〜 0.10 を 0.01 刻み、r は 0.04 〜 0.12 を 0.01 刻み
- 各セルに企業価値を表示(annot=True)
- カラーマップは数値が大きいほど濃く
- タイトル・軸ラベルは日本語
要件: pandas 2.2 系 + matplotlib + seaborn(または matplotlib のみ)。docstring は日本語。

まとめ

  • DCF は「将来 FCF の現在価値の合計」で理論価値を求める方法
  • 2 段階モデル: 予測期間の FCF 現在価値 + ターミナルバリューの現在価値
  • 仮定(成長率・割引率・期間)が結果を強く左右する
  • 感応度表で結果の頑健さを確認する
  • 「条件付きの数字」であり、決定的な正解は出ない