1. Tushare簡介1.1. 開源、免費版TushareTushare是一個免費、開源的python財經(jīng)數(shù)據(jù)接口包。主要實現(xiàn)對股票等金融數(shù)據(jù)從數(shù)據(jù)采集、清洗加工 到 數(shù)據(jù)存儲的過程,能夠為金融分析人員提供快速、整潔、和多樣的便于分析的數(shù)據(jù),為他們在數(shù)據(jù)獲取方面極大地減輕工作量,使他們更加專注于策略和模型的研究與實現(xiàn)上??紤]到Python pandas包在金融量化分析中體現(xiàn)出的優(yōu)勢,Tushare返回的絕大部分的數(shù)據(jù)格式都是pandas DataFrame類型,非常便于用pandas/NumPy/Matplotlib進行數(shù)據(jù)分析和可視化。當然,如果您習慣了用Excel或者關系型數(shù)據(jù)庫做分析,您也可以通過Tushare的數(shù)據(jù)存儲功能,將數(shù)據(jù)全部保存到本地后進行分析。
1.2. 注冊升級版 Tushare proPro版數(shù)據(jù)更穩(wěn)定質(zhì)量更好了,但Pro依然是個開放的,免費的平臺,不帶任何商業(yè)性質(zhì)和目的。 1.3. 獲取Tushare不管你是量化投資分析師,還是正在學習Python進行數(shù)據(jù)分析的學習者,這種方法獲取的數(shù)據(jù)都可以適用。 獲取前的準備: pip install tushare 2. 獲取數(shù)據(jù)我為了更方便的使用Tushare接口API,也為了兼容新、舊版本,設計類整合新版本。 2.1. 獲取歷史行情數(shù)據(jù)
本接口只能獲取近3年的日線數(shù)據(jù),適合搭配均線數(shù)據(jù)進行選股和分析。 輸入?yún)?shù)說明: |股票代碼|開始日期|結(jié)束日期|數(shù)據(jù)類型|
老版本中: 1.股票代碼,即6位數(shù)字代碼,或者指數(shù)代碼(sh=上證指數(shù) sz=深圳成指 hs300=滬深300指數(shù) sz50=上證50 zxb=中小板 cyb=創(chuàng)業(yè)板) 2.數(shù)據(jù)類型,D=日k線 W=周 M=月 5=5分鐘 15=15分鐘 30=30分鐘 60=60分鐘,默認為D 返回值說明:
老版本中date為index,不是具體column。 2.2. 獲取歷史行情數(shù)據(jù)——指數(shù)上證指數(shù)、深圳成指、滬深300指數(shù)、上證50 、中小板、創(chuàng)業(yè)板等。 上證指數(shù)代碼為“000001.SH”,老版本代碼為“sh”;深成指數(shù)代碼為“399001.SZ”,老版本為“399001”或“sz”。 #獲取滬深指數(shù) def get_hs_index(self,start_date,end_date): if self.pro: self.hs_index = ts.pro_bar(ts_code= self.code, asset='I', start_date=start_date, end_date=end_date) else: #舊接口,不用注冊 index_code={ '000001.SH':'sh','399001.SZ':'399001','000300.SH':'000016.SH','sz50':'sz50','399005.SZ':'zxb','399006.SZ':'cyb'} self.his_dat = ts.get_hist_data(code=index_code[self.code],start=start_date, end=end_date) #把索引賦值給trade_date #self.his_dat['trade_date'] = self.his_dat.index self.his_dat = self.his_dat.reset_index() self.his_dat['ts_code'] = self.code #參照pro接口,修改列名 self.his_dat = self.his_dat.rename(columns={ 'date':'trade_date','volume':'vol','price_change':'change','p_change':'pct_chg'}) #篩選列 self.his_dat = self.his_dat[self.columns] #.reset_index() return self.hs_index 2.3. 獲取歷史行情數(shù)據(jù)——情緒指數(shù)目前pro版本國外已經(jīng)支持如下指數(shù)數(shù)據(jù)(數(shù)據(jù)來源:https:///):
使用方法:
2.4. 獲取分時數(shù)據(jù)升級pro版本,可以獲取3年的數(shù)據(jù),而老版本 只能獲取1個月的分時數(shù)據(jù)。 #獲取分鐘級別數(shù)據(jù) def get_tickshare_dat(self,freq,start_date, end_date): if self.pro: start_date=re.sub('\D','',start_date) end_date = re.sub('\D','',end_date) freq = freq + 'min' self.tickshare_dat = ts.pro_bar(ts_code=self.code, freq = freq,start_date=start_date, end_date=end_date) self.tickshare_dat['vol'] = self.tickshare_dat['vol'] /100 else: # ktype:數(shù)據(jù)類型,D=日k線 W=周 M=月 5=5分鐘 15=15分鐘 30=30分鐘 60=60分鐘,默認為D self.tickshare_dat = ts.get_hist_data(code=self.code, ktype = freq,start=start_date, end=end_date) self.tickshare_dat['ts_code'] = self.code self.tickshare_dat = self.tickshare_dat.reset_index() self.tickshare_dat = self.tickshare_dat.rename(columns={ 'date':'trade_time','volume':'vol'}) self.tickshare_dat['trade_date'] = self.tickshare_dat['trade_time'].apply(lambda x:re.sub('\D','',x[0:10])) self.setCodebyOld() self.tickshare_dat['ts_code'] = self.code self.tickshare_dat = self.tickshare_dat[['ts_code','trade_time','open','high','close','low','vol','trade_date']] return self.tickshare_dat注:輸入freq為字符型數(shù)字,1/5/15/30/602.5. 獲取股票基本信息#獲取股票基本面信息 def get_ShareInfo(self,trade_date): if self.pro: self.shareInfo = self.stock.daily_basic(ts_code=self.code, trade_date=trade_date) #, fields='ts_code,trade_date,turnover_rate,volume_ratio,pe,pb') else: self.shareInfo = ts.get_stock_basics() print(self.shareInfo)2.6. 獲取復權數(shù)據(jù)# 獲取復權數(shù)據(jù) def get_h_dat(self,start_date,end_date,fq='hfq'): #self.h_dat = ts.get_h_data(code=self.code, autype='hfq',start=start_date, end=end_date) self.h_dat = ts.pro_bar(ts_code=self.code, adj=fq, start_date=start_date, end_date=end_date) return self.h_dat3. 數(shù)據(jù)存儲在本地Mongo數(shù)據(jù)庫中class Stock_Collection(object): def __init__(self,db_name): self.db_name = db_name client = pymongo.MongoClient('mongodb://stock:stock@localhost:27017/stock') self.db = client[self.db_name] def insertdatas(self,name,datas): collection = self.db[name] collection.insert(json.loads(datas.T.to_json()).values()) def getDistinctCode(self,name): collection = self.db[name] code = collection.distinct('ts_code') return code def setIndex_Code(self): self.sentiment_index = ['IXIC','DJI','HSI'] # 情緒指數(shù) self.sentiment_index_column = ['trade_date','open','high','close','low','change','pct_chg'] self.index_daily = ['000001.SH', '399001.SZ'] self.index_daily_column = ['trade_date','open','high','close','low','vol','change','pct_chg'] def setCode(self,code): self.code = code #['002230.SZ'] #, '000547.SZ', '601318.SH', '601208.SH', '600030.SH', '000938.SZ', '002108.SZ', '600967.SH'] self.stock_column = ['trade_date','open','high','close','low','vol','change','pct_chg'] # 構造LSTM模型訓練集 def generate_train_datas(self,db_name,code_name,filename): collection = self.db[db_name] self.out_code = code_name #查詢條件“字典” query_dict = { 'ts_code':'1','trade_date':{ '$gt':'20171001'}} #col_name = {'_id':0,'trade_date':1,'ts_code':1,'open':1,'high':1,'close':1,'low':1,'vol':1,'change':1,'pct_chg':1} col_name = { '_id':0} for d in self.stock_column: col_name[d] = 1 query_dict['ts_code'] = self.out_code #注意時間排序 df = pd.DataFrame(list(collection.find(query_dict,col_name).sort([('trade_date',1)]))) df['trade_date'] = df['trade_date'].apply(lambda x:re.sub('\D','',x)) #去掉日期中的“-”符號 self.code.remove(self.out_code) # 刪除輸出股票代碼 #構造股票數(shù)據(jù)集 n = 0 k = 0 columns = self.stock_column.copy() columns.remove('trade_date') print('Start!') #self.code長度為1,下面循環(huán)不執(zhí)行 for code in self.code: query_dict['ts_code'] = code df1 = pd.DataFrame(list(collection.find(query_dict,col_name).sort([('trade_date',1)]))) df1['trade_date'] = df1['trade_date'].apply(lambda x:re.sub('\D','',x)) #去掉日期中的“-”符號 #按日期合并兩個表 #df =pd.merge(left=df,right=df1,how='left',on=['trade_date']) #以上證為基準 df =pd.merge(left=df,right=df1,how='inner',on=['trade_date']) # 處理合并表,字段重復的情況,需要把_x,_y新命名字段,下輪繼續(xù) cols_dict = { } for cols in columns: cols_dict[cols+'_x'] = cols + str(n) cols_dict[cols+'_y'] = cols + str(n+1) if k==0: df = df.rename(columns=cols_dict) n = n + 2 k = 1 else: k = 0 print('code 1') print(df) #構造數(shù)據(jù)集——上證、深成指數(shù) query_dict = { 'ts_code':'1'} columns = self.index_daily_column.copy() #默認list為傳址,需要賦值新list columns.remove('trade_date') print(self.index_daily_column) for index_daily in self.index_daily: query_dict['ts_code'] = index_daily col_name = { '_id':0} for d in self.index_daily_column: col_name[d] = 1 df1 = pd.DataFrame(list(collection.find(query_dict,col_name).sort([('trade_date',1)]))) df1['trade_date'] = df1['trade_date'].apply(lambda x:re.sub('\D','',x)) #去掉日期中的“-”符號 #按日期合并兩個表 df =pd.merge(left=df,right=df1,how='left',on=['trade_date']) cols_dict = { } for cols in columns: cols_dict[cols+'_x'] = cols + str(n) cols_dict[cols+'_y'] = cols + str(n+1) if k==0: df = df.rename(columns=cols_dict) n = n + 2 k = 1 else: k = 0 print(df) #構造數(shù)據(jù)集——情緒指數(shù) columns = self.sentiment_index_column.copy() columns.remove('trade_date') for sentiment_index in self.sentiment_index: query_dict['ts_code'] = sentiment_index col_name = { '_id':0} for d in self.sentiment_index_column: col_name[d] = 1 df1 = pd.DataFrame(list(collection.find(query_dict,col_name).sort([('trade_date',1)]))) df1['trade_date'] = df1['trade_date'].apply(lambda x:re.sub('\D','',x)) #去掉日期中的“-”符號 #按日期合并兩個表 df =pd.merge(left=df,right=df1,how='left',on=['trade_date']) cols_dict = { } for cols in columns: cols_dict[cols+'_x'] = cols + str(n) cols_dict[cols+'_y'] = cols + str(n+1) df = df.rename(columns=cols_dict) if k==0: df = df.rename(columns=cols_dict) n = n + 2 k = 1 else: k = 0 print(df) df = df.fillna(0) #數(shù)據(jù)缺失補上為0,相當于停盤?。。? df.to_csv(filename) |
|