今天在学习策略开发的时候发现一个问题,下面这张是获取的股票数据
可以看出日期是按照降序进行排列的,这对后期策略的开发不是很友好。当然如果在读取数据后再进行升序的处理也是可以的哈,不过我个人是比较倾向于,在保存数据的时候就将这一步解决。另外这次顺便提升一下股票更新的性能。
那么先来解决第一步,其实很简单对获取的数据进行升序排列就行,pandas的sort_values可以完美实现这一功能。
df = pd.read_csv(r'G:\PycharmProjects\DeltaTrader\data\data_tushare\600515.SH.csv',index_col=0)
df.sort_values(['trade_date'], inplace=True)
print(df)
这里我是直接读取文件进行降序,那么接下来结合multiprocessing模块实现多线程下载股票,并按日期将进行降序排列。
另外在实际操作的过程中发现,线程池创建的任务不能是内嵌函数,所有得单独定义获取并保存股票数据的函数。
def update_single_stock(code, init_db=False):
'''
更新单只股票的数据
:param code:
:param init_db:
:return:
'''
# 是否初始化股票数据
if init_db:
df = ts.pro_bar(ts_code=code, asset='E', start_date='20050101')
# 按时间降序排列
df.sort_values(['trade_date'], inplace=True)
df.to_csv(r'G:\PycharmProjects\DeltaTrader\data\data_tushare\{}.csv'.format(code), index=False)
else:
df = ts.pro_bar(ts_code=code, asset='E', start_date=start_date)
df.sort_values(['trade_date'], inplace=True) # 按时间进行降序排列
df.to_csv(r'G:\PycharmProjects\DeltaTrader\data\data_tushare\{}.csv'.format(code), index=False,
header=False,
mode='a')
然后将之前用于股票下载的函数中创建线程池即可
def update_all_stock():
'''
按照配置文件最后更新日期最近更新,如果不存在就初始化所有股票
:return:
'''
# 获取本地股票列表
update_stock_list()
stock_list = pd.read_csv(
r'G:\PycharmProjects\DeltaTrader\data\finance\{}_tss.csv'.format(datetime.date.today()),
index_col=0, usecols=['ts_code'])
# 创建线程池 并生成股票代码迭代器
pool = Pool(4)
code_list = (code for code in stock_list.index)
try:
# 读取配置文件
with open(r'G:\PycharmProjects\DeltaTrader\data\data_tushare\更新日期.txt', 'rb') as file:
# 获取更新记录
data = file.read()
record = pickle.loads(data)
date = record['更新日期']
# 如果配置文件不存在初始化股票数据
except Exception as e:
print(e)
# 生成配置文件
file = open(r'G:\PycharmProjects\DeltaTrader\data\data_tushare\更新日期.txt', 'wb+')
date = {'更新日期': str(datetime.date.today())}
record = pickle.dumps(date)
file.write(record)
file.close()
# 初始化股票列表
print('----start----')
t_start = time.time()
for code in code_list:
pool.apply_async(update_single_stock, (code, True))
# 关闭进程池
pool.close()
pool.join()
return print('----end----')
# 判断是否不是最新日期
end_date = datetime.datetime.strptime(date, '%Y-%m-%d')
if not(end_date.date() == datetime.datetime.today().date()):
print('开始更新股票数据至最新日期')
# 更新至最新日期
start_date = end_date + datetime.timedelta(1)
start_date = str(start_date.date())
print('----start----')
t_start = time.time()
for code in code_list:
pool.apply_async(update_single_stock, (code, True, start_date))
# 关闭进程池
pool.close()
pool.join()
print('----end----')
# 记录更新日期
with open(r'G:\PycharmProjects\DeltaTrader\data\data_tushare\更新日期.txt', 'wb') as file:
date = {'更新日期': start_date}
record = pickle.dumps(date)
file.write(record)
print('完成股票数据更新')
这里我创建了4个进程,相比之前效率提升了100%以上。
另外需要提醒的是,tushare的每日行情好像是收盘后一个小时更新,建议更新本地数据时,在当日晚些时候进行更新。