这是2020年暑假自己调用tushare金融数据库,针对A股市场上所有股票的历史数据,使用“追跌卖涨”的思路编写的一份股票筛选程序,遍历可获得的所有股票数据,输出可以购买的股票组合的名单。代码分为两个部分,一个是策略代码,另外一个是自编的调用的模块代码,如下:
# -*- coding: utf-8 -*-
"""
Created on Mon Aug 31 09:59:41 2020
@author: Tang Shiyu
@e-mail: 1471988744@qq.com
"""
"""
strategy_1.3版本升级说明
编写了get_available_stock函数,将原股票列表中的贵的,买不了的股票删掉
"""
import tool_functions as tf
today = tf.get_today_date()
ago = tf.get_ago_date(15)
import tushare as ts
import my_token
ts.set_token(my_token.tsy_token)
pro = ts.pro_api(my_token.tsy_token)
t0 = tf.get_time()
#查询当前所有正常上市交易的股票列表
'''
exchange为指定的交易所,交易所 SSE上交所 SZSE深交所 HKEX港交所(未上线)
list_status 上市状态: L上市 D退市 P暂停上市,默认L
is_hs是否沪深港通标的,N否 H沪股通 S深股通
fields='ts_code,symbol,name,area,industry,list_date'
'''
all_stocks = pro.stock_basic(exchange='', list_status='L', fields='ts_code,name')
stock_list=[]
for i_1 in range(len(all_stocks["ts_code"])):
single_stock = pro.daily(ts_code=all_stocks['ts_code'][i_1], start_date=ago, end_date=today)
try:
test_key = single_stock.loc[0,"open"]
except KeyError:
continue
else:
single_stock["single_label"] = ""
for i in range(len(single_stock["single_label"])):
if single_stock["change"][i] < 0:
single_stock["single_label"][i] = 1#注意,下跌标记为1,不变和上涨标记为0
else:
single_stock["single_label"][i] = 0
groups = single_stock.groupby('single_label')
counts = groups.size()
try:
counts[0] <= counts[1]#<是跌多涨少,>是涨多跌少
except KeyError:
continue
else:
if 4*counts[0] < counts[1]:#<是跌多涨少,>是涨多跌少
stock_list.append(all_stocks['ts_code'][i_1])
"""
1.1版本主要更新部分
"""
"""
#考虑到中国平安上次停牌还是在2014年,这里就以中国平安为基准
shai_over_day = tf.get_today_date()
shai_begin_day =tf.get_ago_date(30)
jz_stock = pro.daily(ts_code="000001.SZ", start_date=shai_begin_day, end_date=shai_over_day)
normal_day = jz_stock.shape[0]#获取了正常交易的天数
stock_list_1_1 = []
for i_2 in stock_list:
single_stock = pro.daily(ts_code=i_2, start_date=shai_begin_day, end_date=shai_over_day)
try:
test_key = single_stock.loc[normal_day-1,"open"]
except KeyError:
continue
else:
stock_list_1_1.append(i_2)
"""
#获取这一个月正常交易的股票
nor_stock_list = tf.get_nor_stock(stock_list, ago, today)
#获取能买的股票
ava_stock_list = tf.get_available_stock(nor_stock_list, 10, today)
print(ava_stock_list)
#储存结果
import json
filename = "ava_stock_list_strategy_1.3.json"
with open (filename,"w") as f_object:
json.dump(stock_list,f_object)
#读取程序运行时间
t1 = tf.get_time()
tf.get_run_time(t1-t0)
下面是需要调用的模块代码,命名为tool_functions:
# -*- coding: utf-8 -*-
"""
Created on Wed Aug 26 17:07:50 2020
@author: Tang Shiyu
@e-mail: 1471988744@qq.com
"""
def get_today_date():
"""获取系统时间,返回字符串形式当前日期"""
import time
#获取今天的日期
today = time.strftime("%Y%m%d", time.localtime())
return today
def get_ago_date(num_day):
"""给定向前推的天数,返回那一天的日期"""
import datetime
now_time = datetime.datetime.now()
yes_time = now_time + datetime.timedelta(days=float(-num_day))#这里的数字决定向前取多少天
ago = yes_time.strftime('%Y%m%d')
return ago
def get_newest_trade_day(day):
"""
给定一个日期,获取离该日期最新的一个交易日,注意本函数最早调用到20100101
"""
import tool_functions as tf
import my_token
import tushare as ts
import pandas as pd
ts.set_token(my_token.tsy_token)
pro = ts.pro_api(my_token.tsy_token)
jz_stock = pro.daily(ts_code="000001.SZ", start_date="20100101", end_date = day)
return jz_stock.loc[0,"trade_date"]
def get_time():
"""计算程序运行时间的方法是在程序的开头和结尾各插入两个time函数,计算程序
读取这两个函数的时间差便是这次程序运行的时间"""
import time
t0=time.time()
print('读时:',time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))
return t0
def get_run_time(subtract):
'''承接上一个函数'''
print("用时:%.6fs"%(subtract))
def get_por(stock_list,por_begin_day,por_over_day):
"""
编写一个函数,使其能够接受一个股票代码的列表,与起始日期和终止日期,
就能够生成一个组合,包含交易日与每天的开盘价与收盘价等相关信息
Parameters
----------
stock_list : TYPE:list
构成组合的个股股票代码.
por_begin_day : TYPE:str
组合的起始日期.
por_over_day : TYPE:str
组合的结束日期.
Returns
-------
hq_por : TYPE:dataframe
返回一个dataframe,包含组合的交易日,开盘价、前一日收盘价、收盘价
每日涨跌幅(收盘价之间)、涨跌百分比(收盘价之间).
"""
import tool_functions as tf
import my_token
import json
import tushare as ts
import pandas as pd
ts.set_token(my_token.tsy_token)
pro = ts.pro_api(my_token.tsy_token)
#从一个上市股票的行情中把日期切出来
hq_get_date = pro.daily(ts_code="000001.SZ", start_date=por_begin_day, end_date=por_over_day)
#在开盘前选股,开盘后立即买入,成交价格以开盘价格计算
#获取组合的开盘行情
hq_open = hq_get_date[["trade_date"]]
for item in stock_list:
hq_open_1 = pro.daily(ts_code=item, start_date=por_begin_day, end_date=por_over_day)
hq_open_1 = hq_open_1[['trade_date',"open"]]
hq_open_1.rename(columns = {"open": "open"+item}, inplace=True)
hq_open = pd.merge(hq_open, hq_open_1,on='trade_date')
#计算组合开盘价
num_stocks = len(stock_list)
hq_open['por_open'] = hq_open.iloc[:,1:num_stocks].sum(axis=1)
hq_open = hq_open[["trade_date","por_open"]]
#获取组合前一日收盘行情
hq_pre_close = hq_get_date[["trade_date"]]
for item in stock_list:
hq_pre_close_1 = pro.daily(ts_code=item, start_date=por_begin_day, end_date=por_over_day)
hq_pre_close_1 = hq_pre_close_1[['trade_date',"pre_close"]]
hq_pre_close_1.rename(columns = {"pre_close": "pre_close"+item}, inplace=True)
hq_pre_close = pd.merge(hq_pre_close, hq_pre_close_1,on='trade_date')
#计算组合前一日收盘价
num_stocks = len(stock_list)
hq_pre_close['por_pre_close'] = hq_pre_close.iloc[:,1:num_stocks].sum(axis=1)
hq_pre_close = hq_pre_close[["trade_date","por_pre_close"]]
#获取组合收盘行情
hq_close = hq_get_date[["trade_date"]]
for item in stock_list:
hq_close_1 = pro.daily(ts_code=item, start_date=por_begin_day, end_date=por_over_day)
hq_close_1 = hq_close_1[['trade_date',"close"]]
hq_close_1.rename(columns = {"close": "close"+item}, inplace=True)
hq_close = pd.merge(hq_close, hq_close_1,on='trade_date')
#计算组合收盘价
num_stocks = len(stock_list)
hq_close['por_close'] = hq_close.iloc[:,1:num_stocks].sum(axis=1)
hq_close = hq_close[["trade_date","por_close"]]
#将开盘行情、前一日收盘行情和收盘行情合并
hq_por = pd.merge(hq_open, hq_pre_close,on='trade_date')
hq_por = pd.merge(hq_por, hq_close,on='trade_date')
#计算组合每日涨跌,注意是收盘价之差
hq_por["por_chg"] = hq_por["por_close"] - hq_por["por_pre_close"]
#计算组合的每日百分比涨跌幅
hq_por["por_pct_chg"] = round(((hq_por["por_close"] - hq_por["por_pre_close"])/hq_por["por_pre_close"])*100,2)
return hq_por
def get_nor_stock(stock_list,begin_day,end_day):
"""
本函数获取一个列表,筛选出其中给定时间段完全正常交易的股票
Parameters
----------
stock_list : list
给出你要筛选的股票列表
begin_day : str
字符串形式的日期如20200830
end_day : list
同上
Returns
-------
返回给定时间段完全正常交易的股票列表
"""
import tushare as ts
import my_token
ts.set_token(my_token.tsy_token)
pro = ts.pro_api(my_token.tsy_token)
jz_stock = pro.index_daily(ts_code='000300.SH', start_date=begin_day, end_date=end_day)
normal_day = jz_stock.shape[0]#获取了正常交易的天数
nor_stock_list = []
for i in stock_list:
single_stock = pro.daily(ts_code=i, start_date=begin_day, end_date=end_day)
try:
test_key = single_stock.loc[normal_day-1,"open"]
except KeyError:
continue
else:
nor_stock_list.append(i)
return nor_stock_list
def get_available_stock(stock_list,pri,shai_xuan_day):
"""
接受一个股票列表,对其做以下筛选.1、筛除创业版股票;2、筛除科创板股票;
3、筛除筛选日价格过高的股票
Parameters
----------
stock_list : LIST
接收一个股票列表.
pri : FLOAT
你能接受的股票最高价格.
shai_xuan_day : STR
字符串形式的日期
Returns LIST
-------
返回筛选后的股票列表.
"""
import tool_functions as tf
import tushare as ts
import my_token
ts.set_token(my_token.tsy_token)
pro = ts.pro_api(my_token.tsy_token)
ava_stock_1 = []
for i in stock_list:
if i[0:3] != "688" and i[0:3] !="300":
ava_stock_1.append(i)
ava_stock = []
#保留筛选日价格没有超过了给定价格的股票
for i_2 in ava_stock_1:
single_stock = pro.daily(ts_code=i_2, trade_date = tf.get_newest_trade_day(shai_xuan_day))
if single_stock.loc[0,"close"] < pri:
ava_stock.append(i_2)
return ava_stock