Ejemplo n.º 1
0
 def short(self,
           symbol,
           volume=1,
           price=None,
           stop=False,
           limit=False,
           strategy=None,
           listener=None):
     if self.__backtesting:
         time_ = self.__data[symbol][SymbolsListener.get_by_id(
             listener).get_time_frame()]['time'][0]
     else:
         time_ = time.time()
     position = self.__current_positions.get(symbol, None)
     if position and position.type > 0:
         order = Order(symbol, ORDER_TYPE_SELL, strategy, listener)
         order.volume_initial = position.volume
         order.time_setup = int(time_)
         order.time_setup_msc = int((time_ - int(time_)) * (10**6))
         # TODO 这里应该要支持事务性的下单操作
         self.send_order(order)
     if volume == 0:
         return
     order = Order(symbol, ORDER_TYPE_SELL, strategy, listener)
     order.volume_initial = volume
     order.time_setup = int(time_)
     order.time_setup_msc = int((time_ - int(time_)) * (10**6))
     return self.send_order(order)
Ejemplo n.º 2
0
 def cover(self, symbol, volume=1, price=None, stop=False, limit=False, strategy=None, listener=None):
     if volume == 0: return        
     position = self.__current_positions.get(symbol,None)        
     order = Order(symbol, ORDER_TYPE_BUY, strategy, listener)
     if not position or position.type >= 0:
         return#XXX可能的返回值
     order.volume_initial = volume
     if self.__backtesting:
         time_ = self.__datas[symbol][SymbolsListener.get_by_id(listener).get_time_frame()]['time'][0]
     else:
         time_ = time.time()
     order.time_setup = int(time_)
     order.time_setup_msc = int((time_ - int(time_))*(10**6))
     return(self.send_order(order))
Ejemplo n.º 3
0
 def __send_order_to_broker(self,order):
     if self.__backtesting:
         time_frame = SymbolsListener.get_by_id(order.handle).get_time_frame()
         time_ = self.__datas[order.symbol][time_frame]["time"][0]
         order.time_done = int(time_)
         order.time_done_msc = int((time_-int(time_))*(10**6))
         order.volume_current = order.volume_initial
         deal = Deal(order.symbol, order.strategy, order.handle)
         deal.volume = order.volume_current                        
         deal.time = order.time_done
         deal.time_msc = order.time_done_msc
         deal.type = 1-((order.type&1)<<1) #参见ENUM_ORDER_TYPE和ENUM_DEAL_TYPE的定义
         deal.price = self.__datas[order.symbol][time_frame]["close"][0]
         #TODO加入手续费等
         order.deal = deal.get_id()
         deal.order = order.get_id()
         return([deal],{})
         #TODO 市价单成交
     else:
         pass
Ejemplo n.º 4
0
 def cover(self,
           symbol,
           volume=1,
           price=None,
           stop=False,
           limit=False,
           strategy=None,
           listener=None):
     if volume == 0:
         return
     position = self.__current_positions.get(symbol, None)
     order = Order(symbol, ORDER_TYPE_BUY, strategy, listener)
     if not position or position.type >= 0:
         return  # XXX可能的返回值
     order.volume_initial = volume
     if self.__backtesting:
         time_ = self.__data[symbol][SymbolsListener.get_by_id(
             listener).get_time_frame()]['time'][0]
     else:
         time_ = time.time()
     order.time_setup = int(time_)
     order.time_setup_msc = int((time_ - int(time_)) * (10**6))
     return self.send_order(order)
Ejemplo n.º 5
0
 def __send_order_to_broker(self, order):
     if self.__backtesting:
         time_frame = SymbolsListener.get_by_id(
             order.handle).get_time_frame()
         time_ = self.__data[order.symbol][time_frame]["time"][
             0] + time_frame_to_seconds(time_frame)
         order.time_done = int(time_)
         order.time_done_msc = int((time_ - int(time_)) * (10**6))
         order.volume_current = order.volume_initial
         deal = Deal(order.symbol, order.strategy, order.handle)
         deal.volume = order.volume_current
         deal.time = order.time_done
         deal.time_msc = order.time_done_msc
         deal.type = 1 - (
             (order.type & 1) << 1)  # 参见ENUM_ORDER_TYPE和ENUM_DEAL_TYPE的定义
         deal.price = self.__data[order.symbol][time_frame]["close"][0]
         # TODO加入手续费等
         order.deal = deal.get_id()
         deal.order = order.get_id()
         return [deal], {}
         # TODO 市价单成交
     else:
         pass
Ejemplo n.º 6
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