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 __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"
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
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