使用Tushares 数据选股

626 阅读2分钟

背景

目标: 选取中证100指数中(000903.SH) 估值较低的股票

要求:

  1. 行业中性,在各行业中挑选低估值股票
  2. 使用烟蒂系数(PE*PB)筛选
  3. 兼顾股票成长性 工具准备:
    注册Tushare账户,完善资料,获取积分,参考接口文档. 475582

注册地址:Tushare账号注册

实操

Step1: 数据准备

  1. 获取中证100指数成分股的stock_code
hs300_ele = pro.index_weight(**{
    "index_code": "000903.SH"
}, fields=[
    "index_code",
    "con_code",
    "trade_date",
    "weight"
])['con_code'].tolist()
  1. 获取成分股的行业信息
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']]
  1. 获取财务指标
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: 条件选股

  1. 计算估值系数,并筛选符合条件数据
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)

  1. 按成长性分组排序
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

至此,我们获得的一个初步的股票列表。可结合自身考虑选取个股,继续进行下一步分析。