def loading_data(self, platform): # parse the datasetting #self.datainfo = self.params['data_setting'] self.Parse_datasetting() # loading bar data period: 1 day self.getdata_utl = HdfUtility() # create the our datafeed CTA_datafeed_name = 'CTA_datafeed'.encode('utf-8') # if you have other data form, change the bt.feeds.pandafeed to your favour # you must cancel the lines in the dataserise or the lines will be overlap self.CTA_datafeed = type(CTA_datafeed_name.decode(), (bt.feeds.PandasData, ), { 'lines': self.lines, 'params': self.data_params }) # 判断需要加载哪些类型的数据,dom ?, subdom?, rawdata? # 是否加载主力合约数据 if self.datainfo['loading_datatype']['domdata']: self.load_domdata(platform) # 是否加载次主力合约数据 if self.datainfo['loading_datatype']['subdomdata']: self.load_subdomdata(platform) # 是否加载原始数据 if self.datainfo['loading_datatype']['rawdata']: # 如果需要加载原始合约数据,那么每个数据feed的名字就是合约名 self.load_rawdata(platform)
def Indicator_Create(self): if self.indicator_islive: # 如果数据是实时生成,那么调用相关指标进行计算 # 将同一品种的数据保存在datafeeds_vt里面 # add the skewness indicator for i, vt in self.index_mapping_vt.items(): clock_data = self.datas[self.vt_mapping_index[vt]] self.Mmt_ind[vt] = Momentum_ind( params={'window_prd': self.params.Mmt_window_prd}, datafeed=[self.datas[i]], clockdata=clock_data) self.Mmt_ind[vt].plotinfo.plot = False # 加个计时器:clock,然后利用计时器来提取指标 self.clock = 0 else: # 调用指标提取器提取数据 Indicator_utl = HdfUtility() for vt in self.vt_mapping_index.keys(): excode = self.od_params['excode'][self.od_params['vt'].index( vt)] indicator_temp = Indicator_utl.hdfRead( EXT_Hdf_Path, excode, vt, kind1='Indicator', kind2=self.indicator_name, kind3=None, startdate=self.od_params['startdate'], enddate=self.od_params['enddate']) self.rollover_ind[vt] = indicator_temp['Indicator'] # 加个计时器:clock,然后利用计时器来提取指标 self.clock = self.params.rollover_window_prd - 1
def Indicator_Create(self): # 初始化指标数据生成器 # Indicator_utl = CTA_Ind_data if self.indicator_islive: # 如果数据是实时生成,那么调用相关指标进行计算 # 将同一品种的数据保存在datafeeds_vt里面 datafeeds_vt = { vt: [] for vt in self.tradevt_campping_index.keys() } for i, vt in self.index_mapping_symbol.items(): vt = re.findall('^(\D*)', vt)[0] datafeeds_vt[vt] = datafeeds_vt[vt] + [self.datas[i]] # 将非交易数据剔除 self.datas = [ self.datas[i] for i in self.tradevt_campping_index.values() ] # 重新记录映射关系 self.tradevt_campping_index = { vt: i for i, vt in enumerate(self.tradevt_campping_index.keys()) } self.index_campping_tradevt = { i: vt for i, vt in enumerate(self.tradevt_campping_index.keys()) } # 将数据添加到指标当中,由于指标需要以系统默认的数据来进行时间计数_clock,所以需要额外添加计时种子clock_data进去, # 但是我们不用其进行计算 for vt, datalist in datafeeds_vt.items(): clock_data = self.datas[self.tradevt_campping_index[vt]] self.BasisMmt_ind[vt] = BasisMmt_ind( datafeed=datalist, clockdata=clock_data, params={'window_prd': self.params.BasisMmt_window_prd}) # 指标太多,就不画出来了 self.BasisMmt_ind[vt].plotinfo.plot = False # 计时器:clock self.clock = 0 else: # 调用指标提取器提取数据 Indicator_utl = HdfUtility() for vt in self.tradevt_campping_index.keys(): excode = self.od_params['excode'][self.od_params['vt'].index( vt)] indicator_temp = Indicator_utl.hdfRead( EXT_Hdf_Path, excode, vt, kind1='Indicator', kind2=self.indicator_name, kind3=None, startdate=self.od_params['startdate'], enddate=self.od_params['enddate']) self.BasisMmt_ind[vt] = indicator_temp['Indicator'] # 计时器:clock self.clock = self.params.BasisMmt_window_prd - 1
def indicator_save(cls, platform, setting): Indicator_utl = HdfUtility() stat = platform.runstrats[0][0] indicator_byvt = stat.ind params = setting['data_setting'] for vt, indicator in indicator_byvt.items(): indicator_data = indicator.array tradingday = platform.datasbyname[vt + '0000'].datetime.array df = pd.DataFrame({ 'Indicator': indicator_data, 'Date': tradingday }) date_parse = lambda x: num2date(x) df['Date'] = df['Date'].apply(date_parse) excode = params['excode'][params['vt'].index(vt)] Indicator_utl.hdfWrite( EXT_Hdf_Path, excode, vt, df.set_index('Date'), kind1='Indicator', kind2=stat.indicator_name, kind3={'window_prd': stat.params['window_prd']})
def loading_data(self, instance): # parse the datasetting self.datainfo = self.params['data_setting'] self.Parse_datasetting() # create the our datafeed CTA_datafeed_name = 'CTA_datafeed'.encode('utf-8') # if you have other data form, change the bt.feeds.pandafeed to your favour # you must cancel the lines in the dataserise or the lines will over self.CTA_datafeed = type(CTA_datafeed_name, (bt.feeds.PandasData, ), { 'lines': self.lines, 'params': self.data_params }) # loading bar data period: 1 day getdata_utl = HdfUtility() for i, vt in enumerate(self.vtsymbol): domdata = getdata_utl.hdfRead(EXT_Hdf_Path, self.excode[i], vt, kind1=EXT_Stitch, kind2='00', kind3='1d', startdate=self.startdate, enddate=self.enddate) # 判断需要加载哪些类型的数据,dom ?, subdom?, rawdata? # 是否加载主力合约数据 if self.datainfo['loading_datatype']['domdata']: # choose the columns we need # 来自hdf5中的数据的时间列为Date,平台的lines默认的时间名为datetime domdata = domdata.reset_index().rename( columns={'Date': 'datetime'}) domdata = domdata[self.datainfo['COLUMNS']].set_index( 'datetime') # 由于平台只允许datetime为非float类型,所以如果数据中有其他类型需要转化为数值类型 is_numtype = { c: pd.api.types.is_numeric_dtype(domdata[c]) for c in domdata.columns } if False in is_numtype.values(): domdata = self.type_change(domdata, is_numtype) data = self.CTA_datafeed(dataname=domdata) # 将主力合约命名形如IF0000 instance.adddata(data, name=vt + '0000') # 是否加载次主力合约数据 if self.datainfo['loading_datatype']['subdomdata']: subdom = getdata_utl.hdfRead(EXT_Hdf_Path, self.excode[i], vt, kind1=EXT_Stitch, kind2='01', kind3=None, startdate=self.startdate, enddate=self.enddate) subdom = subdom.reset_index().rename( columns={'Date': 'datetime'}) subdom = subdom[self.datainfo['COLUMNS']].set_index('datetime') # 由于平台只允许datetime为非float类型,所以如果数据中有其他类型需要转化为数值类型 is_numtype = { c: pd.api.types.is_numeric_dtype(subdom[c]) for c in subdom.columns } if False in is_numtype.values(): subdom = self.type_change(subdom, is_numtype) data = self.CTA_datafeed(dataname=subdom) # 将次主力合约命名形如IF0001 instance.adddata(data, name=vt + '0001') # 是否加载原始数据 if self.datainfo['loading_datatype']['rawdata']: # 如果需要加载原始合约数据,那么每个数据feed的名字就是合约名 # 将每个合约的数据分别导入回测平台, 注意的是原始合约并没有调整因子 self.datainfo['COLUMNS'].remove('AdjFactor') for i, vt in enumerate(self.vtsymbol): raw_data = getdata_utl.getrawDate(EXT_Hdf_Path, self.excode[i], vt, kind1='Rawdata', kind2=None, kind3='1d', startdate=self.startdate, enddate=self.enddate) raw_data = raw_data.reset_index().rename( columns={'Date': 'datetime'}) contract = pd.unique(raw_data['Asset']) for c in contract: data_temp = raw_data.ix[raw_data['Asset'] == c, :] data_temp = data_temp[self.datainfo['COLUMNS']].set_index( 'datetime') # 由于平台只允许datetime为非float类型,所以如果数据中有其他类型需要转化为数值类型 is_numtype = { c: pd.api.types.is_numeric_dtype(data_temp[c]) for c in data_temp.columns } if False in is_numtype.values(): data_temp = self.type_change(data_temp, is_numtype) data = self.CTA_datafeed(dataname=data_temp) instance.adddata(data, name=c)
class CTA_setting_parse(object): def __init__(self, setting): self.params = setting # 基础设置,之后添加到平台当中 # 例如组合交易的起始资金,手续费,佣金,默认交易手数,分析指标analyzers等 self.baseinfo = self.params.get('basic_setting', None) # 关于交易的品种的相关信息,之后添加到策略当中 # 例如最小价格变动价位, 订单生效日期,每点的价格, self.tradesetting = self.params.get('vtsymbol_setting', None) self.datainfo = self.params.get('data_setting', None) # ------------------------------------------------------------------ def add2platform(self, platform): # basic setting # input every basic setting into a dictionary named 'basic_setting' if self.baseinfo.get('startcash', None): # set the starting cash platform.broker.setcash(self.baseinfo['startcash']) if self.baseinfo.get('commission', None): # set the commission platform.broker.setcommission(self.baseinfo['commission']) if self.baseinfo.get('default_sizer', None): # set the default sizer platform.addsizer(bt.sizers.FixedSize, stake=self.baseinfo['default_sizer']) if self.baseinfo.get('analyzer', None): # add the analyzers analyzers = self.baseinfo['analyzer'] for analyzer, newname in analyzers.items(): platform.addanalyzer(getattr(bt.analyzers, analyzer), _name=newname) # self.params.pop('basic_setting') def add2strat(self, platform): for strat in platform.strats: self.params['vtsymbol_setting'].update(self.params['data_setting']) strat[0][0].od_params = self.params['vtsymbol_setting'] # ------------------------------------------------------------------------ def loading_data(self, platform): # parse the datasetting #self.datainfo = self.params['data_setting'] self.Parse_datasetting() # loading bar data period: 1 day self.getdata_utl = HdfUtility() # create the our datafeed CTA_datafeed_name = 'CTA_datafeed'.encode('utf-8') # if you have other data form, change the bt.feeds.pandafeed to your favour # you must cancel the lines in the dataserise or the lines will be overlap self.CTA_datafeed = type(CTA_datafeed_name.decode(), (bt.feeds.PandasData, ), { 'lines': self.lines, 'params': self.data_params }) # 判断需要加载哪些类型的数据,dom ?, subdom?, rawdata? # 是否加载主力合约数据 if self.datainfo['loading_datatype']['domdata']: self.load_domdata(platform) # 是否加载次主力合约数据 if self.datainfo['loading_datatype']['subdomdata']: self.load_subdomdata(platform) # 是否加载原始数据 if self.datainfo['loading_datatype']['rawdata']: # 如果需要加载原始合约数据,那么每个数据feed的名字就是合约名 self.load_rawdata(platform) def Parse_datasetting(self): # lines and params setting self.lines = tuple([l.lower() for l in self.datainfo['COLUMNS']]) self.data_params = ( ('nocase', True), ('datetime', None), ('open', -1), ('high', -1), ('low', -1), ('close', -1), ('volume', -1), ('AdjFactor', -1), ('openinterest', -1), ) params_name = [name for name, i in self.data_params] add2params = [l for l in self.lines if l not in params_name] self.data_params = self.data_params + tuple([(name, -1) for name in add2params]) self.vtsymbol = self.datainfo['vt'] self.excode = self.datainfo['excode'] self.startdate = self.datainfo['startdate'] if self.datainfo.get( 'startdate', None) else None self.enddate = self.datainfo['enddate'] if self.datainfo.get( 'enddate', None) else None # ----------------------------------------------------------------------------- def load_domdata(self, platform): for i, vt in enumerate(self.vtsymbol): domdata = self.getdata_utl.hdfRead(EXT_Hdf_Path, self.excode[i], vt, kind1=EXT_Stitch, kind2='00', kind3='1d', startdate=self.startdate, enddate=self.enddate) # 判断需要加载哪些类型的数据,dom ?, subdom?, rawdata? # 是否加载主力合约数据 # 选择我们所需的列数据 # 来自hdf5中的数据的时间列为Date,平台的lines默认的时间名为datetime domdata = domdata.reset_index().rename( columns={'Date': 'datetime'}) COLUMNS = list( set(domdata.columns) & set(self.datainfo['COLUMNS'])) domdata = domdata[COLUMNS].set_index('datetime') # 由于平台只允许datetime为非float类型,所以如果数据中有其他类型需要转化为数值类型 is_numtype = { c: pd.api.types.is_numeric_dtype(domdata[c]) for c in domdata.columns } if False in is_numtype.values(): domdata = self.type_change(domdata, is_numtype) data = self.CTA_datafeed(dataname=domdata) # 将主力合约命名形如IF0000 platform.adddata(data, name=vt + '0000') #---------------------------------------------------------------------- def load_subdomdata(self, platform): for i, vt in enumerate(self.vtsymbol): subdom = self.getdata_utl.hdfRead(EXT_Hdf_Path, self.excode[i], vt, kind1=EXT_Stitch, kind2='01', kind3=None, startdate=self.startdate, enddate=self.enddate) subdom = subdom.reset_index().rename(columns={'Date': 'datetime'}) COLUMNS = set(subdom.columns) & set(self.datainfo['COLUMNS']) subdom = subdom[COLUMNS].set_index('datetime') # 由于平台只允许datetime为非float类型,所以如果数据中有其他类型需要转化为数值类型 is_numtype = { c: pd.api.types.is_numeric_dtype(subdom[c]) for c in subdom.columns } if False in is_numtype.values(): subdom = self.type_change(subdom, is_numtype) data = self.CTA_datafeed(dataname=subdom) # 将次主力合约命名形如IF0001 platform.adddata(data, name=vt + '0001') #---------------------------------------------------------------------- def load_rawdata(self, platform): # 如果需要加载原始合约数据,那么每个数据feed的名字就是合约名 for i, vt in enumerate(self.vtsymbol): raw_data = self.getdata_utl.hdfRead(EXT_Hdf_Path, self.excode[i], vt, kind1='Rawdata', kind2=None, kind3='1d', startdate=self.startdate, enddate=self.enddate) raw_data = raw_data.reset_index().rename( columns={'Date': 'datetime'}) COLUMNS = list( set(raw_data.columns) & set(self.datainfo['COLUMNS'])) contract = pd.unique(raw_data['Asset']) for c in contract: data_temp = raw_data.ix[raw_data['Asset'] == c, :] data_temp = data_temp[COLUMNS].set_index('datetime') # 由于平台只允许datetime为非float类型,所以如果数据中有其他类型需要转化为数值类型 is_numtype = { c: pd.api.types.is_numeric_dtype(data_temp[c]) for c in data_temp.columns } if False in is_numtype.values(): data_temp = self.type_change(data_temp, is_numtype) data = self.CTA_datafeed(dataname=data_temp) platform.adddata(data, name=c) # ----------------------------------------------------------------------------- def type_change(self, data, datatype_dict): for column, is_numtype in datatype_dict.items(): if not is_numtype: # 这里使用者可以根据各种类型进行调整 #if pd.api.types.is_bool_dtype(data[column]) #if pd.api.types.is_string_dtype(data[column]) if pd.api.types.is_datetime64_ns_dtype(data[column]): date2num = lambda x: x.toordinal() data[column] = data[column].apply(date2num) return data # ---------------------------------------------------------------------------- def add_extrdata(self, platform, extra_data, vt, extra_name): # 使用者可以根据自己的需要添加其他数据集 extra_data = extra_data.reset_index().rename( columns={'Date': 'datetime'}) COLUMNS = list(set(self.datainfo['COLUMNS']) & set(extra_data.columns)) extra_data = extra_data[COLUMNS].set_index('datetime') # 由于平台只允许datetime为非float类型,所以如果数据中有其他类型需要转化为数值类型 is_numtype = { c: pd.api.types.is_numeric_dtype(extra_data[c]) for c in extra_data.columns } if False in is_numtype.values(): extra_data = self.type_change(extra_data, is_numtype) data = self.CTA_datafeed(dataname=extra_data) platform.adddata(data, name=vt + extra_name)
parse_tool.add2platform(platform=cerebro) # loading data parse_tool.loading_data(platform=cerebro) # add some parmas from setting parse_tool.add2strat(platform=cerebro) # Print out the starting conditions print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue()) # Run over everything cerebro.run() # Print out the final result print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue()) if False: # save the indicator print('save the indicator') Indicator_utl = HdfUtility() stat = cerebro.runstrats[0][0] indicator_byvt = stat.Mmt_ind params = cerebro.runstrats[0][0].od_params for indicator, vt in indicator_byvt.items(): indicator_data = indicator.array tradingday = cerebro.datasbyname(vt + '0000').datetime.array df = pd.DataFrame({ 'Indicator': indicatoe_data, 'Date': tradingday }) date_parse = lambda x: num2date(x) df['Date'] = df['Date'].apply(date_parse) excode = params['excode'][params['vt'].index(vt)] Indicator_utl.hdfWrite( EXT_Hdf_Path,