选股策略:
1、以中证1000为股票池;
2、删除上市时间不足两年的股票;
3、删除掉创业板股票
4、使用concurrent.futures import ThreadPoolExecutor 对每只股票的趋势进行直线拟合,删除掉角度小于3°的股票
5、获取下列指标指标数据,turnover_rate_f换手率、volume_ratio量比、circ_mv流通市值、pb市净率、dv_ttm股息率。
6、求出每个指标列的平均值,将每个值与对应的平均值比较并评分。
7、获取按照得分降序排列的头部10名。
import tushare as ts
import pandas as pd
import numpy as np
import datetime
from dateutil.relativedelta import relativedelta
from time import sleep
from abupy import ABuRegUtil
today = datetime.datetime.today().strftime('%Y%m%d') #获取今天的年月日
lastday = datetime.datetime.today() - datetime.timedelta(days=1) #获取前一天数据
lastday = lastday.strftime('%Y%m%d')
last_year = datetime.datetime.today() - relativedelta(months=12) #获取前一年的日期
last_year = last_year.strftime('%Y%m%d') # 转换成STR
Lastweek = datetime.datetime.today() - datetime.timedelta(days=7) #获取前一周的日期
Lastweek = Lastweek.strftime('%Y%m%d') # 转换成STR
last_mon = datetime.datetime.today() - relativedelta(months=1) #获取前一月的日期
last_mon = last_mon.strftime('%Y%m%d') # 转换成STR
ts.set_token('you token')
pro=ts.pro_api()
# 1 以中证1000为股票池
df = pro.index_weight(index_code = '000852.SH', start_date = last_mon, end_date = today)
# 将获取的股票代码导出为列表
con_dex_list = df[['con_code'][0]].tolist()
# 删除上市时间不足两年的股票
# 获取两年前的日期 类型为时间戳
now = datetime.datetime.today()
Two_years_ago = datetime.datetime.today() - relativedelta(months=24)
Two_years_ago = Two_years_ago.strftime('%Y%m%d')
Two_years_ago
df1 = pd.DataFrame()
for stock in con_dex_list:
df2=pro.stock_basic(ts_code=stock,list_status='L',fields='ts_code,symbol,name,industry,market,list_date')
if df2[['list_date'][0]][0] < Two_years_ago:
df1 = df1.append(df2)
# 复制一个DataFrame
df3 = df1.copy(deep=True)
zz1000 = df3[['ts_code'][0]].tolist()
len(zz1000)
#为什么要加入这个循环,因为在执行remove()时候引起了下标的变化,可能会导致漏删,
#作者在仔细查看时发现至少要循环6次才能将列表中以30开头的股票才能移除干净
for label in range(10):
for i in zz1000:
if i >= '300000.SZ' and i <= '309999.SZ':
zz1000.remove(i)
len(zz1000)
stocks = []
for i in zz1000:
# 获取每只股票近一个月收盘价的走势
df4 = pro.daily(ts_code=i, start_date=last_mon, end_date= today, fields='ts_code,trade_date,close')
# 对收盘价进行计算趋势角度
deg = ABuRegUtil.calc_regress_deg(df4.close.values)
# 只获取大于3°的股票
if deg > 3.0:
stocks.append(i)
print(i)
len(stocks)
# volume_ratio 量比 低于平均值得一分 turnover_rate_f 换手率(自由流通股) 低于平均值得一分 pb 市净率(总市值/净资产)高于平均值得一分
# circ_mv流通市值 低于平均值得一分 dv_ttm股息率 高于平均值得一分
# 获取 stocks 中各股票的每日指标 start_date = Lastweek,end_date = today,
stocks_df = pd.DataFrame()
for i in stocks:
df5 = pro.daily_basic(ts_code = i,start_date = lastday,end_date = today,fields='ts_code,trade_date,volume_ratio,turnover_rate_f,circ_mv,pb,dv_ttm')
stocks_df = stocks_df.append(df5)
sleep(0.5)
stocks_df
# 更改列名
stocks_df = stocks_df.rename(columns={'ts_code':'股票代码','trade_date': '交易日期','volume_ratio':'量比','turnover_rate_f':'换手率','circ_mv':'流通市值','pb':'市净率','dv_ttm':'股息率'})
# 删除空值
stocks_df = stocks_df.dropna(axis=0, how='any')
stocks_df
# 求出每个列的平均值
hsl_mean = stocks_df[['换手率'][0]].mean()
lb_mean = stocks_df[['量比'][0]].mean()
sjl_mean = stocks_df[['市净率'][0]].mean()
gxl_mean = stocks_df[['股息率'][0]].mean()
ltsz_mean = stocks_df[['流通市值'][0]].mean()
#将各列转换成列表
hsl_list = list(stocks_df[['换手率'][0]])
lb_list = list(stocks_df[['量比'][0]])
sjl_list = list(stocks_df[['市净率'][0]])
gxl_list = list(stocks_df[['股息率'][0]])
ltsz_list = list(stocks_df[['流通市值'][0]])
# 评分
score = []
for i in range(len(stocks_df)):
n = 0
if hsl_list[i] < hsl_mean: n = n + 1
if lb_list[i] < lb_mean: n = n + 1
if sjl_list[i] > sjl_mean: n = n + 1
if gxl_list[i] > gxl_mean: n = n + 1
if ltsz_list[i] < ltsz_mean: n = n + 1
score.append(n)
# 将评分添加至DataFrame
stocks_df['得分'] = score
# 根据得分降序排列获取头部十名
stocks = stocks_df.sort_values(by = '得分',ascending = False).head(10)
# 导出前十名的股票代码成列表
by_stock = list(stocks[['股票代码'][0]])
print(by_stock)