??三年前我還是大四的時候,一個寫完畢業(yè)論文的早晨無意發(fā)現(xiàn)了Tushare,發(fā)現(xiàn)很好用并一直使用到現(xiàn)在。推薦給大家。目前,Tushare可調(diào)取A股、港股、外匯、基金等多種金融數(shù)據(jù),十分全面好用。對于A股,其不光有每日的交易數(shù)據(jù)(開盤價、收盤價、最高價、最低價、漲幅、成交量等等日線數(shù)據(jù)),其還提供了基本面財務(wù)數(shù)據(jù)的調(diào)取,這對于自動化的財務(wù)報表分析極其重要。官網(wǎng):
Tushare。
??在使用Tushare調(diào)取數(shù)據(jù)時,有如下的坑需要注意。(此貼長期更新,新踩的坑會不斷添加)
避雷
數(shù)據(jù)順序
??對于時間序列的分析,不同的人對于數(shù)據(jù)順序有不同的喜好,但是一定要有個順序,搞錯的話就會出現(xiàn)“用后面的數(shù)據(jù)預(yù)測之前的結(jié)果”這種錯誤。我個人習(xí)慣將最早的數(shù)據(jù)放在0行,按時間順序不斷往后排。此處需要注意的是,直接按官網(wǎng)的示例調(diào)取數(shù)據(jù)后生成的dataframe數(shù)據(jù)是倒序的,如圖中trade_date列所示:  若想按時間順序從前到后排列,加上以下一行代碼即可:
dataframe = dataframe.iloc[:: -1]
個股停牌問題
??直接調(diào)取API返回的dataframe并不包含所有交易日,而是只包含這支股票上市交易的日期的數(shù)據(jù)。所以對于某些策略,有必要在使用數(shù)據(jù)前檢查是否包含停牌期。一個直觀但錯誤的解決方法是利用datetime去判斷dataframe中的上一個交易日是否是昨天或上周五,但是這個方法沒有考慮到法定節(jié)假日對于暫停交易的影響。 ??一個可行的方法是利用股指進行判斷,因為只要A股當天有交易股指就一定是有數(shù)據(jù)的。例如要判斷dataframe中上一行是否是上一個交易日的數(shù)據(jù),可以調(diào)取上證50指數(shù)的日線數(shù)據(jù),然后就相關(guān)行的trade_date列進行對比,代碼如下:
# 獲取交易日
# 以上證指數(shù)存在的日子作為有交易的日子
# 輸入:起始時間、結(jié)束時間
# 輸出:所有交易日期組成的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中對應(yīng)的位置,往前看x天,看dataframe中往前看x行對應(yīng)的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
復(fù)權(quán)問題
??使用ts.pro_api().daily調(diào)取的數(shù)據(jù)是未復(fù)權(quán)的,若需調(diào)取復(fù)權(quán)數(shù)據(jù),需要使用ts.pro_bar接口,需要注意的是該接口復(fù)權(quán)參數(shù)adj默認的也是未復(fù)權(quán),需要設(shè)置adj=”qfq”或adj=”hfq”來看是前復(fù)權(quán)還是后復(fù)權(quán)。
調(diào)取頻率問題
對于積分低的用戶(忘了多少了好像是2000)Tushare有調(diào)取頻率的限制,直接遍歷調(diào)API的話可能會因為頻率超過限制而報錯。若想對所有的股票數(shù)據(jù)進行遍歷的測試,需加入延時。如下:
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
'''
|