Example #1
0
 def get_injector(self, allow_trading=True):
     exclude = [] if allow_trading else self.EXCLUDE
     to_inject_init = ["__globals = globals()"]
     to_inject_init.extend([
         "{0} = __globals[\"{0}\"]".format(key)
         for key in self.__environment.globals_const.keys()
         if key not in exclude
     ])
     to_inject_init.extend([
         "{0} = __globals[\"{0}\"]".format(key)
         for key in self.__environment.system_functions.keys()
     ])
     globals_var = self.__environment.globals_var
     to_inject_init.extend([
         "{0} = __globals[\"{0}\"]".format("get" + key)
         for key in globals_var.keys()
     ])
     to_inject_var = [
         "{0} = get{0}()".format(key) for key, value in globals_var.items()
     ]
     return LocalsInjector(InjectingInfo(to_inject_init, to_inject_var))
Example #2
0
    def bind_code_to_strategy(self, code):
        def get_parameter_default(paras, name, check, default, pop=True):
            if pop:
                para = paras.pop(name, None)
            else:
                para = paras.get(name, None)
            if para:
                temp = para.default
                if temp == inspect._empty:
                    # TODO未给定值的处理
                    return default
                elif check(temp):
                    return temp
                else:
                    raise KeyError("变量%s所赋值不合法", name)
            else:
                return default

        def get_global_attrs(locals_):
            for name, attr in self.ATTR_MAP.items():
                if getattr(self, attr) is None:
                    setattr(self, attr, locals_.get(name))

        def set_global_attrs(globals_):
            for name, attr in self.ATTR_MAP.items():
                value = getattr(self, attr)
                if value is not None:
                    globals_[name] = value
                else:
                    pass

        def upper_first_letter(string):
            return string[0].upper() + string[1:]

        # get the system functions in use
        ast_ = ast.parse(code)
        import_inspector = ImportInspector()
        import_inspector.visit(ast_)  # 模块导入检查
        signal_locals_ = {}
        function_locals = {}
        signal_globals_ = {'open': self.open}  # 可动态管理的全策略命名空间,禁用open
        function_globals_ = {'open': self.open}  # 可动态管理的系统函数命名空间,禁用open
        # 获取并检查一些全局变量的设定
        exec(compile(code, "[Strategy:%s]" % self.name, mode="exec"), signal_globals_, signal_locals_)
        # get_global_attrs(signal_locals_)  # 弃用,暂时保留以便向下兼容
        set_global_attrs(signal_globals_)
        set_global_attrs(function_globals_)
        signal_globals_.update(signal_locals_)
        signal_globals_.update(self.__glb)
        function_globals_.update(self.__glb)
        self.engine.set_capital_base(self.capital_base)
        self.engine.start_time = self.start_time
        self.engine.end_time = self.end_time
        check_time_frame(self.time_frame)
        sys_func_detector = SystemFunctionsDetector()
        sys_func_detector.visit(ast_)
        sys_func_dir = self.user_dir.get_sys_func_dir()
        funcs_in_use = sys_func_detector.get_funcs_in_use()

        # get the instructions to inject to every handle
        signal_to_inject_init = {}
        function_to_inject_init = {}
        signal_to_inject_loop = {}
        function_to_inject_loop = {}
        code_lines = ["import functools", "__globals = globals()"]
        code_lines.extend(["{0} = __globals['{0}']".format(key) for key in self.__glb.keys()
                           if key not in ["Sell", "Buy", "SellShort", "BuyToCover"]])
        # init中可以设定全局变量,所以要以"global foo"的方式进行注入。
        if inspect.isfunction(signal_locals_.get('init', None)):
            init_transformer = InitTransformer()
            init_transformer.visit(ast_)
            # XXX 必须要一个module node作为根节点。
            exec(compile(wrap_with_module(init_transformer.init_node), "[Strategy:%s]" % self.name, mode="exec"),
                 signal_globals_, signal_locals_)
            self.handlers['init'] = signal_locals_['init']
            # 执行init并记录locals,之后注入信号
            init_globals = self.handlers['init']()
            signal_globals_.update(init_globals)
            init_to_inject_init = ["{0} = __globals['{0}']".format(key) for key in init_globals.keys()]
        else:
            init_to_inject_init = []

        for key, value in signal_locals_.items():
            if inspect.isfunction(value):
                if key == "init":
                    continue
                paras = inspect.signature(value).parameters.copy()  # 获取handler函数的参数列表
                is_handle = get_parameter_default(paras, "IsHandle", lambda x: isinstance(x, bool), True)
                if not is_handle:
                    continue
                custom = get_parameter_default(paras, "Custom", lambda x: isinstance(x, bool), False)
                if not custom:
                    # TODO加入真正的验证方法
                    # 转化为tuple是因为symbols要那来当做字典的键
                    symbols = tuple(get_parameter_default(paras, "Symbols", lambda x: True, self.symbols))
                    time_frame = get_parameter_default(paras, "TimeFrame", check_time_frame, self.time_frame)
                    max_length = get_parameter_default(paras, "MaxLen", lambda x: isinstance(x, int) and (x > 0),
                                                       self.max_length)
                    self.engine.add_cache_info(symbols, time_frame, max_length)
                    self.signals[key] = self.signal_factory.new(self.engine, self.user, self.name, key, symbols,
                                                                time_frame)
                    additional_instructions = ["{0} = system_functions['%s.%s'%('{1}','{0}')]".format(f, key)
                                               for f, s in funcs_in_use.items() if key in s] + ['del(system_functions)']
                    temp = []
                    # Begin open,high,low,close相关变量的注入
                    quotes = ["open", "high", "low", "close", "datetime", "timestamp", "volume"]
                    temp.extend(["{0} = __globals['Data']['{1}']['{3}']['{2}']"
                                .format(upper_first_letter(field), time_frame, symbols[0], field)
                                 for field in quotes])
                    temp.extend(["{0} = __globals['Data']['{1}']['{3}']['{2}']"
                                .format(field[0].upper(), time_frame, symbols[0], field)
                                 for field in quotes])
                    temp.extend(["{0}s = __globals['Data']['{1}']['{2}']"
                                .format(upper_first_letter(field), time_frame, field)
                                 for field in quotes])
                    # end
                    # get_current_bar 函数的注入,BarNum实际通过该函数维护
                    temp.append("{0} = __globals['signals']['{1}'].{0}".format('get_current_bar', key))
                    temp.append("Symbol = Symbols[0]")  # Symbol注入
                    temp.append("Point=Points[Symbol]")  # Points注入
                    function_to_inject_init[key] = code_lines + temp + ["del(functools)", "del(__globals)"] + \
                                                   additional_instructions
                    temp.extend(["{0} = functools.partial(__globals['{0}'],signal='{1}')".format(
                        field, key)
                                 for field in ["Sell", "Buy", "SellShort", "BuyToCover"]])
                    # TODO 现在是将init中的变量当做局部变量注入每个信号的初始化部分,其实这样并不等同于全局变量的概念,
                    # 只不过对于单个信号的策略是一样的。
                    signal_to_inject_init[key] = code_lines + temp + init_to_inject_init + \
                                                 ["del(functools)", "del(__globals)"] + additional_instructions
                    # 信号与函数中相比多出的就是交易指令
                    signal_to_inject_loop[key] = ["BarNum = get_current_bar()",
                                                  "Pos = Positions[Symbol]",
                                                  "MarketPosition = Pos.type",
                                                  "CurrentContracts= Pos.volume"]
                    function_to_inject_loop[key] = signal_to_inject_loop[key]
                else:
                    # TODO自定义事件处理
                    pass
                for para_name in paras.keys():
                    # TODO加入类型检测
                    default = get_parameter_default(paras, para_name, lambda x: True, None,
                                                    pop=False)
                    if default is None:
                        raise ValueError('参数%s未指定初始值' % para_name)
                    elif not isinstance(default, (int, float)):
                        raise ValueError('参数%s的值必须为整数或浮点数' % para_name)
                    self.signals[key].add_parameters(para_name, default)
        self.__points.update({key: value.point for key, value in self.engine.symbol_pool.items()})
        series_exporter = SeriesExporter()  # deal with the export syntax
        # export the system functions in use
        for func, signals in funcs_in_use.items():
            for signal in signals:
                fullname = os.path.join(sys_func_dir, func + ".py")
                with codecs.open(fullname, "r", "utf-8") as f:
                    func_ast = ast.parse(f.read())
                    f.close()
                import_inspector.visit(func_ast)  # 检查模块导入
                function_injector = LocalsInjector({func: function_to_inject_init[signal]},
                                                   {func: function_to_inject_loop[signal]})
                function_injector.visit(func_ast)
                func_ast = series_exporter.visit(func_ast)
                # TODO 多个handle时需要对每个handle调用的系统函数建立独立的系统函数
                exec(compile(func_ast, "[SysFunctions:%s]" % func, mode="exec"), function_globals_, function_locals)
                self.system_functions['%s.%s' % (signal, func)] = SeriesFunction(function_locals[func], signal)
                # new方法是对__init__的封装,创建SeriesFunction对象所需信息有其所在的函数体本身,signal和其运行时传入的参数,
                # 编译时所能确定的只有前者,采用偏函数的方式将两者结合到一起
        # inject global vars into locals of handler
        signal_injector = LocalsInjector(signal_to_inject_init, signal_to_inject_loop)
        signal_injector.visit(ast_)
        ast_ = series_exporter.visit(ast_)
        exec(compile(ast_, "[Strategy:%s]" % self.name, mode="exec"), signal_globals_, signal_locals_)
        for key in signal_to_inject_init.keys():
            self.signals[key].set_generator(signal_locals_[key])
        self.log("<%s>策略添加成功" % self.name, logging.INFO)
        return True
Example #3
0
    def bind_code_to_strategy(self, code):
        def get_parameter_default(paras, name, check, default, pop=True):
            if pop:
                para = paras.pop(name, None)
            else:
                para = paras.get(name, None)
            if para:
                temp = para.default
                if temp == inspect._empty:
                    # TODO未给定值的处理
                    return default
                elif check(temp):
                    return temp
                else:
                    raise KeyError("变量%s所赋值不合法", name)
            else:
                return default

        def get_global_attrs(locals_):
            for name, attr in self.ATTR_MAP.items():
                if getattr(self, attr) is None:
                    setattr(self, attr, locals_.get(name))

        def set_global_attrs(globals_):
            for name, attr in self.ATTR_MAP.items():
                value = getattr(self, attr)
                if value is not None:
                    globals_[name] = value
                else:
                    raise ValueError('全局变量%s未被赋值' % name)

        def upper_first_letter(string):
            return string[0].upper() + string[1:]

        # get the system functions in use
        ast_ = ast.parse(code)
        import_inspector = ImportInspector()
        import_inspector.visit(ast_)  # 模块导入检查
        signal_locals_ = {}
        function_locals = {}
        signal_globals_ = {'open': self.open}  # 可动态管理的全策略命名空间,禁用open
        function_globals_ = {'open': self.open}  # 可动态管理的系统函数命名空间,禁用open
        # 获取并检查一些全局变量的设定
        exec(compile(code, "[Strategy:%s]" % self.name, mode="exec"),
             signal_globals_, signal_locals_)
        get_global_attrs(signal_locals_)  # 弃用,暂时保留以便向下兼容
        set_global_attrs(signal_globals_)
        set_global_attrs(function_globals_)
        signal_globals_.update(signal_locals_)
        signal_globals_.update(self.__glb)
        function_globals_.update(self.__glb)
        self.engine.set_capital_base(self.capital_base)
        self.engine.start_time = self.start_time
        self.engine.end_time = self.end_time
        check_time_frame(self.time_frame)
        sys_func_detector = SystemFunctionsDetector()
        sys_func_detector.visit(ast_)
        sys_func_dir = self.user_dir.get_sys_func_dir()
        funcs_in_use = sys_func_detector.get_funcs_in_use()

        # get the instructions to inject to every handle
        signal_to_inject_init = {}
        function_to_inject_init = {}
        signal_to_inject_loop = {}
        function_to_inject_loop = {}
        code_lines = ["import functools", "__globals = globals()"]
        code_lines.extend([
            "{0} = __globals['{0}']".format(key) for key in self.__glb.keys()
            if key not in ["Sell", "Buy", "SellShort", "BuyToCover"]
        ])
        # init中可以设定全局变量,所以要以"global foo"的方式进行注入。
        if inspect.isfunction(signal_locals_.get('init', None)):
            init_transformer = InitTransformer()
            init_transformer.visit(ast_)
            # XXX 必须要一个module node作为根节点。
            exec(
                compile(wrap_with_module(init_transformer.init_node),
                        "[Strategy:%s]" % self.name,
                        mode="exec"), signal_globals_, signal_locals_)
            self.handlers['init'] = signal_locals_['init']
            # 执行init并记录locals,之后注入信号
            init_globals = self.handlers['init']()
            signal_globals_.update(init_globals)
            init_to_inject_init = [
                "{0} = __globals['{0}']".format(key)
                for key in init_globals.keys()
            ]
        else:
            init_to_inject_init = []

        for key, value in signal_locals_.items():
            if inspect.isfunction(value):
                if key == "init":
                    continue
                paras = inspect.signature(
                    value).parameters.copy()  # 获取handler函数的参数列表
                is_handle = get_parameter_default(
                    paras, "IsHandle", lambda x: isinstance(x, bool), True)
                if not is_handle:
                    continue
                custom = get_parameter_default(paras, "Custom",
                                               lambda x: isinstance(x, bool),
                                               False)
                if not custom:
                    # TODO加入真正的验证方法
                    # 转化为tuple是为了去掉重复,而且symbols要那来当做字典的键
                    symbols = tuple(
                        get_parameter_default(paras, "Symbols", lambda x: True,
                                              self.symbols))
                    time_frame = get_parameter_default(paras, "TimeFrame",
                                                       check_time_frame,
                                                       self.time_frame)
                    max_length = get_parameter_default(
                        paras, "MaxLen",
                        lambda x: isinstance(x, int) and (x > 0),
                        self.max_length)
                    self.engine.add_cache_info(symbols, time_frame, max_length)
                    self.signals[key] = self.signal_factory.new(
                        self.engine, self.user, self.name, key, symbols,
                        time_frame)
                    additional_instructions = [
                        "{0} = system_functions['%s.%s'%('{1}','{0}')]".format(
                            f, key)
                        for f, s in funcs_in_use.items() if key in s
                    ] + ['del(system_functions)']
                    temp = []
                    # Begin open,high,low,close相关变量的注入
                    quotes = [
                        "open", "high", "low", "close", "datetime",
                        "timestamp", "volume"
                    ]
                    temp.extend([
                        "{0} = __globals['Data']['{1}']['{3}']['{2}']".format(
                            upper_first_letter(field), time_frame, symbols[0],
                            field) for field in quotes
                    ])
                    temp.extend([
                        "{0} = __globals['Data']['{1}']['{3}']['{2}']".format(
                            field[0].upper(), time_frame, symbols[0], field)
                        for field in quotes
                    ])
                    temp.extend([
                        "{0}s = __globals['Data']['{1}']['{2}']".format(
                            upper_first_letter(field), time_frame, field)
                        for field in quotes
                    ])
                    # end
                    # get_current_bar 函数的注入,BarNum实际通过该函数维护
                    temp.append("{0} = __globals['signals']['{1}'].{0}".format(
                        'get_current_bar', key))
                    temp.append("Symbol = Symbols[0]")  # Symbol注入
                    temp.append("Point=Points[Symbol]")  # Points注入
                    function_to_inject_init[key] = code_lines + temp + ["del(functools)", "del(__globals)"] + \
                                                   additional_instructions
                    temp.extend([
                        "{0} = functools.partial(__globals['{0}'],signal='{1}')"
                        .format(field, key) for field in
                        ["Sell", "Buy", "SellShort", "BuyToCover"]
                    ])
                    # TODO 现在是将init中的变量当做局部变量注入每个信号的初始化部分,其实这样并不等同于全局变量的概念,
                    # 只不过对于单个信号的策略是一样的。
                    signal_to_inject_init[key] = code_lines + temp + init_to_inject_init + \
                                                 ["del(functools)", "del(__globals)"] + additional_instructions
                    # 信号与函数中相比多出的就是交易指令
                    signal_to_inject_loop[key] = [
                        "BarNum = get_current_bar()",
                        "Pos = Positions[Symbol]", "MarketPosition = Pos.type",
                        "CurrentContracts= Pos.volume"
                    ]
                    function_to_inject_loop[key] = signal_to_inject_loop[key]
                else:
                    # TODO自定义事件处理
                    pass
                for para_name in paras.keys():
                    # TODO加入类型检测
                    default = get_parameter_default(paras,
                                                    para_name,
                                                    lambda x: True,
                                                    None,
                                                    pop=False)
                    if default is None:
                        raise ValueError('参数%s未指定初始值' % para_name)
                    elif not isinstance(default, (int, float)):
                        raise ValueError('参数%s的值必须为整数或浮点数' % para_name)
                    self.signals[key].add_parameters(para_name, default)
        self.__points.update({
            key: value.point
            for key, value in self.engine.symbol_pool.items()
        })
        series_exporter = SeriesExporter()  # deal with the export syntax
        # export the system functions in use
        for func, signals in funcs_in_use.items():
            for signal in signals:
                fullname = os.path.join(sys_func_dir, func + ".py")
                with codecs.open(fullname, "r", "utf-8") as f:
                    func_ast = ast.parse(f.read())
                    f.close()
                import_inspector.visit(func_ast)  # 检查模块导入
                function_injector = LocalsInjector(
                    {func: function_to_inject_init[signal]},
                    {func: function_to_inject_loop[signal]})
                function_injector.visit(func_ast)
                func_ast = series_exporter.visit(func_ast)
                # TODO 多个handle时需要对每个handle调用的系统函数建立独立的系统函数
                exec(
                    compile(func_ast, "[SysFunctions:%s]" % func, mode="exec"),
                    function_globals_, function_locals)
                self.system_functions['%s.%s' %
                                      (signal, func)] = SeriesFunction(
                                          function_locals[func], signal)
                # new方法是对__init__的封装,创建SeriesFunction对象所需信息有其所在的函数体本身,signal和其运行时传入的参数,
                # 编译时所能确定的只有前者,采用偏函数的方式将两者结合到一起
        # inject global vars into locals of handler
        signal_injector = LocalsInjector(signal_to_inject_init,
                                         signal_to_inject_loop)
        signal_injector.visit(ast_)
        ast_ = series_exporter.visit(ast_)
        exec(compile(ast_, "[Strategy:%s]" % self.name, mode="exec"),
             signal_globals_, signal_locals_)
        for key in signal_to_inject_init.keys():
            self.signals[key].set_generator(signal_locals_[key])
        print("<%s>信号添加成功" % self.name)
        return True
Example #4
0
 def bind_code_to_strategy(self, code):
     def get_parameter_default(paras, name, check, default):
         para = paras.get(name, None)
         if para:
             temp = para.default
             if temp == inspect._empty:
                 #TODO未给定值的处理
                 return(default)
             elif check(temp):
                 return(temp)
             else:
                 raise KeyError("变量%s所赋值不合法", name) 
         else:
             return(default)
     def get_global_attrs(locals_):
         for name,attr in self.ATTRS_MAP.items():
             setattr(self, attr, locals_.get(name))               
     
     locals_ = {}
     globals_ = {}           
     exec(code,globals_,locals_)
     get_global_attrs(locals_)
     self.engine.set_capital_base(self.capital_base)
     globals_.update(self.__locals_)
     globals_.update(locals_)
     self.engine.start_time = self.start_time
     self.engine.end_time = self.end_time
     check_time_frame(self.time_frame)
     to_inject = {}
     code_lines = ["import functools", "__globals = globals()"]
     code_lines.extend(["%s = __globals['%s']" % (key, key) for key in self.__locals_.keys()
             if key not in ["sell","buy","short","cover"]])
     for key , value in locals_.items():
         if inspect.isfunction(value):
             if key == "init":
                 #TODO init中可以设定全局变量,所以要以"global foo"的方式进行注入,监听的事件不同所以要改写SymbolsListener
                 continue    
             paras = inspect.signature(value).parameters
             data_handler = get_parameter_default(paras, "data_handler", lambda x:isinstance(x,bool), True)
             if not data_handler:
                 continue
             custom = get_parameter_default(paras, "custom", lambda x:isinstance(x,bool), False)                               
             if not custom:
                 #TODO加入真正的验证方法
                 symbols = get_parameter_default(paras, "symbols", lambda x:True, self.symbols)                   
                 time_frame = get_parameter_default(paras, "timeframe", check_time_frame, self.time_frame)
                 max_length = get_parameter_default(paras, "maxlen", lambda x: isinstance(int)and(x>0), 0)                                    
                 self.engine.add_symbols(symbols,time_frame,max_length)
                 self.listeners[key] = SymbolsListener(self.engine, symbols, time_frame)
                 temp = []                    
                 temp.extend(["%s = __globals['datas']['%s']['%s']['%s']" % (field, symbols[0], time_frame, field)
                              for field in ["open","high","low","close","time","volume"]])
                 temp.extend(["%s = functools.partial(__globals['%s'],listener=%d)" % (field, field, self.listeners[key].get_id())
                               for field in ["buy","short","sell","cover"]])    
                 to_inject[key] = code_lines + temp + ["del(functools)", "del(__globals)"]
             else:
                 #TODO自定义事件处理
                 pass
     injector = LocalsInjector(to_inject)
     ast_ = ast.parse(code)
     injector.visit(ast_)
     exec(compile(ast_,"<string>",mode="exec"), globals_, locals_)
     for key in to_inject.keys():
          self.listeners[key].set_generator(locals_[key])
     print("<%s>信号添加成功" % self.name)
     return(True)
Example #5
0
    def bind_code_to_strategy(self, code):
        def get_parameter_default(paras, name, check, default, pop=True):
            if pop:
                para = paras.pop(name, None)
            else:
                para = paras.get(name, None)
            if para:
                temp = para.default
                if temp == inspect._empty:
                    # TODO未给定值的处理
                    return default
                elif check(temp):
                    return temp
                else:
                    raise KeyError("变量%s所赋值不合法", name)
            else:
                return default

        def get_global_attrs(locals_):
            for name, attr in self.ATTR_MAP.items():
                if getattr(self, attr) is None:
                    setattr(self, attr, locals_.get(name))

        def set_global_attrs(globals_):
            for name, attr in self.ATTR_MAP.items():
                value = getattr(self, attr)
                if value is not None:
                    globals_[name] = value
                else:
                    raise ValueError('全局变量%s未被赋值' % name)

        signal_locals_ = {}
        function_locals = {}
        signal_globals_ = {}  # 可动态管理的全策略命名空间
        function_globals_ = {}  # 可动态管理的系统函数命名空间
        # 获取并检查一些全局变量的设定
        exec(compile(code, "[Strategy:%s]" % self.name, mode="exec"),
             signal_globals_, signal_locals_)
        get_global_attrs(signal_locals_)
        set_global_attrs(signal_globals_)
        set_global_attrs(function_globals_)
        signal_globals_.update(self.__locals_)
        function_globals_.update(self.__locals_)
        self.engine.set_capital_base(self.capital_base)
        self.engine.start_time = self.start_time
        self.engine.end_time = self.end_time
        check_time_frame(self.time_frame)
        # get the system functions in use
        ast_ = ast.parse(code)
        sys_func_detector = SystemFunctionsDetector()
        sys_func_detector.visit(ast_)
        sys_func_dir = self.user_dir.get_sys_func_dir()
        funcs_in_use = sys_func_detector.get_funcs_in_use()

        # get the instructions to inject to every handle
        signal_instructions = {}
        function_instructions = {}
        code_lines = ["import functools", "__globals = globals()"]
        code_lines.extend([
            "{0} = __globals['{0}']".format(key)
            for key in self.__locals_.keys()
            if key not in ["sell", "buy", "short", "cover"]
        ])
        for key, value in signal_locals_.items():
            if inspect.isfunction(value):
                if key == "init":
                    self.handlers['init'] = value
                    # TODO init中可以设定全局变量,所以要以"global foo"的方式进行注入,监听的事件不同所以要改写SymbolsListener
                    continue
                paras = inspect.signature(value).parameters.copy()
                ishandle = get_parameter_default(paras, "ishandle",
                                                 lambda x: isinstance(x, bool),
                                                 True)
                if not ishandle:
                    continue
                custom = get_parameter_default(paras, "custom",
                                               lambda x: isinstance(x, bool),
                                               False)
                if not custom:
                    # TODO加入真正的验证方法
                    symbols = get_parameter_default(paras, "symbols",
                                                    lambda x: True,
                                                    self.symbols)
                    time_frame = get_parameter_default(paras, "timeframe",
                                                       check_time_frame,
                                                       self.time_frame)
                    max_length = get_parameter_default(
                        paras, "maxlen",
                        lambda x: isinstance(x, int) and (x > 0),
                        self.max_length)
                    self.engine.add_symbols(symbols, time_frame, max_length)
                    self.listeners[key] = SymbolsListener(
                        self.engine, symbols, time_frame)
                    additional_instructions = [
                        "{0} = system_functions['%s.%s'%('{1}','{0}')]".format(
                            f, key) for f in funcs_in_use.keys()
                    ] + ['del(system_functions)']
                    temp = []
                    # TODO 加入opens等,这里字典的嵌套结构
                    temp.extend([
                        "%s = __globals['data']()['%s']['%s']['%s']" %
                        (field, symbols[0], time_frame, field) for field in
                        ["open", "high", "low", "close", "time", "volume"]
                    ])
                    temp.extend([
                        "{0} = __globals['listeners']['{1}'].{0}".format(
                            'get_current_bar', key)
                    ])
                    function_instructions[key] = code_lines + temp + ["del(functools)", "del(__globals)"] + \
                                                 additional_instructions
                    temp.extend([
                        "{0} = functools.partial(__globals['{0}'],listener={1})"
                        .format(field, self.listeners[key].get_id())
                        for field in ["buy", "short", "sell", "cover"]
                    ])
                    signal_instructions[key] = code_lines + temp + ["del(functools)", "del(__globals)"] + \
                                               additional_instructions
                else:
                    # TODO自定义事件处理
                    pass
                for para_name in paras.keys():
                    # TODO加入类型检测
                    default = get_parameter_default(paras,
                                                    para_name,
                                                    lambda x: True,
                                                    None,
                                                    pop=False)
                    if default is None:
                        raise ValueError('参数%s未指定初始值' % para_name)
                    elif not isinstance(default, (int, float)):
                        raise ValueError('参数%s的值必须为整数或浮点数', para_name)
                    self.listeners[key].add_parameters(para_name, default)
        series_exporter = SeriesExporter()  # deal with the export syntax
        # export the system functions in use
        for func, signal in funcs_in_use.items():
            fullname = os.path.join(sys_func_dir, func + ".py")
            with open(fullname) as f:
                func_ast = ast.parse(f.read())
                f.close()
            function_injector = LocalsInjector(
                {func: function_instructions[signal]})
            function_injector.visit(func_ast)
            func_ast = series_exporter.visit(func_ast)
            # TODO 多个handle时需要对每个handle调用的系统函数建立独立的系统函数
            exec(compile(func_ast, "[SysFunctions:%s]" % func, mode="exec"),
                 function_globals_, function_locals)
            self.system_functions['%s.%s' % (signal, func)] = SeriesFunction(
                function_locals[func], signal)
            # new方法是对__init__的封装,创建SeriesFunction对象所需信息有其所在的函数体本身,signal和其运行时传入的参数,
            # 编译时所能确定的只有前者,采用偏函数的方式将两者结合到一起
        # inject global vars into locals of handler
        signal_injector = LocalsInjector(signal_instructions)
        signal_injector.visit(ast_)
        ast_ = series_exporter.visit(ast_)
        # TODO 解决行号的问题
        exec(compile(ast_, "[Strategy:%s]" % self.name, mode="exec"),
             signal_globals_, signal_locals_)
        for key in signal_instructions.keys():
            self.listeners[key].set_generator(signal_locals_[key])
        print("<%s>信号添加成功" % self.name)
        if 'init' in self.handlers:
            self.handlers['init']()
        return True