Пример #1
0
 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"
Пример #2
0
 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"
Пример #3
0
 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
Пример #4
0
 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
Пример #5
0
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)
Пример #6
0
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)
Пример #7
0
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)
Пример #8
0
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)