背景
目标: 选取中证100指数中(000903.SH) 估值较低的股票
要求:
- 行业中性,在各行业中挑选低估值股票
- 使用烟蒂系数(PE*PB)筛选
- 兼顾股票成长性
工具准备:
注册Tushare账户,完善资料,获取积分,参考接口文档.475582
注册地址:Tushare账号注册
实操
Step1: 数据准备
- 获取中证100指数成分股的stock_code
hs300_ele = pro.index_weight(**{
"index_code": "000903.SH"
}, fields=[
"index_code",
"con_code",
"trade_date",
"weight"
])['con_code'].tolist()
- 获取成分股的行业信息
stock_basics = pro.stock_basic(**{}, fields=[
"ts_code",
"name",
"industry"
])
data_industry = stock_basics.loc[stock_basics['ts_code'].isin(hs300_ele),
['ts_code', 'name', 'industry']]
- 获取财务指标
data_p = pd.DataFrame(columns=['ts_code', 'pb', 'pe', 'ps'])
for code in zz100:
ts_p = pro.daily_basic(**{
"ts_code": code,
"limit": "1"
}, fields=[
"ts_code",
"pb",
"pe",
"ps"
])
data_p = data_p.append(ts_p, ignore_index=True)
data_p
4 获取盈利数据
df_profit = pd.DataFrame(columns=['ts_code', 'eps', 'netprofit_margin', 'grossprofit_margin'])
for code in zz100:
profit = pro.fina_indicator(**{
"ts_code": code,
"limit": 1
}, fields=[
"ts_code",
"eps",
"roe",
"netprofit_margin",
"grossprofit_margin",
"netprofit_yoy"
])
df_profit = df_profit.append(profit, ignore_index=True)
df_profit.columns = ['ts_code', 'EPS', 'ROE', '净利率%', '毛利率%', '净利率增长率%']
round(df_profit, 2)
5 数据合并
from functools import reduce
# 数据合并
merge = lambda x,y: pd.merge(x, y, how='left', on='ts_code') #定义了merge函数;
data = reduce(merge, [data_industry, data_p, df_profit])
data.columns = ['ts_code','名称', '行业','PB','PE','PS', 'EPS', 'ROE', '净利率%', '毛利率%', '净利率增长率%']
data
最终得到如下数据:
Step2: 条件选股
- 计算估值系数,并筛选符合条件数据
data['估值系数'] = data['PE'] * data['PB']
data = round(data,2)
data_filtered = data.loc[(data['估值系数'] < 60) & (data['ROE'] > 5)]
print('筛选结果共 %d 只个股' % len(data_filtered)) # 筛选结果共 49 只个股
# 按选定字段对数据进行排序
data_filtered.sort_values(['估值系数'], ascending=True, inplace=True) # sort_values具体实战应用;
data_filtered.head(10)
- 按成长性分组排序
def map_func(x):
"""
作为 apply 函数的参数传入
:param x: df 中一行或一列数据,取决于 apply 函数的参数 axis
:return: 将每个计算结果组合,返回一个 series
"""
if x['ROE'] > 5:
return '高成长'
elif x['ROE'] >= 0:
return '低成长'
elif x['ROE'] < 0:
return '亏损'
# 根据 ROE 数据计算“成长性”
data['成长性'] = data.apply(map_func, axis=1)
data_grouped = data.groupby('成长性').apply(group_func)
data_grouped
3. 按行业分组排序
data_grouped = data.groupby('行业').apply(group_func)
data_grouped
至此,我们获得的一个初步的股票列表。可结合自身考虑选取个股,继续进行下一步分析。