UPDATE: 2022-12-13 20:52:49
このノートではRを使ってファイナンスに関する基礎的な理論をまとめておく。ビジネスでデータ分析をする際に、ファイナンスの企業価値はユーザー価値とも考えることができそうだし、お金の時間価値はLTVに限らずユーザー価値を計算する際に、ユーザーが生み出すお金を、どのように考え、どのように扱うべきなのか、これらはファイナンスの分野の知識が役立てれそうと考えたので、ノートをいくつかに分けて、ファイナンスの基本知識をまとめておく。
このノートでは、下記の文献の第2章をRで再現しながらまとめており、数値例は書籍よりお借りしている。
前回のノートで割引率の話は扱っているが、ここでも簡単におさらいしておく。今の100万円と1年後に受け取れる100万円の価値を考える問題をここでも扱う。1年後に受け取れる100万円の現在時点の価値、つまり現在価値を計算する。将来発生するキャッシュフローの現時点における価値を現在価値(Present Value)と呼ぶ。1年後に受け取れる100万円は現在の100万円と同じ価値は持たない。これを時間価値と言い、この関係を定量化するための指標が割引率。下記の計算式で将来のお金を現在価値に変換できる。このとき、将来のキャッシュフローを割引率で割り引くと表現される。
\[ PV = \frac{CF}{1 + R} \]
1年後の100万円の価値は、割引率を10%とすると、現在では90.9万円しかない。この9.1万円の差が時間価値となる。
100 / (1 + 0.10)
## [1] 90.90909
割引率が大きくなると、時間価値は小さくなり、反対に、割引率が小さくなると、現在価値は大きくなる。この関係を可視化すると、わかりやすい。割引率が0であれば現在価値は100となるが、割引率が50%だと66.6万となる。
library(tidyverse)
<- seq(0.0, 0.5, 0.01)
r <- 100 / (1 + r)
pv <- tibble(r, pv)
df
ggplot(df, aes(r, pv)) +
geom_line() +
xlab("Discount Rate") +
ylab("Present Value") +
scale_y_continuous(breaks = seq(50, 100, 5)) +
theme_bw()
数年後のお金を現在価値に割り引く場合は、年数分割り引く必要がある。このようになるのは複利の性質から導かれる。
\[ PV = \frac{CF_{t}}{(1 + R)^{t}} \]
時間経過とともに現在価値がどうなるか可視化しておく。割引率は10%とする。3年後の100万円の現在価値は75.1万であり、10年後の100万円の現在価値は38.5万しかない。
<- seq(0,10,1)
t <- 100/(1+0.10)^t
pv2 <- tibble(pv2, t)
df2
ggplot(df2, aes(t, pv2)) +
geom_line() +
xlab("Time(Years)") +
ylab("Present Value") +
scale_y_continuous(breaks = seq(30, 100, 5)) +
theme_bw()
割引率は将来のお金と時間価値の関係を定量化するためのものと説明したが、リスクプレミアム\(R_{p}\)の反映というもう1つの側面もある。リスクプレミアムとは、リスクのある資産の期待収益率から無リスク資産の収益率を引いた差のことと説明されるが、要するにリスクの大きさを割引率に反させるための指標のこと。割引率が0.10で、リスクプレミアムが0.15のとき、
\[ PV = \frac{CF}{1 + R + R_{p}} = \frac{100}{1 + 0.10 + 0.15} = \frac{100}{1.25} = 80 \]
となる。割引率が大きくなると現在価値は小さくなるので、リスクプレミアムとしてリスクの大きさを割引率に上乗せしているため、割引率0.10よりも現在価値が小さくなっている。
NPV法は現在価値を利用してプロジェクトへの投資を判断する方法の1つ。プロジェクトから得られる全てのキャッシュフローを現在価値に割り戻して、その合計と初期投資額を比較することで判断する方法。
\[ NPV = \underbrace{CF_{0}}_{初期投資額} + \underbrace{\sum_{t=1}^{T} \frac{CF_{t}}{(1+R)^{t}}}_{PVの合計} \] 例えば、
この場合、プロジェクトに投資するべきか否かを考える。まずは1年後は115万円、2年後は264.5万円のキャッシュフローを現在価値に割り引く作業を行う。1年後の115万円は現在価値で100万円、2年後は264.5万円は現在価値で200万円ということになる。
c(115/(1+0.15)^1, 264.5/(1+0.15)^2)
## [1] 100 200
これらを合計すると、300万円となり、初期投資額の280を上回るため、このプロジェクトはプラスのキャッシュフローを生み出すので投資してもよい。毎回このような計算をするのは面倒なので、下記のように関数化しておく。
<- function(init, cf, r){
npv_method <- seq(1,length(cf),1)
t <- cf/(1+r)^t
pv <- sum(pv)
npv <- init + npv
gain
<- list(
res DiscountRate = r,
InitialCost = init,
CF = cf,
PV = pv,
NPV = npv,
gain = gain
)
return(res)
}
npv_method(init = -280, cf = c(115, 264.5), r = 0.15)
## $DiscountRate
## [1] 0.15
##
## $InitialCost
## [1] -280
##
## $CF
## [1] 115.0 264.5
##
## $PV
## [1] 100 200
##
## $NPV
## [1] 300
##
## $gain
## [1] 20
割引率を用いた応用方法として、配当割引モデル(Dividend Discount Model)というのがある。いくつか計算方法があるが、ここでは定率成長配当割引モデルをまとめる。このモデルは毎年一定の割合で配当額が成長するという仮定をもとにした計算方式をとる。下記のサイトがわかりやすく、等比数列の和の公式を利用して近似する方法を解説されていてわかりやすかった。こちらのサイトより図をお借りする。
【財務・会計】配当割引モデルと継続価値の式は導出しよう│暗記はNG【中小企業診断士】
定率成長モデル
\[ P = \frac{D_{1}}{(1+r)^{1}} + \frac{D_{1}(1+g)^{1}}{(1+r)^{2}} + \frac{D_{1}(1+g)^{2}}{(1+r)^{3}} \approx \frac{D_{1}}{r-g} \]
下記の設定において、定率成長モデルで計算を行う。
<- 0.1
r <- 0.03
g <- 25
d /(r-g) d
## [1] 357.1429
可視化すると、100年目くらいには収束に向かっていることがわかる。
<- function(x, d = 25, r = 0.1, g = 0.03){
dmm sum((d*(1+g)^(x-1))/((1+r)^x))
}
<- 1:200
t # map_dbl(.x = t, .f = function(x){dmm(x = t[1:x])})でもよい
<- vector(mode = "numeric", length(t))
res for (i in 1:length(t)) {
<- dmm(x = t[1:i])
res[[i]]
}
ggplot(tibble(t, res), aes(t, res)) +
geom_line() +
xlab("Time(Years)") +
ylab("Theoretical Stock Price") +
scale_y_continuous(breaks = seq(0, 500, 50)) +
scale_x_continuous(breaks = seq(0, 200, 10)) +
theme_bw()
IRR(内部収益率)は「プロジェクトのNPVが0になるような割引率」と定義される。言い換えると、プロジェクトが将来生み出すキャッシュフローの現在価値と、プロジェクトに必要なキャッシュフローの現在価値が0になる割引率のこと。数式で表現するとわかりやすい。現在価値の総和が0になる割引率\(y\)を求める。もし、リスクを勘定し、この割引率よりも割引率が大きくなる場合、NPVは小さくなるので、これがある種のハードルと考えることもできるので、ハードルレートとも呼ばれる。
\[ \sum_{t=1}^{T} \frac{CF_{t}}{(1+y)^{t}} = 0 \]
下記のプロジェクトからIRR法で投資判断を行ってみる。
数式にしてみると、下記の多項式の解を計算する必要がある。
\[ \begin{eqnarray} -100 + \frac{40}{(1+y)^{1}} + \frac{50}{(1+y)^{2}} + \frac{60}{(1+y)^{3}} = 0 \\ \Leftrightarrow -100(1+y)^{3} + 40(1+y)^{2} + 50(1+y)^{1} + 60 = 0 \\ \end{eqnarray} \]
ここで、\(1+y=Y\)として変形して、Rで計算しやすいようにする。
\[ \begin{eqnarray} -100(1+y)^{3} + 40(1+y)^{2} + 50(1+y)^{1} + 60 = 0 \\ \Leftrightarrow 60 + 50Y^{1} + 40Y^{2} - 100Y^{3} = 0 \end{eqnarray} \]
あとは多項式の数値解を計算してくれるpolyroot
関数で計算する。\(1+y=Y\)としているので、最後に戻すことを忘れないように注意する。
# 次数が0から並べてベクトルで渡す
# 60 + 50Y^{1} + 40Y^{2} - 100Y^{3}
<- c(60, 50, 40, -100)
x <- Re(polyroot(x)[[3]])
Y # Y = 1 + y ⇔ y = Y - 1
<- Y - 1
irr irr
## [1] 0.2164779
この割引率でNPVが0になるかどうか、さきほど作成した関数を使って検証してみると、gain
はほぼ0で、NPVを0にする割引率であることがわかる。
npv_method(init = -100, cf = c(40, 50, 60), r = irr)
## $DiscountRate
## [1] 0.2164779
##
## $InitialCost
## [1] -100
##
## $CF
## [1] 40 50 60
##
## $PV
## [1] 32.88182 33.78793 33.33025
##
## $NPV
## [1] 100
##
## $gain
## [1] 5.684342e-14
NPVとの関係を可視化しておく。
<- seq(0, 1, 0.05)
irrs <- map_dbl(.x = irrs, .f = function(x){npv_method(init = -100, cf = c(40, 50, 60), r = x)$gain})
npvs
ggplot(tibble(irrs, npvs), aes(irrs, npvs)) +
geom_line() +
geom_hline(yintercept = 0, linetype = "dotted") +
geom_vline(xintercept = irr, linetype = "dotted") +
xlab("IRR") +
ylab("NPV") +
scale_y_continuous(breaks = seq(-100, 100, 5)) +
scale_x_continuous(breaks = seq(0, 1, 0.05)) +
theme_bw()