def __init__(self): LoggerInterface.__init__(self) ConfigInterface.__init__(self) self.__code = None self.__strategy = None self.__strategy_engine = None self.__data_generator = None self.__strategy_parameters = None self.__performance_manager = None self.__timer = Timer() self.__is_alive = False self.__initialized = False self.logger_name = "Backtesting"
def __init__(self): super().__init__() self.__config = {} self.__code = None self.__strategy = None self.__strategy_engine = None self.__data_generator = None self.__strategy_parameters = None self._logger = None self.__performance_manager = None self.__timer = Timer() self._login = False self.__is_alive = False self.__initialized = False
def __init__(self, user, name, code, symbols=None, time_frame=None, start_time=None, end_time=None, commission=0, slippage=0): super().__init__() self.__config = {'user': user, 'name': name, 'symbols': symbols, 'time_frame': time_frame, 'start_time': start_time, 'end_time': end_time, 'commission': commission, 'slippage': slippage} self.__code = code self.__strategy = None self.__strategy_engine = None self.__data_generator = None self.__strategy_parameters = None self._logger = None self.__performance_manager = None self.__timer = Timer() self.__is_alive = False self.__initialized = False
class RuntimeSignal(LoggerInterface): def __init__(self): super().__init__() self.__config = {} self.__code = None self.__strategy = None self.__strategy_engine = None self.__data_generator = None self.__strategy_parameters = None self._logger = None self.__performance_manager = None self.__timer = Timer() self._login = False self.__is_alive = False self.__initialized = False def init(self): if self.__initialized: return True bf_config = BfConfig(**self.__config) self.__strategy_engine = StrategyEngine(is_backtest=False, **self.__config) self.__strategy = Strategy(self.__strategy_engine, code=self.__code, logger=self._logger, **self.__config) self.__strategy_engine.add_strategy(self.__strategy) self.__data_generator = TickDataGenerator(bf_config, lambda x: self.__strategy_engine.put_event(x.to_event()), lambda: self.__strategy_engine.put_event(Event(EVENT_FINISH))) self.__initialized = True def set_config(self, **kwargs): self.__config.update(kwargs) def login(self): if not self._login: self._login = False def set_logger(self, logger): self._logger = logger @property def code(self): return self.__code @code.setter def code(self, code): if self.__code is None: self.__code = code @property def is_finished(self): return self.__is_alive @profile def start(self, paras=None, refresh=True): """ :param paras: :param refresh: True表示刷新绩效且需要释放资源,即用户一个完整的请求已经结束;False的情况主要是参数优化时批量运行回测。 """ try: if not self.__initialized: self.init() gc.collect() self.__is_alive = True if paras is not None: self.__strategy.set_parameters(paras) self.__strategy_engine.start() self.__data_generator.start() if refresh: self.__performance_manager = self.__strategy_engine.wait(self.__get_performance_manager) self.__data_generator.stop() if MEMORY_DEBUG: print('gb:\n%s' % sys.getsizeof(gc.garbage)) # 写日志,计算垃圾占用的内存等 gb_log = {} for gb in gc.garbage: type_ = type(gb) if type_ not in gb_log: gb_log[type_] = 0 gb_log[type_] += sys.getsizeof(gb) print(gb_log) result = self.__performance_manager else: result = self.__strategy_engine.wait() self.log(self.__timer.time("策略运算完成,耗时:{0}"), logging.INFO) return result except Exception as e: self.stop() raise e def stop(self): self.__is_alive = False self.__timer.reset() self.__data_generator.stop() self.__strategy_engine.stop() def __get_performance_manager(self): # TODO 加入回测是否运行的判断 if False: raise ValueError('please run the backtest first') return StrategyPerformanceManagerOnline(self.__strategy_engine.get_profit_records(), self.__strategy_engine.get_deals(), self.__strategy_engine.get_positions()) def get_profit_records(self): return self.__strategy_engine.get_profit_records() def get_performance(self): return self.__performance_manager.get_performance() def get_output(self): return self.__strategy.get_output() def get_setting(self): setting = self.__config.copy() return setting def get_parameters(self): if self.__strategy_parameters is None: temp = self.__strategy.get_parameters() for handle_name in temp.keys(): for para_name, values in temp[handle_name].items(): temp[handle_name][para_name] = {'default': values, 'type': str(type(values))} self.__strategy_parameters = temp return self.__strategy_parameters def time(self, *args): return self.__timer.time(*args)
class Backtesting(LoggerInterface, ConfigInterface): def __init__(self): LoggerInterface.__init__(self) ConfigInterface.__init__(self) self.__code = None self.__strategy = None self.__strategy_engine = None self.__data_generator = None self.__strategy_parameters = None self.__performance_manager = None self.__timer = Timer() self.__is_alive = False self.__initialized = False self.logger_name = "Backtesting" def init(self): if self.__initialized: return None assert self._config is not None # 判断初始化前是否设置好了基本参数 self.__strategy_engine = StrategyEngine(parent=self) self.__strategy = Strategy(self.__strategy_engine, self.__code, parent=self) self.__strategy_engine.add_strategy(self.__strategy) self.__data_generator = DataGenerator( lambda x: self.__strategy_engine.put_event(x.to_event()), lambda: self.__strategy_engine.put_event(Event(EVENT_FINISH)), parent=self) if DEBUG: self.logger.setLevel(logging.DEBUG) else: self.logger.setLevel(logging.INFO) self.__initialized = True def set_config(self, config): assert isinstance(config, BfConfig) self._config = config self._config.running_mode = RunningMode.backtest def set_code(self, code): assert isinstance(code, str) self.__code = code.replace('\t', ' ') @property def is_finished(self): return self.__is_alive @property def progress(self): if not self.__is_alive: return 0 et = get_datetime(self._config['end_time']).timestamp() st = get_datetime(self._config['start_time']).timestamp() ct = self.__strategy_engine.current_time if ct: return min((ct - st) / (et - st) * 100, 100) else: return 0 @property def max_margin(self): return self.__strategy_engine.max_margin @profile def start(self, paras=None, refresh=True): """ :param paras: :param refresh: True表示刷新绩效且需要释放资源,即用户一个完整的请求已经结束;False的情况主要是参数优化时批量运行回测。 """ self.logger.info("<%s>策略运算开始" % self._config['name']) self.init() gc.collect() self.__is_alive = True if paras is not None: self.__strategy.set_parameters(paras) self.__strategy_engine.start() self.__data_generator.start() if refresh: self.__performance_manager = self.__strategy_engine.wait( self.__get_performance_manager) self.__data_generator.stop() if MEMORY_DEBUG: print('gb:\n%s' % sys.getsizeof(gc.garbage)) # 写日志,计算垃圾占用的内存等 gb_log = {} for gb in gc.garbage: type_ = type(gb) if type_ not in gb_log: gb_log[type_] = 0 gb_log[type_] += sys.getsizeof(gb) print(gb_log) result = self.__performance_manager else: result = self.__strategy_engine.wait() self.logger.info( self.__timer.time("<%s>策略运算完成,耗时:{0}" % self._config['name'])) return result def stop(self): self.__is_alive = False self.__timer.reset() self.__data_generator.stop() self.__strategy_engine.stop() def __get_performance_manager(self): # TODO 加入回测是否运行的判断 if False: raise ValueError('please run the backtest first') return StrategyPerformanceManagerOnline( self.__strategy_engine.profit_records, self.__strategy_engine.deals, self.__strategy_engine.positions) def get_profit_records(self): return self.__strategy_engine.profit_records def get_performance(self): return self.__performance_manager.get_performance() def get_output(self): return self.__strategy.get_output() def get_setting(self): return self._config.to_dict() def time(self, *args): return self.__timer.time(*args)
class Backtesting(LoggerInterface): def __init__(self, user, name, code, symbols=None, time_frame=None, start_time=None, end_time=None, commission=0, slippage=0): super().__init__() self.__config = {'user': user, 'name': name, 'symbols': symbols, 'time_frame': time_frame, 'start_time': start_time, 'end_time': end_time, 'commission': commission, 'slippage': slippage} self.__code = code self.__strategy = None self.__strategy_engine = None self.__data_generator = None self.__strategy_parameters = None self._logger = None self.__performance_manager = None self.__timer = Timer() self.__is_alive = False self.__initialized = False def init(self): if self.__initialized: return True bf_config = BfConfig(**self.__config) self.__strategy_engine = StrategyEngine(is_backtest=True, **self.__config) self.__strategy = Strategy(self.__strategy_engine, code=self.__code, logger=self._logger, **self.__config) self.__strategy_engine.add_strategy(self.__strategy) self.__data_generator = DataGenerator(bf_config, lambda x: self.__strategy_engine.put_event(x.to_event()), lambda: self.__strategy_engine.put_event(Event(EVENT_FINISH))) self.__initialized = True def set_config(self, **kwargs): self.__config.update(kwargs) def set_logger(self, logger): self._logger = logger @property def is_finished(self): return self.__is_alive @property def progress(self): if not self.__initialized: return 0 et = get_datetime(self.__config['end_time']).timestamp() st = get_datetime(self.__config['start_time']).timestamp() ct = self.__strategy_engine.current_time if ct: return min((ct - st) / (et - st) * 100, 100) else: return 0 @profile def start(self, paras=None, refresh=True): """ :param paras: :param refresh: True表示刷新绩效且需要释放资源,即用户一个完整的请求已经结束;False的情况主要是参数优化时批量运行回测。 """ if not self.__initialized: self.init() gc.collect() self.__is_alive = True if paras is not None: self.__strategy.set_parameters(paras) self.__strategy_engine.start() self.__data_generator.start() if refresh: self.__performance_manager = self.__strategy_engine.wait(self.__get_performance_manager) self.__data_generator.stop() if MEMORY_DEBUG: print('gb:\n%s' % sys.getsizeof(gc.garbage)) # 写日志,计算垃圾占用的内存等 gb_log = {} for gb in gc.garbage: type_ = type(gb) if type_ not in gb_log: gb_log[type_] = 0 gb_log[type_] += sys.getsizeof(gb) print(gb_log) result = self.__performance_manager else: result = self.__strategy_engine.wait() self.log(self.__timer.time("策略运算完成,耗时:{0}"), logging.INFO) return result def stop(self): self.__is_alive = False self.__timer.reset() self.__data_generator.stop() self.__strategy_engine.stop() def __get_performance_manager(self): # TODO 加入回测是否运行的判断 if False: raise ValueError('please run the backtest first') return StrategyPerformanceManagerOnline(self.__strategy_engine.get_profit_records(), self.__strategy_engine.get_deals(), self.__strategy_engine.get_positions()) def get_profit_records(self): return self.__strategy_engine.get_profit_records() def get_performance(self): return self.__performance_manager.get_performance() def get_output(self): return self.__strategy.get_output() def get_setting(self): setting = self.__config.copy() setting.pop('user') return setting @staticmethod def get_optimize_goals(): return {'net_profit': '净利'} @staticmethod def get_optimize_types(): return {'enumerate': '枚举', 'genetic': '遗传'} def get_parameters(self): if self.__strategy_parameters is None: temp = self.__strategy.get_parameters() for handle_name in temp.keys(): for para_name, values in temp[handle_name].items(): temp[handle_name][para_name] = {'default': values, 'type': str(type(values))} self.__strategy_parameters = temp return self.__strategy_parameters def _enumerate_optimize(self, ranges, goal, num): stack = [] range_length = [] parameters = {} result = [] head_index = [] def get_range(range_info): return np.arange(range_info['start'], range_info['end'] + range_info['step'], range_info['step']) for handle, paras in ranges.items(): parameters[handle] = {} for para, value in paras.items(): range_value = get_range(value) stack.append({'handle': handle, 'para': para, 'range': range_value}) head_index.append('%s(%s)' % (para, handle)) range_length.append(len(range_value)) n = len(stack) index = [-1] * n head = [0] * n def set_paras(n, handle=None, para=None, range=None): nonlocal parameters, head, index parameters[handle][para] = head[n] = range[index[n]] i = 0 finished = False while 1: index[i] += 1 while index[i] >= range_length[i]: if i == 0: finished = True break index[i] = -1 i -= 1 index[i] += 1 if finished: break set_paras(i, **stack[i]) if i == n - 1: performance_manager = self.start(parameters, refresh=False) head = pd.Series(head, index=head_index) optimize_info = performance_manager.get_performance().optimize_info.copy() target = optimize_info[goal] del optimize_info[goal] result.append(pd.concat([head, pd.Series([target], index=[goal]), optimize_info])) else: i += 1 self.__data_generator.stop() # 释放数据资源 output = pd.DataFrame(result).sort_values(goal, ascending=False) result.clear() # 释放资源 output.index.name = '_' output = output.iloc[:num] return output def _genetic_optimize(self, ranges, goal): pass def optimize(self, ranges, type, goal, num=50): if not ranges: return if type is None: type = "enumerate" # TODO 不要使用硬编码 if goal is None: goal = "净利($)" goal = "净利($)" optimizer = getattr(self, '_%s_optimize' % type) return optimizer(ranges, goal, num) def time(self, *args): return self.__timer.time(*args)
class Backtesting(LoggerInterface, ConfigInterface): def __init__(self): LoggerInterface.__init__(self) ConfigInterface.__init__(self) self.__code = None self.__strategy = None self.__strategy_engine = None self.__data_generator = None self.__strategy_parameters = None self.__performance_manager = None self.__timer = Timer() self.__is_alive = False self.__initialized = False self.logger_name = "Backtesting" def init(self): if self.__initialized: return None assert self._config is not None # 判断初始化前是否设置好了基本参数 self.__strategy_engine = StrategyEngine(parent=self) self.__strategy = Strategy(self.__strategy_engine, self.__code, parent=self) self.__strategy_engine.add_strategy(self.__strategy) self.__data_generator = DataGenerator(lambda x: self.__strategy_engine.put_event(x.to_event()), lambda: self.__strategy_engine.put_event(Event(EVENT_FINISH)), parent=self) if DEBUG: self.logger.setLevel(logging.DEBUG) else: self.logger.setLevel(logging.INFO) self.__initialized = True def set_config(self, config): assert isinstance(config, BfConfig) self._config = config self._config.running_mode = RunningMode.backtest def set_code(self, code): assert isinstance(code, str) self.__code = code.replace('\t', ' ') @property def is_finished(self): return self.__is_alive @property def progress(self): if not self.__is_alive: return 0 et = get_datetime(self._config['end_time']).timestamp() st = get_datetime(self._config['start_time']).timestamp() ct = self.__strategy_engine.current_time if ct: return min((ct - st) / (et - st) * 100, 100) else: return 0 @property def max_margin(self): return self.__strategy_engine.max_margin @profile def start(self, paras=None, refresh=True): """ :param paras: :param refresh: True表示刷新绩效且需要释放资源,即用户一个完整的请求已经结束;False的情况主要是参数优化时批量运行回测。 """ self.logger.info("<%s>策略运算开始" % self._config['name']) self.init() gc.collect() self.__is_alive = True if paras is not None: self.__strategy.set_parameters(paras) self.__strategy_engine.start() self.__data_generator.start() if refresh: self.__performance_manager = self.__strategy_engine.wait(self.__get_performance_manager) self.__data_generator.stop() if MEMORY_DEBUG: print('gb:\n%s' % sys.getsizeof(gc.garbage)) # 写日志,计算垃圾占用的内存等 gb_log = {} for gb in gc.garbage: type_ = type(gb) if type_ not in gb_log: gb_log[type_] = 0 gb_log[type_] += sys.getsizeof(gb) print(gb_log) result = self.__performance_manager else: result = self.__strategy_engine.wait() self.logger.info(self.__timer.time("<%s>策略运算完成,耗时:{0}" % self._config['name'])) return result def stop(self): self.__is_alive = False self.__timer.reset() self.__data_generator.stop() self.__strategy_engine.stop() def __get_performance_manager(self): # TODO 加入回测是否运行的判断 if False: raise ValueError('please run the backtest first') return StrategyPerformanceManagerOnline(self.__strategy_engine.profit_records, self.__strategy_engine.deals, self.__strategy_engine.positions) def get_profit_records(self): return self.__strategy_engine.profit_records def get_performance(self): return self.__performance_manager.get_performance() def get_output(self): return self.__strategy.get_output() def get_setting(self): return self._config.to_dict() def time(self, *args): return self.__timer.time(*args)