コード例 #1
0
ファイル: TushareImpls.py プロジェクト: FreyYann/FactorManage
 def renew(cls,conn:sqlite3.Connection):
     trade_date = fapi.trade_cal('SSE', '20180101', datetime.datetime.now().strftime('%Y%m%d'),'1')
     MissingDates = [];
     lastDate = trade_date["date"].tolist()[-1]
     beginDate, endDate = None, None
     timespan = 0
     for date in tqdm(trade_date["date"],desc='正在自检日度行情...',ncols=80):
         is_exist = cls.probe(conn,trade_date=date)
         if(not is_exist):
             timespan += 1
             endDate=date
             if(not beginDate):
                 beginDate=date
             if(date == lastDate or timespan>100):
                 MissingDates.append((beginDate, endDate))
                 timespan = 0
                 beginDate, endDate = None, None
         elif(beginDate):
                 MissingDates.append((beginDate,endDate))
                 timespan = 0
                 beginDate,endDate = None,None
     if(MissingDates.__len__()>0):
         for bgdt,eddt in tqdm(MissingDates,desc='正在从tushare更新日度行情...',ncols=90):
             cls.get_data('',datetime.datetime.strptime(bgdt,'%Y%m%d')
                          ,datetime.datetime.strptime(eddt,'%Y%m%d')
                          ,conn)
     print('日度行情更新完毕!')
コード例 #2
0
ファイル: TushareImpls.py プロジェクト: FreyYann/FactorManage
 def renew(cls,conn:sqlite3.Connection):
     trade_date = fapi.trade_cal('SSE', '20180101', datetime.datetime.now().strftime('%Y%m%d'),'1')
     lastDate = trade_date["date"].tolist()[-1]
     trade_date.rename(columns = {'date':'trade_date'},inplace=True)
     print('正在自检股票每日基本面指标...')
     lacks = set(cls.probe(conn,trade_date[['trade_date']])['trade_date'])
     MissingDates = [];
     beginDate, endDate = None, None
     timespan = 0
     for date in trade_date["trade_date"]:
         is_exist = date not in lacks
         if(not is_exist):
             timespan += 1
             endDate=date
             if(not beginDate):
                 beginDate=date
             if(date == lastDate or timespan>200):
                 MissingDates.append((beginDate, endDate))
                 timespan = 0
                 beginDate, endDate = None, None
         elif(beginDate):
                 MissingDates.append((beginDate,endDate))
                 timespan = 0
                 beginDate,endDate = None,None
     if(MissingDates.__len__()>0):
         for bgdt,eddt in tqdm(MissingDates,desc='正在从tushare更新股票基本面指标...',ncols=90):
             cls.get_data('',datetime.datetime.strptime(bgdt,'%Y%m%d')
                          ,datetime.datetime.strptime(eddt,'%Y%m%d')
                          ,conn)
     print('基本面指标更新完毕!')
コード例 #3
0
ファイル: TushareImpls.py プロジェクト: FreyYann/FactorManage
 def apidata(cls, StockCode: str, starttime: datetime, endtime: datetime) -> pd.DataFrame:
     '''
     输入参数:starttime,endtime
     从tushare->daily接口中获取所有股票在某时间段内的行情
     .daily接口每分钟允许调用500次
     '''
     trade_date = fapi.trade_cal('SSE',starttime.strftime('%Y%m%d'),endtime.strftime('%Y%m%d'),'1')
     price_df = pd.DataFrame()
     for date in tqdm(trade_date["date"],desc='正在更新...',ncols=80):
         df = None
         num = 0
         while(df is None):
             try:
                 df = api.daily(trade_date=date)
                 num=0
             except Exception as e:
                 if(num<5):
                     num+=1
                     print(e)
                     print('通过tushare获取{date}日行情时出现异常,将进行第{num}次重试'.format(date=date,num=str(num)))
                 else:
                     print('更新日行情失败!')
                     raise e
         price_df = price_df.append(df)
     price_df["amount"] = price_df["amount"] * 1000; #tushare的交易额单位为(千元)
     return price_df
コード例 #4
0
ファイル: TushareImpls.py プロジェクト: d23rojew/FactorManage
 def renew(cls,conn:sqlite3.Connection,checkAll:bool=True):
     stocks = fapi.stockinfo()
     today = datetime.now().strftime('%Y%m%d')
     DF_dates = fapi.trade_cal('SSE','20100101',today,'1')['date']
     DF_dates = DF_dates if checkAll else DF_dates.tail(1)
     MissingDates = [];
     for stockcode,field in tqdm(list(stocks.iterrows()),desc="正在自检分钟行情...",ncols=90):
         begin_date = field['list_date']
         end_date = field['delist_date'] if field['delist_date'] is not None else '99999999'
         DF_dates4stock = DF_dates[(DF_dates>begin_date) & (DF_dates<=end_date)]
         beginDate, endDate = None, None
         for date in DF_dates4stock.values:
             timestr = datetime.strptime(date,'%Y%m%d').strftime('%Y-%m-%d') + ' 10:00:00'
             is_exist = cls.probe(conn,ts_code=stockcode,trade_time=timestr)
             if (not is_exist):
                 endDate = date
                 if (not beginDate):
                     beginDate = date
                 if (date == DF_dates4stock.values[-1]):
                     MissingDates.append((stockcode,beginDate, endDate))
                     beginDate, endDate = None, None
             elif (beginDate):
                 MissingDates.append((stockcode,beginDate, endDate))
                 beginDate, endDate = None, None
     if (MissingDates.__len__() > 0):
         for stockcode, bgdt, eddt in tqdm(MissingDates, desc='正在从tushare更新分钟行情...', ncols=90):
             cls.get_data(stockcode, datetime.strptime(bgdt, '%Y%m%d')
                          , datetime.strptime(eddt, '%Y%m%d')
                          , conn)
コード例 #5
0
ファイル: TushareImpls.py プロジェクト: FreyYann/FactorManage
 def apidata(cls, StockCode: str, starttime: datetime, endtime: datetime) -> pd.DataFrame:
     trade_date = fapi.trade_cal('SSE',starttime.strftime('%Y%m%d'),endtime.strftime('%Y%m%d'),'1')
     daily_basic = pd.DataFrame()
     for date in tqdm(trade_date["date"],desc='正在更新...',ncols=80):
         df = None
         num = 0
         while(df is None):
             try:
                 df = api.daily_basic(trade_date=date)
                 num=0
             except Exception as e:
                 if(num<5):
                     num+=1
                     print(e)
                     print('通过tushare获取{date}日股票基本面指标时出现异常,将进行第{num}次重试'.format(date=date,num=str(num)))
                 else:
                     print('更新日行情失败!')
                     raise e
         daily_basic = daily_basic.append(df)
     daily_basic["turnover_rate"] = daily_basic["turnover_rate"] / 100
     daily_basic["turnover_rate_f"] = daily_basic["turnover_rate_f"] / 100
     daily_basic["dv_ratio"] = daily_basic["dv_ratio"] / 100
     daily_basic["dv_ttm"] = daily_basic["dv_ttm"] / 100
     daily_basic["total_share"] = daily_basic["total_share"] * 10000
     daily_basic["float_share"] = daily_basic["float_share"] * 10000
     daily_basic["free_share"] = daily_basic["free_share"] * 10000
     daily_basic["total_mv"] = daily_basic["total_mv"] * 10000
     daily_basic["circ_mv"] = daily_basic["circ_mv"] * 10000
     return daily_basic
コード例 #6
0
 def getActiveModelStackFromDB(cls)->list:
     '''
     返回当日激活[即到了换仓周期]的模型列表(按模型预测期降序排列)
     :return:
     '''
     CalendarCount = fApi.trade_cal('SSE', cls.MODEL_BEGIN_DATE, datetime.now().strftime('%Y%m%d'), '1').__len__()
     sql = 'select Id,Model,Optimizor,ForcastPeriod from MultiFactorOptimizor where {CalendarCount}%ForcastPeriod=0 and IsInService=1 order by ForcastPeriod desc'
     cursor = fApi.conn.execute(sql.format(CalendarCount=CalendarCount))
     rst = cursor.fetchall()
     unziped = [(x[0],pickle.loads(gzip.decompress(x[1])),x[2],x[3]) for x in rst]
     return unziped
コード例 #7
0
 def reBase(self):
     #从表OrderBook和表Dividend中确定今日哪些订单关闭(在OrderBook中标记关闭行IsClosed=1)
     #随后将新的base载入本类中
     conn = fApi.conn
     CalendarCount = fApi.trade_cal('SSE',self.MODEL_BEGIN_DATE,datetime.now().strftime('%Y%m%d'),'1').__len__()
     sql = 'replace into OrderBook ' \
           '(Id,AdjDt,exp_ret,real_ret,IsClosed) ' \
           'select a.Id,a.AdjDt,a.exp_ret,a.real_ret,1 from OrderBook a left join MultiFactorOptimizor b ' \
           'on a.Id = b.Id and a.IsClosed=0 and {CalendarCount}%b.ForcastPeriod=0'.format(CalendarCount=CalendarCount)
     conn.execute(sql)
     conn.commit()
     self.getTopModelFromDB()
コード例 #8
0
    def __settleOrder(self,stockcode:str,dealprice:float,holdAmt:int,topModelPeriod:int):
        #被fire调用时执行
        #以股票交易价格作为已结模型的关闭仓位价格、新开模型的开仓价格,每只股票关闭时,尝试对OrderBook表、OrderBookDetail表登记实现损益
        #(这玩意不影响交易流程,但运行的时机和实际交易时机一致)

        #1.标记平仓行实际收益率real_ret
        #1.1 select出OrderBookDetail中所有待平仓行(所有已执行(即标记了开仓价及开仓后仓位),但未平仓,且指令源模型已到平仓时间的指令)
        #1.2 逐行循环,找出复权因子
        #1.3 计算实现平仓复权价与实现开仓复权价之间的收益率
        #1.4 记录收益率
        CalendarCount = fApi.trade_cal('SSE', self.MODEL_BEGIN_DATE, datetime.now().strftime('%Y%m%d'), '1').__len__()
        markCloseSql = 'select a.Id,a.AdjDt,a.stockcode,a.open_price from OrderBookDetail a ' \
                       'left join MultiFactorOptimizor b on a.Id=b.Id ' \
                       'where a.post_position is not null and a.real_ret is null' \
                       'and {CalendarCount}%b.ForcastPeriod=0 '.format(CalendarCount=CalendarCount)
        closeList = pd.read_sql_query(markCloseSql,fApi.conn)
        for k,v in closeList.iterrows():
            id,adjdt,stkcode,open_price = v
            openAdjFactor = fApi.quotes(stkcode,None,datetime.strptime(adjdt,'%Y%m%d'),1,'Adjfactor','d',None)['Adjfactor'].values[0]
            nowAdjFactor = fApi.quotes(stkcode,None,datetime.now()-timedelta(days=1),1,'Adjfactor','d',None)['Adjfactor'].values[0]
            openAdjPrice = open_price * openAdjFactor
            closeAdjPrice = dealprice * nowAdjFactor
            realRet = closeAdjPrice/openAdjPrice -1
            sql = 'replace into OrderBookDetail' \
              '(id, adjdt, stockcode, fore_position, adj_amount_plan, post_position_plan, post_position, open_price, exp_ret, real_ret)' \
              'select a.id, a.adjdt, a.stockcode, a.fore_position, a.adj_amount_plan, a.post_position_plan' \
              ', a.post_position, {dealprice}, a.exp_ret, {realRet}' \
              'from OrdeBookDetail a' \
              'where a.stockcode=\'{stockcode}\' and a.Id={Id} and a.AdjDt=\'{adjdt}\''.format(dealprice=dealprice,realRet=realRet,stockcode=stockcode,Id=id,adjdt=adjdt)
            fApi.conn.execute(sql)
        #2.标记开仓行的实际开仓价格和仓位(当前阶段,将现实仓位与计划仓位差异全归于顶层模型)
        #找出已下达但未执行(即未标记开仓价格和开仓后仓位)的指令,写入开仓价及开仓后仓位
        markOpenSql = 'replace into OrderBookDetail' \
              '(id, adjdt, stockcode, fore_position, adj_amount_plan, post_position_plan, post_position, open_price, exp_ret, real_ret)' \
              'select a.id, a.adjdt, a.stockcode, a.fore_position, a.adj_amount_plan, a.post_position_plan' \
              ', case when c.ForcastPeriod={topModelPeriod} then {holdAmt} else a.post_position_plan end' \
              ', {dealprice}, a.exp_ret, a.real_ret' \
              'from OrdeBookDetail a' \
              'left join OrderBook b on a.Id=b.Id and a.AdjDt=b.AdjDt' \
              'left join MultiFactorOptimozor c on a.Id=c.Id'\
              'where a.stockcode=\'{stockcode}\' and b.IsClosed=0 and a.post_position is null'.format(topModelPeriod=topModelPeriod,holdAmt=holdAmt,dealprice=dealprice,stockcode=stockcode)
        fApi.conn.execute(markOpenSql)
        fApi.conn.commit()
コード例 #9
0
ファイル: TushareImpls.py プロジェクト: FreyYann/FactorManage
 def apidata(cls, StockCode: str, starttime: datetime, endtime: datetime) -> pd.DataFrame:
     trade_date = fapi.trade_cal('SSE',starttime.strftime('%Y%m%d'),endtime.strftime('%Y%m%d'),'1')
     adjfactor_df = pd.DataFrame()
     for date in tqdm(trade_date["date"],desc='正在更新...',ncols=80):
         df = None
         num = 0
         while(df is None):
             try:
                 df = api.adj_factor(trade_date=date)
                 num=0
             except Exception as e:
                 if(num<5):
                     num+=1
                     print(e)
                     print('通过tushare获取{date}日行情时出现异常,将进行第{num}次重试'.format(date=date,num=str(num)))
                 else:
                     print('更新日行情失败!')
                     raise e
         adjfactor_df = adjfactor_df.append(df)
     return adjfactor_df
コード例 #10
0
ファイル: TushareImpls.py プロジェクト: d23rojew/FactorManage
 def apidata(cls, StockCode:Union[str,list] , starttime: datetime, endtime: datetime) -> pd.DataFrame:
     '''
     对stockcode列表和日期区间适当分块,通过多进程并发增加下载速度.
     Tips:
         a. 1日全市场分钟数据大概200MB,因此大批量下载时需分批调多次用该api,避免内存占用
         b. 由于原生tushare分钟行情Api仅支持单股票下载,在多股票、多时间点下载时尽量保留
         较长时间区间,在股票层面上分割
     '''
     if type(StockCode) is str:
         StockCode = [StockCode]
     DF_dates = fapi.trade_cal('SSE',starttime.strftime('%Y%m%d'),endtime.strftime('%Y%m%d'),'1')['date']
     span = 0
     split_dateSpan = []
     for i in range(DF_dates.__len__()):
         span += 1
         if(span==1):
             begin = DF_dates[i]
         if(span==33 or i == DF_dates.__len__()-1):#由于单次获取8000行限制,每次下载区间不超过33天
             split_dateSpan.append((begin,DF_dates[i]))
             span = 0
     downloadList = list(itertools.product(StockCode,split_dateSpan))
     rstList = []
     pool = ThreadPool()
     # pbar = tqdm(total=downloadList.__len__(), desc='正在分段下载分钟行情',ncols=90)
     def remindDone(df:pd.DataFrame):
         if (df is not None and df.__len__() > 0):
             rstList.append(df)
             # pbar.update(1)
     for job in downloadList:
         pool.apply_async(cls.singleDownLoadJob,args=(job,),callback=remindDone)
         time.sleep(60/500)
     pool.close()
     pool.join()
     res = pd.DataFrame()
     for df in rstList:
         res = res.append(df)
     return res