估值方法:分红现金流折现值在不同参数变化下的目标偏离度的敏感性分析
发布时间:2023-09-25 07:22:53
- 使用折现率定义目标,并定义目标偏离度=市场利率-目标折现率。
- 为什么定义目标偏离度?本意是想观察在不同参数下,目标折现率会有什么变化,于是抽象出了目标偏离度的概念。
- 对不同参数做敏感性分析,观察目标偏离度的变化情况。
- 此处使用敏感性分析作为风险分析方法,观察当一个环境变量变化时,目标偏离度如何变化,其结果可作为参考判断投入价格成本是否安全。
- 两者结合,给出一种可以分析风险的估值方法,避免不理性行为。
模型说明
使用分红折现的方式估计现值,即P点的价格P 须等于 D点(P’点之前的所有D点)的折现 + P‘点的折现。但这里有两个疑问?
(1)为什么P点的价格要等于后面的折现值?
P点的价格P是使用D点和P’点的折现值计算出来的参考价格,且折现率已经包含了期望的收益率,也就是说,使用这个计算出来的P值作为价格成本,如果后续的分红发生了,那么收益率自然就达到了折现率,因此就用了“等于”。
(2)P‘点的价格怎样估计?
在之前学习估值方法的时候,无脑地接受使用了类似无限期等比数列的方法,但是在实际操作中,我发现我自己只用10年期等比长度,因为我觉得没有人能投资无限期,无限期假设是不成立的,我把P‘点定义为剩余价值,也就是说我一直把剩余价值当做0来处理。这样做固然是安全的,但是整体估值却是偏低的,错过了很多有价值的资产。于是为了提高估值的准确性,开始逐渐考虑P’的剩余价值,后来才想明白,教科书还是有道理的,为什么呢?因为站在现在这个时间点,我们通过把未来的现金流折现来计算P值,那么站在未来的时间点P',我们还是通过把未来(P'的未来)的现金流折现计算P’的值,最终换算下来的时候,就出现了教科书里的等比数列(前提条件是市场必须在前后时间使用一致的估值方法)。
模型参数
有了基本的模型理论,就开始为模型选择一些有意义的参数信息,参数的选择并不是盲目的,必须结合一些能观察到现实数据和发展稳定的公司才有意义。最终还是使用了教科书里的方法:
参数介绍
输入值
- 净利润高速增长率net_profit_high_growth_rate 10%
- 净利润高速增长期限,单位:年net_profit_high_growth_years 10
- 贴现率discount_rate 8%
- 分红比率dividend_rate 40%
- 净利润永续增长率net_profit_continuity_growth_rate 3%
- 净利润永续期限,单位:年net_profit_continuity_growth_years 40
- 实际净利润EPS
输出值
- 净利润累积贴现值CEPS
- 分红累积贴现值CDPS
上面的参数定义可以不用局限,可以根据自己的理解进行调整。
于是到此为止,建立出了一个简单估值模型。接下来,我们就使用这个估值模型计算目标偏离度和做敏感性分析。
目标偏离度
当我们把钱存在银行时,银行会给我们一个利率,这是我们预期的收益率,并且是非常稳定的。当我们把钱购买理财产品或者投资到其他品种时,理财产品也会给我们一个收益率,但是却没有那么稳定,于是我们就称之为风险。产品到期时,我们发现实际到手的钱和当初约定的钱差那么一些,也可能差很多,于是就产生了悲欢离合。这里实际和约定的差异,我定义为目标偏离度。
在本文的估值模型中,对目标偏离度的定义和度量:在初始度量时,选择一个期望的折现率作为目标折现率,然后再为其他参数选择有参考依据的值;然后假设当参数(非折现率参数)发生变化时,输出值就会发生变化,为了保持输出值不变,调整折现率的值,这个最终调整的折现率就是类似最终实际到手的钱,我称之为市场利率(调整后的折现率)。而目标偏离度 = 市场利率(调整后的折现率)- 目标折现率。
用函数表达式的语言解释如下,其实就是变换成了折现率是其他参数的函数。
在本文的模型中,并没有使用解析的方式求调整后的折现率(因为不会求解析解),而是使用了数值估计的方法(一点一点试,直到和初次度量的输出值差异较小时停止)。
敏感性分析
目标偏离度度量好之后,就开始做敏感性分析了。做敏感性分析是为了控制风险,比如虽然理财的到期收益是不确定的,但是我期望它变化不要太大,或者是说在购买之前,就提前知道它的变化到底有多大,如果太大就不要购买了。使用函数表达式的语言来解释的话,其实就是做了一次偏微分,但是因为没有解析解,最终是通过简单的数值画图来观察。
初始度量输出值:[85.19870121 34.07948048],目标折现率10%。
对投入价格的敏感性
假设预期投入价格是34元,但是追涨购买会导致收益率降低4%
对净利润增长率的敏感性
如果净利润增长不及预期,那么收益率会不同程度降低
对EPS的敏感性
如果盈利不及预期,那么收益率会不同程度降低
对净利润高增长率年限的敏感性
如果可持续高速发展年限不及预期,那么收益率会不同程度降低
敏感性分析给出的结论都是显而易见的,量化之后可能更加清晰一些,也许可以阻止头脑发热的行为。
小结
- 本文给出的模型非常入门,用来回答 不做什么 比回答 做什么 更合适一些。
- 在模型优化上,还可以继续改善经营相关的参数,例如引入更多的不确定性,从而更加审慎地估值。
- 使用模型之前,要先为模型选择合适的生存条件,例如选择趋势性发展良好的公司。
源码参考
# -*- coding: UTF-8 -*-
import matplotlib
import portfolio as pf
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
from matplotlib.font_manager import FontManager
import numpy as np
import math
import sys
# 支持中文
# matplotlib.rc("font", family='Apple LiSung')
def unit_cumulation_discount(net_profit_high_growth_rate=0.12,
net_profit_high_growth_years=10,
discount_rate=0.1,
dividend_rate=0.4,
net_profit_continuity_growth_rate=0.03,
net_profit_continuity_growth_years=40):
term_net_profit_array = []
unit_EPS = 1
years = range(net_profit_high_growth_years + net_profit_continuity_growth_years)
for year in years:
if year == 0:
term_net_profit = unit_EPS
elif year <= net_profit_high_growth_years:
term_net_profit = term_net_profit_array[year - 1] * (1 + net_profit_high_growth_rate)
else:
term_net_profit = term_net_profit_array[year - 1] * (1 + net_profit_continuity_growth_rate)
term_net_profit_array.append(term_net_profit)
discount_term_net_profit_array = []
for year in years:
discount_term_net_profit = term_net_profit_array[year] / math.pow((1 + discount_rate), year)
discount_term_net_profit_array.append(discount_term_net_profit)
cumulation_discount_term_net_profit = np.sum(discount_term_net_profit_array[1:])
term_dividend_array = []
for year in years:
term_dividend = term_net_profit_array[year] * dividend_rate
term_dividend_array.append(term_dividend)
discount_term_dividend_array = []
for year in years:
discount_term_dividend = discount_term_net_profit_array[year] * dividend_rate
discount_term_dividend_array.append(discount_term_dividend)
cumulation_discount_term_dividend = np.sum(discount_term_dividend_array[1:])
return np.array([cumulation_discount_term_net_profit, cumulation_discount_term_dividend])
"""
input:
EPS = 1
output:
CEPS = 0
CDPS = 0
"""
def cumulation_discount(
EPS=1,
net_profit_high_growth_rate=0.12,
net_profit_high_growth_years=10,
discount_rate=0.1,
dividend_rate=0.4,
net_profit_continuity_growth_rate=0.03,
net_profit_continuity_growth_years=40):
unit_cumu_discount = unit_cumulation_discount(net_profit_high_growth_rate,
net_profit_high_growth_years,
discount_rate,
dividend_rate,
net_profit_continuity_growth_rate,
net_profit_continuity_growth_years)
return unit_cumu_discount * EPS
"""
市场利率
"""
def find_market_rate(
prices=np.array([1, 1]),
EPS=1,
net_profit_high_growth_rate=0.12,
net_profit_high_growth_years=10,
target_discount_rate=0.1,
dividend_rate=0.4,
net_profit_continuity_growth_rate=0.03,
net_profit_continuity_growth_years=40):
_diff_abs = 1
market_discount_rate = target_discount_rate
_cumu_discount = cumulation_discount(EPS, net_profit_high_growth_rate, net_profit_high_growth_years, market_discount_rate, dividend_rate,
net_profit_continuity_growth_rate, net_profit_continuity_growth_years)
_diff = np.sum(_cumu_discount - prices)
_diff_abs = math.fabs(_diff)
count = 1
while _diff_abs >= 1:
count = count + 1
if _diff > 0:
# 现值大于投入价格,那么需要提高贴现率,也就是超额目标
# 增加步长设定为1个基点,即0.01%
market_discount_rate = market_discount_rate + 0.0001
else:
# 现值低于投入价格,那么需要降低贴现率,也就是低于目标
# 减少步长设定为1个基点,即0.01%
market_discount_rate = market_discount_rate - 0.0001
_cumu_discount = cumulation_discount(EPS, net_profit_high_growth_rate, net_profit_high_growth_years, market_discount_rate, dividend_rate,
net_profit_continuity_growth_rate, net_profit_continuity_growth_years)
_diff = np.sum(_cumu_discount - prices)
_diff_abs = math.fabs(_diff)
# print("遍历次数" + str(count))
# 现值和目标价格差异在1角钱以内
return market_discount_rate
"""
目标偏离度:市场利率 - 目标贴现率
"""
def target_rate_bias(prices=np.array([1, 1]),
EPS=1,
net_profit_high_growth_rate=0.10,
net_profit_high_growth_years=10,
target_discount_rate=0.10,
dividend_rate=0.4,
net_profit_continuity_growth_rate=0.03,
net_profit_continuity_growth_years=40):
market_rate = find_market_rate(prices, EPS, net_profit_high_growth_rate, net_profit_high_growth_years, target_discount_rate, dividend_rate,
net_profit_continuity_growth_rate, net_profit_continuity_growth_years)
return market_rate - target_discount_rate
# 现值估计
cumu_discount = cumulation_discount(EPS=4.23, net_profit_high_growth_years=5)
print(cumu_discount)
# 计算目标对参数的敏感性
# 对投入价格的敏感性
prices_array = np.linspace(cumu_discount, [142, 56], 100)
target_rate_bias_array = []
for price_array in prices_array:
target_rate_bias_value = target_rate_bias(price_array, EPS=4.23, net_profit_high_growth_years=5)
target_rate_bias_array.append(target_rate_bias_value)
plt.plot(prices_array, target_rate_bias_array)
plt.title("对投入价格的敏感性")
plt.savefig("对投入价格的敏感性.png")
plt.show()
# 对净利润增长率的敏感性
net_profit_high_growth_rate_array = np.linspace(0.05, 0.20, 100)
target_rate_bias_array = []
for net_profit_high_growth_rate in net_profit_high_growth_rate_array:
target_rate_bias_value = target_rate_bias(cumu_discount, EPS=4.23, net_profit_high_growth_rate=net_profit_high_growth_rate,
net_profit_high_growth_years=5)
target_rate_bias_array.append(target_rate_bias_value)
plt.plot(net_profit_high_growth_rate_array, np.zeros(net_profit_high_growth_rate_array.size), lw=3, alpha=0.8)
plt.plot(net_profit_high_growth_rate_array, target_rate_bias_array)
plt.title("对净利润增长率rate的敏感性")
plt.savefig("对净利润增长率rate的敏感性.png")
plt.show()
# 对EPS的敏感性
EPS_array = np.linspace(3, 5, 150)
target_rate_bias_array = []
for eps in EPS_array:
target_rate_bias_value = target_rate_bias(cumu_discount, EPS=eps, net_profit_high_growth_years=5)
target_rate_bias_array.append(target_rate_bias_value)
plt.plot(EPS_array, np.zeros(EPS_array.size), lw=3, alpha=0.8)
plt.plot(EPS_array, target_rate_bias_array)
plt.title("对EPS的敏感性")
plt.savefig("对EPS的敏感性.png")
plt.show()
# 对净利润高增长率年限的敏感性
year_array = np.linspace(1, 10, 10)
target_rate_bias_array = []
for year in year_array:
target_rate_bias_value = target_rate_bias(cumu_discount, EPS=4.23, net_profit_high_growth_years=int(year))
target_rate_bias_array.append(target_rate_bias_value)
plt.plot(year_array, np.zeros(year_array.size), lw=3, alpha=0.8)
plt.plot(year_array, target_rate_bias_array)
plt.title("对净利润高增长率年限year的敏感性")
plt.savefig("对净利润高增长率年限year的敏感性.png")
plt.show()