昨天讨论完股利贴现模型 - 年化复合增长率(CAGR)中的增长率后,发现只需要在原来的python源代码上再添加几行代码就可以实现PEG选股策略。
啥是PEG
在估值指标中,PEG意为市盈率相对盈利增长率指标,最先由Jim Slater提出来,公式为PEG=PE/净利润增长率。PE即为某期公司市盈率水平,分母为对未来的净利润增长率预期,根据考察年限的区别,可以选用1年、2年较短的年复合增长率,也可以选用5年、10年这样的较长年复合增长率,一般而言PEG指标<1意味着企业进入投资价值区域(负值意味着亏损,该类不考虑),PEG越小企业投资价值越大,反之不具备太大投资价值。
简单来说,PEG就是股票市场衡量单一股票性价比的工具。
因为股票的高估和低估值并不是单靠看PE就能判断。 假设某一股票的PE已经达到100倍,那么只看这一数值,我们第一反应肯定觉得是这只股票是被高估了,不值得投。但是如果我告诉你这股票的年复合增长率可以高达100%,那么这就不一样了,因为这股票的下一年营收会翻倍,预计净利润也会翻倍,那么PE就变为50倍。 这就解释了为什么有些龙头股票的股票会越涨越便宜
。
所以PE的高与低还需要结合年复合增长率(g)
来衡量。
案例
这里以隆基股份(601012)作为标的股票。
根据同花顺给出的行业标的,这里选取了 爱旭股份, 晶澳科技, 协鑫集成, 中环股份, 东方日升, 中来股份, 亿晶光电, 天合光能, 向日葵, 隆基股份, 通威股份, 正泰电器, 航天机电, 拓日新能。
下面主要是在jupyterlab 实现的, 数据来源(免费):tushare.pro。
实现代码
设置tushare的token和引入相关的库
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import tushare as ts import pandas as pd
#设置完整显示数据 pd.set_option('display.max_rows', 500) pd.set_option('display.max_columns', 500) pd.set_option('display.width', 1000) pd.set_option('display.float_format', '{:,.2f}'.format)
#注册tushare后获得token pro = ts.pro_api('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')
def cagr(start_value, end_value, num_periods): return (end_value / start_value) ** (1 / (num_periods - 1)) - 1
|
设置年化复合增长率(CAGR)的时间跨度,这里我选取5年期,因此时间段为2015年-2020年.
1 2 3 4 5
| #时间段,这里选取5年期 start_date = '20150101'
#股票池 stock_list = ['爱旭股份', '晶澳科技', '协鑫集成', '中环股份', '东方日升', '中来股份', '亿晶光电', '天合光能', '向日葵', '隆基股份', '通威股份', '正泰电器', '航天机电', '拓日新能']
|
计算各股票的年复合增长率
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| result_list = []
#主要用于将上述的股票中文名称转换为tushare能识别的`ts_code` stock_basic = pro.stock_basic(exchange='', list_status='L', fields='ts_code,symbol,name') stock_selections = stock_basic[stock_basic['name'].isin(stock_list)]
for ticker, name in zip(stock_selections['ts_code'], stock_selections['name']): result_dict = {} #获取股票历年的营收 total_revenue = pro.income(ts_code=ticker, fields='ts_code,end_date,total_revenue') total_revenue.drop_duplicates(subset=['ts_code','end_date'],keep='first',inplace=True) total_revenue.set_index('end_date', inplace=True) total_revenue_yrs = total_revenue.filter(like='1231', axis=0) total_revenue_yrs = total_revenue_yrs[total_revenue_yrs.index >= start_date]
#计算CAGR start_value = float(total_revenue_yrs.iloc[-1]['total_revenue']) end_value = float(total_revenue_yrs.iloc[0]['total_revenue']) num_periods = len(total_revenue_yrs['total_revenue']) cagr_y = cagr(start_value, end_value, num_periods)
result_dict['代码'] = ticker result_dict['股票名称'] = name result_dict['年复合增长率'] = cagr_y * 100 result_dict['周期'] = num_periods - 1 result_list.append(result_dict)
df = pd.DataFrame(result_list) df.sort_values(by='年复合增长率', ascending=False)
|
计算PEG
这里先说明一下,我这里的年复合增长率(g)
是基于营收增速,而不是净利润增速(上面引用段落中所提及)。
1 2 3 4 5
| pe = pro.daily_basic(trade_date='20210609', fields='ts_code,pe,pe_ttm, total_mv') peg_data = df.merge(pe, on=['ts_code']) peg_data['peg'] = peg_data['pe'].div(peg_data['年复合增长率']) peg_data['peg_ttm'] = peg_data['pe_ttm'].div(peg_data['年复合增长率']) peg_data.sort_values(by='peg', ascending=False)
|
效果
github
代码文件已上传到github, 可以直接看效果。地址:chinobing/cnvar.cn-source-code