author: aaron-clark-aic
这货的其他文章目录
多年以来,金融分析师们使用过很多公式计算一个公司的内在价值。一些人喜欢快速简单的方法:低市盈率、低市净率和高分红率。但根据巴菲特的观点,最好的系统描述是约翰·伯尔·威廉斯70年前的定义,在《投资价值理论》一书中,他的定义是:“一个公司的价值决定于在其生存期间,预期产生的所有现金流,在一个合理的利率上的折现。”巴菲特解释说:“这样的话,无论是马鞭制造商,还是手机运营商(尽管性质各异),所有企业在经济层面都是一样的。”
巴菲特指出这个方法的使用,非常类似于债券的估值过程。债券通常具有明确的票面利息和到期日,人们可以清楚地知道,它在到期日之前产生的现金流。如果你将所有收到的票息加在一起,然后除以一个合适合适的贴现率,就会得到债券的当前价格。要确定一个企业的价值,分析者只要估计公司未来的股东盈余现金流,并用合适的利率进行贴现,即可得到其现在的价值(现值)。
好,上面一段是我承认在巴菲特的书里抄的!那么这么多一大段东西能不能通过人话翻译出来?答案是肯定的!
上面的内容说的最主要的就是两点:1、估算企业价值 2、合理折现率
翻译成人话:我们要通过一个数学公式估算出企业的价值,而且这个价值能够通过合理折现率变成钱。
“我擦,这TM谁能够算得出来,算得出来都去开巴菲盛宴了”
但是,还真的有人能算的出来这个公式,谁啊?当然是天天和钱打交道的银行了。我是长期没有存款的人~,不知道你们有没有,所以我不知道现在的存款利率,但是我有房啊~我很清楚现在银行商业贷款需要我交多少利息!我买房的时候为什么银行会贷款给我?当然是为了赚钱,也就是说,银行将现金折算成价值以及这个价值应该产生多少现金才划算,也就是起码差不多也许大概要跑赢果丹皮(GDP)吧!我这里姑且将这个利率定为6%:
def __init__(self,standardRate = 0.06):
self.__standardRate__ = standardRate
现在折现率有了,不过房子贷的款是确定的,企业呢?一个企业到底能变成多少等价的钱,莎士比亚说“这是一个问题!”。不过巴菲特说,这不是一个问题,企业估价看“股东盈余现金流”。也就是巴菲特认为,股东盈余才是真真能够代表股东们投入的钱,而这些钱是需要生钱的!
“龙生龙凤生凤,耗子生儿打地洞!”,钱当然是要生钱的。银行说,少了6个点,我们不贷款给你们买房~。股东们当然也会说,少了6个点我还不如把钱借给aaron-clark-aic买房~,开什么企业,开企业。
现在明显了,我们只要计算出一个企业的股东盈余,再除以,利率。这个就是企业的估值?是的,好像巴菲特说的就是这个。
巴菲的的公式计算好了,我们只需要知道净利润,固定资产的变化值,房贷利率,就能够知道现在的股价对应的企业到底是贵了还是便宜了。
下面是关于代码的一些说明:
1.这个类用于平滑股价,为什么平滑股价请参考我的文章
class SmoothPrice:
#code
2.这个类用于生成查询季度,为什么用季度来查询请参考我的文章
class SeasonReports:
def __init__(self):
self.__today__ = datetime.date.today()
self.__toyear__ = datetime.datetime(self.__today__.year,1,1)
self.__lastyear__ = datetime.datetime((self.__toyear__ - datetime.timedelta(days=1)).year,1,1)
self.__lasttwoyear__ = datetime.datetime((self.__lastyear__ - datetime.timedelta(days=1)).year,1,1)
def seasonDaily(self):
season = ['q4','q3','q2','q1']
# print([str(self.__toyear__.year) i for i in season] [str(self.__lastyear__.year) i for i in season] [str(self.__lasttwoyear__.year) i for i in season])
_out = [str(self.__toyear__.year) i for i in season] [str(self.__lastyear__.year) i for i in season] [str(self.__lasttwoyear__.year) i for i in season]
_out.reverse()
return _out
3.生成图像中的绿线,黄线,红线分别是什么意思:
绿色实线:最近4个月的季报汇总,且以总股数计算
绿色虚线:同绿色实线,且以流通股数计算
黄色实线:上一次计算(也是按季报汇总),也就是往前追溯一个季度的计算值,且以总股数计算
黄色虚线:同黄色实线,且以流通股数计算
红色实线:上上次计算,也就是往前追溯两个季度的计算值,且以总股数计算
红色虚线:同红色实线,且以流通股数计算
import numpy as np
import datetime
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import math
# 平滑价格
# @inP [,,,,] 价格数组
class SmoothPrice:
def __init__(self,inP:np.ndarray):
self.__inP__ = inP
self.__l_smooth__ = inP
self.__q_smooth__ = inP
self.__c_smooth__ = inP
def __linearSmooth5__(self):
_outP = []
inP = self.__inP__
n = len (inP)
if n < 5:
for i in inP:
_outP.append (i)
else:
_outP.append ((3.0 * inP[0] + 2.0 * inP[1] + inP[2] - inP[4]) / 5.0)
_outP.append ((4.0 * inP[0] + 3.0 * inP[1] + 2 * inP[2] + inP[3]) / 10.0)
_i = 0
for i in inP:
if not _i == 0 and not _i == 1 and not _i == n - 2 and not _i == n - 1:
_outP.append ((inP[_i - 2] + inP[_i - 1] + inP[_i] + inP[_i + 1] + inP[_i + 2]) / 5.0)
_i = _i + 1
_outP.append ((4.0 * inP[n - 1] + 3.0 * inP[n - 2] + 2 * inP[n - 3] + inP[n - 4]) / 10.0)
_outP.append ((3.0 * inP[n - 1] + 2.0 * inP[n - 2] + inP[n - 3] - inP[n - 5]) / 5.0)
self.__l_smooth__ = _outP
def __quadraticSmooth5__(self):
_outP = []
inP = self.__l_smooth__
n = len (inP)
if n < 5:
for i in inP:
_outP.append (i)
else:
_outP.append ((31.0 * inP[0] + 9.0 * inP[1] - 3.0 * inP[2] - 5.0 * inP[3] + 3.0 * inP[4]) / 35.0)
_outP.append ((9.0 * inP[0] + 13.0 * inP[1] + 12 * inP[2] + 6.0 * inP[3] - 5.0 * inP[4]) / 35.0)
_i = 0
for i in inP:
if not _i == 0 and not _i == 1 and not _i == n - 2 and not _i == n - 1:
_outP.append ((- 3.0 * (inP[_i - 2] + inP[_i + 2]) + 12.0 * (inP[_i - 1] + inP[_i + 1]) + 17 * inP[
_i]) / 35.0)
_i = _i + 1
_outP.append (
(9.0 * inP[n - 1] + 13.0 * inP[n - 2] + 12.0 * inP[n - 3] + 6.0 * inP[n - 4] - 5.0 * inP[n - 5]) / 35.0)
_outP.append (
(31.0 * inP[n - 1] + 9.0 * inP[n - 2] - 3.0 * inP[n - 3] - 5.0 * inP[n - 4] + 3.0 * inP[n - 5]) / 35.0)
self.__q_smooth__ = _outP
def __cubicSmooth5__(self):
_outP = []
inP = self.__q_smooth__
n = len (inP)
if n < 5:
for i in inP:
_outP.append (i)
else:
_outP.append ((69.0 * inP[0] + 4.0 * inP[1] - 6.0 * inP[2] + 4.0 * inP[3] - inP[4]) / 70.0)
_outP.append ((2.0 * inP[0] + 27.0 * inP[1] + 12.0 * inP[2] - 8.0 * inP[3] + 2.0 * inP[4]) / 35.0)
_i = 0
for i in inP:
if not _i == 0 and not _i == 1 and not _i == n - 2 and not _i == n - 1:
_outP.append ((-3.0 * (inP[_i - 2] + inP[_i + 2]) + 12.0 * (inP[_i - 1] + inP[_i + 1]) + 17.0 * inP[
_i]) / 35.0)
_i = _i + 1
_outP.append (
(2.0 * inP[n - 5] - 8.0 * inP[n - 4] + 12.0 * inP[n - 3] + 27.0 * inP[n - 2] + 2.0 * inP[n - 1]) / 35.0)
_outP.append (
(- inP[n - 5] + 4.0 * inP[n - 4] - 6.0 * inP[n - 3] + 4.0 * inP[n - 2] + 69.0 * inP[n - 1]) / 70.0)
self.__c_smooth__ = _outP
def smooth(self):
self.__linearSmooth5__()
self.__quadraticSmooth5__()
self.__cubicSmooth5__()
return self.__c_smooth__
class SeasonReports:
def __init__(self):
self.__today__ = datetime.date.today()
self.__toyear__ = datetime.datetime(self.__today__.year,1,1)
self.__lastyear__ = datetime.datetime((self.__toyear__ - datetime.timedelta(days=1)).year,1,1)
self.__lasttwoyear__ = datetime.datetime((self.__lastyear__ - datetime.timedelta(days=1)).year,1,1)
def seasonDaily(self):
season = ['q4','q3','q2','q1']
# print([str(self.__toyear__.year)+i for i in season]+[str(self.__lastyear__.year)+i for i in season]+[str(self.__lasttwoyear__.year)+i for i in season])
_out = [str(self.__toyear__.year)+i for i in season]+[str(self.__lastyear__.year)+i for i in season]+[str(self.__lasttwoyear__.year)+i for i in season]
_out.reverse()
return _out
#处理股票代码
class Stocks:
def combineIdustryStocks(self,industries:list):
return np.hstack([ get_industry_stocks(i) for i in industries])
def standardStocks(self,stockList):
_stocks = list(get_all_securities('stock').index)
_standardStocks = []
for i in stockList:
_standardStocks =_standardStocks+[code for code in _stocks if code.upper().startswith(i)]
return _standardStocks
class TargetStock:
def __init__(self,standardRate = 0.06):
self.__standardRate__ = standardRate
def setSeasonReport(self,seasonDaily,stock):
list =[]
# print(seasonDaily)
for _season in seasonDaily:
jqv = valuation
df = get_fundamentals(query(jqv.code,jqv.circulating_cap,jqv.capitalization,income.net_profit,jqv.market_cap,balance.fixed_assets,indicator.eps
).filter(jqv.code == stock
).order_by(
),statDate = _season
)
if not df.empty:
list.append([
('net_profit',df['net_profit'][0]),
('circulating_cap',df['circulating_cap'][0]),
('capitalization',df['capitalization'][0]),
('seasonReport',_season),
('fixed_assets'+_season,df['fixed_assets'][0]),
('eps',df['eps'][0])
])
return list
def getstockPrice(self,stock,days = 200,end_date = datetime.date.today(),frequency = 'daily'):
_points = get_price(stock,count=days,end_date= end_date,frequency=frequency,fields=['close','volume'],fq=None)
_in = _points['close'].values[:days]
_in_volume = _points['volume'].values[:days]
sp_in = SmoothPrice(_in)
sp_in_volume = SmoothPrice(_in_volume)
y_in = sp_in.smooth()
volume_in = sp_in_volume.smooth()
y_base = _in
x=range(days)
sr = SeasonReports()
stock_sel = self.setSeasonReport(sr.seasonDaily(),stock)
if len(stock_sel) < 6:
print('warning,-'+stock+'-seasons is not enough!')
return False
stock_sel.reverse()
last_net_profit =sum([i[0][1] for i in stock_sel[1:4]])
# print([i[0][1] for i in stock_sel[:4]])
pre_net_profit = sum([i[0][1] for i in stock_sel[2:5]])
base_net_profit = sum([i[0][1] for i in stock_sel[3:6]])
# print(stock,[last_net_profit,pre_net_profit,base_net_profit])
def fixed_assert(i):
return stock_sel[i][4][1]
def circulating_cap(i):
return 10000*stock_sel[i][1][1]
def capitalization(i):
return 10000*stock_sel[i][2][1]
last_target_price_circap = ((last_net_profit - fixed_assert(0)+fixed_assert(3))/self.__standardRate__)/circulating_cap(0)
last_target_price_cap = ((last_net_profit - fixed_assert(0)+fixed_assert(3))/self.__standardRate__)/capitalization(0)
pre_target_price_circap = ((pre_net_profit - fixed_assert(1)+fixed_assert(4))/self.__standardRate__)/circulating_cap(1)
pre_target_price_cap = ((pre_net_profit - fixed_assert(1)+fixed_assert(4))/self.__standardRate__)/capitalization(1)
base_target_price_circap = ((base_net_profit - fixed_assert(2)+fixed_assert(5))/self.__standardRate__)/circulating_cap(2)
base_target_price_cap = ((base_net_profit - fixed_assert(2)+fixed_assert(5))/self.__standardRate__)/capitalization(2)
# print([not math.isnan(i) for i in [last_target_price_circap,last_target_price_cap,pre_target_price_circap,pre_target_price_cap,base_target_price_circap,base_target_price_cap]])
for i in [math.isnan(i) for i in [last_target_price_circap,last_target_price_cap,pre_target_price_circap,pre_target_price_cap,base_target_price_circap,base_target_price_cap]]:
if i :
print('warning,-'+stock+'-can\'t find enough circap or cap')
return False
# print(stock,[(last_target_price_circap,last_target_price_cap),
# (pre_target_price_circap,pre_target_price_cap),
# (base_target_price_circap,base_target_price_cap)
# ])
# print([i[3][1] for i in stock_sel])
return [('smoothPrice',y_in),('truthPrice',y_base),('x_axis',x),(
'report',[('last_target_price_circap',int(last_target_price_circap)),
('last_target_price_cap',int(last_target_price_cap)),
('pre_target_price_circap',int(pre_target_price_circap)),
('pre_target_price_cap',int(pre_target_price_cap)),
('base_target_price_circap',int(base_target_price_circap)),
('base_target_price_cap',int(base_target_price_cap))
]),
('in_volume',volume_in),
('stock',stock),
('reportSeason',[i[3][1] for i in stock_sel])]
def plotFigure(self,getstockPrice):
if getstockPrice == False or len(getstockPrice) != 7:
print('warning empty')
return False
stock = getstockPrice[5][1]
reportSeason = getstockPrice[6][-1][0]
smoothPrice = getstockPrice[0]
truthPrice = getstockPrice[1]
x_axis = getstockPrice[2]
report = getstockPrice[3]
in_volume = getstockPrice[4]
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
fig = plt.figure (tight_layout=False,figsize=(13, 30))
gs = gridspec.GridSpec (2, 2)
ax = fig.add_subplot (gs[0, :])
ax.plot (x_axis[1], smoothPrice[1], "b")
ax.plot (x_axis[1], truthPrice[1], "y")
# ax.set_ylabel ('YLabel0')
ax.set_xlabel ('最近预估g(-[总股份]/--[流通股份]),上一季度起点y,上上季度起点r')
ax.axhline ((report[1][0][1]), color='g', linestyle='--', label='last_target_price_circap')
ax.axhline ((report[1][1][1]), color='g', linestyle='-', label='last_target_price_cap')
ax.axhline (report[1][2][1], color='y', linestyle='--', label='pre_target_price_circap')
ax.axhline (report[1][3][1], color='y', linestyle='-', label='pre_target_price_cap')
ax.axhline (report[1][4][1], color='r', linestyle='--', label='base_target_price_circap')
ax.axhline (report[1][5][1], color='r', linestyle='-', label='base_target_price_cap')
ax.grid ()
ax = fig.add_subplot (gs[1, :])
ax.set_ylabel ('量 能')
ax.plot (x_axis[1], in_volume[1], 'g')
ax.grid ()
plt.show()
_st = Stocks()
_sd = SeasonReports()
_as = TargetStock()
_as.plotFigure(_as.getstockPrice(stock=_st.standardStocks(stockList=['000915'])[0]))
本社区仅针对特定人员开放
查看需注册登录并通过风险意识测评
5秒后跳转登录页面...
移动端课程