选股策略
1)以中证500指数为股票池
2)用9个指标信号对所有股票进行评分
3)获取得分最高的前十名
import tushare as ts
import pandas as pd
import datetime
from dateutil.relativedelta import relativedelta
import talib as tb
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()
df = pro.index_weight(index_code = '000905.SH', start_date = last_mon, end_date = today)
df1 = df.copy()
stocks = list(df1[['con_code'][0]])
len(stocks)
# SMA评价
# 获取每只股票的收盘价及MA
sma = [] #
macd = [] #
rsi = [] #
mfi = []
apo = [] #
willr = []
atr = [] #
boll = [] #
VR = [] #
for stock in stocks:
price = pro.daily(ts_code=stock, start_date= last_year , end_date=today)
price = price.set_index('trade_date')
price = price.sort_index(ascending = True)
# 如果close[-1] > MA5[-1] and MA5[-2] < MA10[-2] and MA5[-1] > MA10[-1] 为买入信号
NOW = price.close.values
SMA5 = tb.SMA(price.close.values, timeperiod=5)
SMA10 = tb.SMA(price.close.values, timeperiod=10)
if (NOW[-1] > SMA5[-1]) and (SMA5[-5] < SMA10[-5]) and (SMA5[-1] > SMA10[-1]):
sma.append(1)
else:
sma.append(0)
#2.MACD dif[-2] < dea[-2] and dif[-1] > dea[-1] 为买入信号
# 参数设置为12 26 9
dif,dea,bar = tb.MACD(price.close.values, fastperiod=12, slowperiod=26, signalperiod=9)
if (dif[-5] < dea[-5]) and (dif[-1] > dea[-1]):
macd.append(1)
else:
macd.append(0)
# RSI指标 RSI[-2] < 30 RSI[-1] > 30 为买入信号
rsi_value = tb.RSI(price.close.values, timeperiod=14)
if rsi_value[-5] < 30 and rsi_value[-1] > 30 :
rsi.append(1)
else:
rsi.append(0)
#MFI 资金流量指标 MFI[-2] < 20 and MFI[-1] > 20 为买入信号
mfi_value = tb.MFI(price.high.values, price.low.values, price.close.values, price.vol.values, timeperiod=14)
if mfi_value[-5] < 20 and mfi_value[-1] > 20:
mfi.append(1)
else:
mfi.append(0)
#APO绝对价格振荡器 APO[-2] < 0 and APO[-1] > 0 为买入信号
apo_value = tb.APO(price.close.values,fastperiod=12,slowperiod=26,matype=0)
if apo_value[-5] < 0 and apo_value[-1] > 0:
apo.append(1)
else:
apo.append(0)
#WILLR(威廉指标) WILLR[-2] > 80 and WILLR[-1] < 80 为买入信号
willr_value = tb.WILLR(price.high.values,price.low.values,price.close.values, timeperiod=14)
if willr_value[-5] < -80 and willr_value[-1] > -80:
willr.append(1)
else:
willr.append(0)
# ATR 近半年线性回归角度为 < 10 and ATR值 > 3为买入信号
# BOLL 近半年线性回归角度为正值 > 3的, close[-2] < lowerband and close[-1] > lowerband为买入信号
a_price = price.close.values
atr_value = tb.ATR(price.high.values,price.low.values,price.close.values, timeperiod=14)
# 布林带突破
upperband, middleband, lowerband = tb.BBANDS(a_price, timeperiod=5, nbdevup=2, nbdevdn=2, matype=0)
if atr_value[-1] > 2:
atr.append(1)
else:
atr.append(0)
if NOW[-5] < lowerband[-5] and NOW[-1] > lowerband[-1]:
boll.append(1)
else:
boll.append(0)
# VR量比 VR[-1] > 1 为买入信号
VR_df = pro.daily_basic(ts_code = stock,start_date = Lastweek,end_date = today,fields='ts_code,trade_date,volume_ratio')
VR_df = VR_df.head(1)
if VR_df[['volume_ratio'][0]][0] > 1:
VR.append(1)
else:
VR.append(0)
df1['sma'] = sma
df1['macd'] = macd
df1['rsi'] = rsi
df1['mfi'] = mfi
df1['apo'] = apo
df1['willr'] = willr
df1['atr'] = atr
df1['boll'] = boll
df1['VR'] = VR
# 将各指标得分汇总
df1['score']=df1['sma']+df1['macd']+df1['rsi']+df1['mfi']+df1['apo']+df1['willr']+df1['atr']+df1['boll']+df1['VR']
# 按照得分降序排列取前10名
list_df1 = df1.sort_values(by = 'score',ascending = False).head(10)
list_df1 = list_df1.loc[:,['con_code','trade_date','weight','score']]
print(list_df1)
输出结果为: