Example #1
0
 def __init__(self, is_backtest=False, **config):
     """Constructor"""
     self.__config = config
     self.__event_engine = EventEngine()  # 事件处理引擎
     if is_backtest:
         self.__account_manager = AccountManager(self, **config)  # 账户管理
     else:
         self.__account_manager = FDTAccountManager(self, **config)
         self.mongo_user = MongoUser(self.__config['user'])
     self.__trade_manager = TradeManager(self, is_backtest, **config)  # 交易管理器
     self.__data_cache = DataCache(self, is_backtest)  # 数据中继站
     self.__strategys = {}  # 策略管理器
     self.__profit_records = []  # 保存账户净值的列表
Example #2
0
 def __init__(self, parent=None):
     """Constructor"""
     LoggerInterface.__init__(self, parent=parent)
     Runnable.__init__(self)
     ConfigInterface.__init__(self, parent=parent)
     APIInterface.__init__(self)
     self.__event_engine = EventEngine(parent=self)  # 事件处理引擎
     self.__quotation_manager = QuotationManager(self, parent=self)  # 行情数据管理器
     if self.config.running_mode == RunningMode.backtest:
         self.__account_manager = BfAccountManager(parent=self)  # 账户管理
     else:
         self.__account_manager = FDTAccountManager(parent=self)
         self.mongo_user = MongoUser(self.config.user)
     self.__trading_manager = TradingManager(self, self.__quotation_manager, self.__account_manager,
                                             parent=self)  # 交易管理器
     if self.config.running_mode == RunningMode.backtest:
         self.__account_manager.set_trading_manager(self.__trading_manager)
     self.__strategys = {}  # 策略管理器
     self.__profit_records = []  # 保存账户净值的列表
     self.logger_name = "StrategyEngine"
Example #3
0
class StrategyEngine(object):
    """策略引擎"""
    CACHE_MAXLEN = 10000

    # ----------------------------------------------------------------------
    def __init__(self, is_backtest=False, **config):
        """Constructor"""
        self.__config = config
        self.__event_engine = EventEngine()  # 事件处理引擎
        if is_backtest:
            self.__account_manager = AccountManager(self, **config)  # 账户管理
        else:
            self.__account_manager = FDTAccountManager(self, **config)
            self.mongo_user = MongoUser(self.__config['user'])
        self.__trade_manager = TradeManager(self, is_backtest, **config)  # 交易管理器
        self.__data_cache = DataCache(self, is_backtest)  # 数据中继站
        self.__strategys = {}  # 策略管理器
        self.__profit_records = []  # 保存账户净值的列表

    def set_account(self, account):
        assert isinstance(account, AccountManager)
        self.__account_manager = account

    def get_data(self):
        return self.__data_cache.data

    def get_symbol_pool(self):
        return self.__data_cache.symbol_pool

    def get_current_positions(self):
        return self.__trade_manager.current_positions

    def get_current_time(self):
        return self.__data_cache.current_time

    def get_positions(self):
        return self.__trade_manager.positions

    def get_deals(self):
        return self.__trade_manager.deals

    def get_strategys(self):
        return self.__strategys

    def get_profit_records(self):
        """获取平仓收益记录"""
        return self.__profit_records

    def get_symbol_timeframe(self):
        return self.__data_cache.get_cache_info().keys()

    def get_capital_cash(self):
        return self.__account_manager.capital_cash

    def get_capital_net(self):
        return self.__account_manager.capital_net

    def get_capital_available(self):
        return self.__account_manager.capital_available

    # XXX之所以不用装饰器的方式是考虑到不知经过一层property会不会影响效率,所以保留用get_XXX直接访问
    # property:
    current_time = property(get_current_time)
    symbol_pool = property(get_symbol_pool)
    data = property(get_data)
    current_positions = property(get_current_positions)
    positions = property(get_positions)
    deal = property(get_deals)
    strategys = property(get_strategys)
    profit_records = property(get_profit_records)
    symbol_timeframe = property(get_symbol_timeframe)
    capital_cash = property(get_capital_cash)
    capital_net = property(get_capital_net)
    capital_available = property(get_capital_available)

    def get_counter_price(self, code, time_frame):
        """
        计算当前对应货币对的报价货币(counter currency)兑美元的价格
        :param code: 品种代码
        :param time_frame: 时间尺度
        :return: 当前对应货币对的报价货币(counter currency)兑美元的价格
        """
        symbol = self.symbol_pool[code]
        if symbol.code.endswith('USD'):  # 间接报价
            base_price = 1
        elif symbol.code.startswith('USD'):  # 直接报价
            base = symbol.code[-3:]
            base_price = 1 / self.data[time_frame]['close']['USD' + base][0]
        else:  # 交叉盘
            base = symbol.code[-3:]
            if base + 'USD' in symbol.ALL.index:
                base_price = self.data[time_frame]['close'][base + 'USD'][0]
            elif 'USD' + base in symbol.ALL.index:
                base_price = 1 / self.data[time_frame]['close']['USD' + base][0]
            else:
                raise ValueError('找不到基准报价:%s' % base)
        return base_price

    def get_base_price(self, code, time_frame):
        """
        计算当前对应货币对的基准货币(base currency)兑美元的价格
        :param code: 品种代码
        :param time_frame: 时间尺度
        :return: 当前对应货币对的报价货币(base currency)兑美元的价格
        """
        symbol = self.symbol_pool[code]
        if symbol.code.startswith('USD'):  # 间接报价
            base_price = 1
        elif symbol.code.endswith('USD'):  # 直接报价
            base = symbol.code[:3]
            base_price = self.data[time_frame]['close'][base + 'USD'][0]
        else:  # 交叉盘
            base = symbol.code[:3]
            if base + 'USD' in symbol.ALL.index:
                base_price = self.data[time_frame]['close'][base + 'USD'][0]
            elif 'USD' + base in symbol.ALL.index:
                base_price = 1 / self.data[time_frame]['close']['USD' + base][0]
            else:
                raise ValueError('找不到基准报价:%s' % base)
        return base_price

    def get_capital(self):
        return self.__account_manager.get_api()

    def profit_record(self, *args, **kwargs):
        return self.__account_manager.profit_record(*args, **kwargs)

    def update_cash(self, deal):
        return self.__account_manager.update_cash(deal)

    def send_order_to_broker(self, order):
        return self.__account_manager.send_order_to_broker(order)

    def order_status(self):
        return self.__account_manager.order_status()

    def position_status(self, *args, **kwargs):
        return self.__account_manager.position_status(*args, **kwargs)

    def open_position(self, *args, **kwargs):
        return self.__trade_manager.open_position(*args, **kwargs)

    def close_position(self, *args, **kwargs):
        return self.__trade_manager.close_position(*args, **kwargs)

    def set_capital_base(self, base):
        self.__account_manager.capital_base = base

    # ----------------------------------------------------------------------
    def add_cache_info(self, *args, **kwargs):
        self.__data_cache.add_cache_info(*args, **kwargs)
        # TODO 从全局的品种池中查询

    # ----------------------------------------------------------------------
    def add_file(self, file):
        self.__event_engine.add_file(file)

    # ----------------------------------------------------------------------
    def add_strategy(self, strategy):
        """添加已创建的策略实例"""
        self.__strategys[strategy.get_id()] = strategy
        strategy.engine = self

    # ----------------------------------------------------------------------
    def put_event(self, event):
        # TODO 加入验证
        # TODO 多了一层函数调用,尝试用绑定的形式
        self.__event_engine.put(event)

    # ----------------------------------------------------------------------
    def register_event(self, event_type, handle):
        """注册事件监听"""
        # TODO  加入验证
        self.__event_engine.register(event_type, handle)

    def unregister_event(self, event_type, handle):
        """取消事件监听"""
        self.__event_engine.unregister(event_type, handle)

    # ----------------------------------------------------------------------
    def write_log(self, log):
        """写日志"""
        self.__event_engine.put(Event(type=EVENT_LOG, log=log))

    # ----------------------------------------------------------------------
    def start(self):
        """启动所有策略"""
        for strategy in self.__strategys.values():
            strategy.start()
        self.__profit_records.clear()
        self.__data_cache.start()
        self.__trade_manager.init()
        self.__event_engine.start()
        self.__account_manager.initialize()

    # ----------------------------------------------------------------------

    def stop(self):
        """停止所有策略"""
        self.__event_engine.stop()
        self.__data_cache.stop()
        for strategy in self.__strategys.values():
            strategy.stop()
        self._recycle()  # 释放资源

    # ----------------------------------------------------------------------

    def _recycle(self):
        self.__data_cache.stop()
        self.__trade_manager.recycle()

    def wait(self, call_back=None, finished=True, *args, **kwargs):
        """等待所有事件处理完毕
        :param call_back: 运行完成时的回调函数
        :param finish: 向下兼容,finish为True时,事件队列处理完成时结束整个回测引擎;为False时只是调用回调函数,继续挂起回测引擎。
        """
        self.__event_engine.wait()
        if call_back:
            result = call_back(*args, **kwargs)
        else:
            result = None
        if finished:
            self.stop()
        return result
Example #4
0
class StrategyEngine(LoggerInterface, Runnable, ConfigInterface, APIInterface):
    """策略引擎"""

    def __init__(self, parent=None):
        """Constructor"""
        LoggerInterface.__init__(self, parent=parent)
        Runnable.__init__(self)
        ConfigInterface.__init__(self, parent=parent)
        APIInterface.__init__(self)
        self.__event_engine = EventEngine(parent=self)  # 事件处理引擎
        self.__quotation_manager = QuotationManager(self, parent=self)  # 行情数据管理器
        if self.config.running_mode == RunningMode.backtest:
            self.__account_manager = BfAccountManager(parent=self)  # 账户管理
        else:
            self.__account_manager = FDTAccountManager(parent=self)
            self.mongo_user = MongoUser(self.config.user)
        self.__trading_manager = TradingManager(self, self.__quotation_manager, self.__account_manager,
                                                parent=self)  # 交易管理器
        if self.config.running_mode == RunningMode.backtest:
            self.__account_manager.set_trading_manager(self.__trading_manager)
        self.__strategys = {}  # 策略管理器
        self.__profit_records = []  # 保存账户净值的列表
        self.logger_name = "StrategyEngine"

    def set_account(self, account):
        assert isinstance(account, AccountManager)
        self.__account_manager = account

    @property
    def current_time(self):
        return self.__quotation_manager.current_time

    @property
    def positions(self):
        return self.__trading_manager.positions

    @property
    def deals(self):
        return self.__trading_manager.deals

    @property
    def strategys(self):
        return self.__strategys

    @property
    def profit_records(self):
        """获取平仓收益记录"""
        return self.__profit_records

    @property
    def max_margin(self):
        return self.__trading_manager.max_margin

    def profit_record(self, *args, **kwargs):
        return self.__account_manager.profit_record(*args, **kwargs)

    def realize_order(self):
        self.__trading_manager.realize_order()

    def add_cache_info(self, *args, **kwargs):
        self.__quotation_manager.add_cache_info(*args, **kwargs)
        # TODO 从全局的品种池中查询

    def add_file(self, file):
        self.__event_engine.add_file(file)

    def add_strategy(self, strategy):
        """添加已创建的策略实例"""
        self.__strategys[strategy.get_id()] = strategy
        strategy.engine = self

    def put_event(self, event):
        # TODO 加入验证
        # TODO 多了一层函数调用,尝试用绑定的形式
        self.__event_engine.put(event)

    def register_event(self, event_type, handle):
        """注册事件监听"""
        # TODO  加入验证
        self.__event_engine.register(event_type, handle)

    def unregister_event(self, event_type, handle):
        """取消事件监听"""
        self.__event_engine.unregister(event_type, handle)

    def write_log(self, log):
        """写日志"""
        self.__event_engine.put(Event(type=EVENT_LOG, log=log))

    def _start(self):
        """启动所有策略"""
        self.__profit_records.clear()
        self.__quotation_manager.start()
        self.__trading_manager.init()
        self.__event_engine.start()
        self.__account_manager.initialize()
        for strategy in self.__strategys.values():
            strategy.start()

    def _stop(self):
        """停止所有策略"""
        for strategy in self.__strategys.values():
            strategy.stop()
        self.__event_engine.stop()
        self.__quotation_manager.stop()
        self._recycle()  # 释放资源

    def _recycle(self):
        self.__quotation_manager.stop()
        self.__trading_manager.recycle()

    # TODO finished的参数设计有点问题
    def wait(self, call_back=None, finished=True, *args, **kwargs):
        """等待所有事件处理完毕
        :param call_back: 运行完成时的回调函数
        :param finished: 向下兼容,finish为True时,事件队列处理完成时结束整个回测引擎;为False时只是调用回调函数,继续挂起回测引擎。
        """
        self.__event_engine.wait()
        if call_back:
            result = call_back(*args, **kwargs)
        else:
            result = None
        if finished:
            self.stop()
        return result

    def get_APIs(self, strategy=None, signal=None, symbols=None, time_frame=None) -> Globals:
        APIs = Globals({}, {})
        APIs.update(self.__account_manager.get_APIs())
        APIs.update(self.__quotation_manager.get_APIs(symbols=symbols, time_frame=time_frame))
        APIs.update(self.__trading_manager.get_APIs(strategy=strategy, signal=signal, symbol=symbols[0]))
        return APIs