三年前我还是大四的时候,一个写完毕业论文的早晨无意发现了Tushare,发现很好用并一直使用到现在。推荐给大家。目前,Tushare可调取A股、港股、外汇、基金等多种金融数据,十分全面好用。对于A股,其不光有每日的交易数据(开盘价、收盘价、最高价、最低价、涨幅、成交量等等日线数据),其还提供了基本面财务数据的调取,这对于自动化的财务报表分析极其重要。官网:
Tushare。
在使用Tushare调取数据时,有如下的坑需要注意。(此贴长期更新,新踩的坑会不断添加)
避雷
数据顺序
对于时间序列的分析,不同的人对于数据顺序有不同的喜好,但是一定要有个顺序,搞错的话就会出现“用后面的数据预测之前的结果”这种错误。我个人习惯将最早的数据放在0行,按时间顺序不断往后排。此处需要注意的是,直接按官网的示例调取数据后生成的dataframe数据是倒序的,如图中trade_date列所示:  若想按时间顺序从前到后排列,加上以下一行代码即可:
dataframe = dataframe.iloc[:: -1]
个股停牌问题
直接调取API返回的dataframe并不包含所有交易日,而是只包含这支股票上市交易的日期的数据。所以对于某些策略,有必要在使用数据前检查是否包含停牌期。一个直观但错误的解决方法是利用datetime去判断dataframe中的上一个交易日是否是昨天或上周五,但是这个方法没有考虑到法定节假日对于暂停交易的影响。 一个可行的方法是利用股指进行判断,因为只要A股当天有交易股指就一定是有数据的。例如要判断dataframe中上一行是否是上一个交易日的数据,可以调取上证50指数的日线数据,然后就相关行的trade_date列进行对比,代码如下:
# 获取交易日
# 以上证指数存在的日子作为有交易的日子
# 输入:起始时间、结束时间
# 输出:所有交易日期组成的list
def Get_Trading_Date(startDate, endDate):
ts.set_token("###################################")
dataframe = ts.pro_bar(ts_code= "000001.SH", asset= "I", start_date= startDate, end_date= endDate)
dataframe = dataframe.iloc[::-1]
dataframe.reset_index(drop= True, inplace= True)
tradingDays = dataframe["trade_date"].values.tolist()
return tradingDays
# 检查x天前是否是停牌的
# 查找今天在tradingDays中对应的位置,往前看x天,看dataframe中往前看x行对应的date是否与这个真实的date一致
# 输入:dataframe、row、几天前、trading days list
# 输出:Boolean,停牌返回False
def Suspension_Check(dataframe, row, nDays, tradingDays):
today = dataframe.loc[row, "trade_date"]
trueLastTradingDate = tradingDays[tradingDays.index(today) - nDays]
stockLastTradingDate = dataframe.loc[row - nDays, "trade_date"]
if stockLastTradingDate == trueLastTradingDate :
return True
else:
return False
复权问题
使用ts.pro_api().daily调取的数据是未复权的,若需调取复权数据,需要使用ts.pro_bar接口,需要注意的是该接口复权参数adj默认的也是未复权,需要设置adj=”qfq”或adj=”hfq”来看是前复权还是后复权。
调取频率问题
对于积分低的用户(忘了多少了好像是2000)Tushare有调取频率的限制,直接遍历调API的话可能会因为频率超过限制而报错。若想对所有的股票数据进行遍历的测试,需加入延时。如下:
import timeit
import time
def Get_Stock(stockCode, startTime, endTime, timeStamp):
timeDelta = timeit.default_timer() - timeStamp
if timeDelta < 0.2 :
time.sleep(0.2 - timeDelta)
ts.set_token("##########################")
dataframe = ts.pro_bar(ts_code= stockCode, start_date= startTime, end_date= endTime, adj="qfq")
timeStamp = timeit.default_timer()
return dataframe, timeStamp
timeStamp = timeit.default_timer()
for i in stock_code_list :
dataframe, timeStamp = Get_Stock(i, startTime, endTime, timeStamp)
'''
run your algorithm here
'''
|