Beispiel #1
0
    def validate_trading(self, order, bar):
        order_book_id = order.order_book_id
        trading_date = ExecutionContext.get_current_trading_dt().date()

        if bar.isnan:
            """
            只有未上市/已退市,对应的bar才为NaN
            """
            instrument = ExecutionContext.get_instrument(order_book_id)
            if trading_date < instrument.listed_date.date():
                order._mark_rejected(
                    _("Order Rejected: {order_book_id} is not listed!").format(
                        order_book_id=order_book_id, ))
            elif trading_date > instrument.de_listed_date.date():
                order._mark_rejected(
                    _("Order Rejected: {order_book_id} has been delisted!").
                    format(order_book_id=order_book_id, ))
            else:
                order._mark_rejected(
                    _("Order Rejected: {order_book_id} is not trading!").
                    format(order_book_id=order_book_id, ))
            return False
        elif not bar.is_trading:
            """
            如果bar.is_trading为False,还需要判断是否为停盘,如果不是停牌,则说明交易量为0.
            """
            if bar.suspended:
                order._mark_rejected(
                    _("Order Rejected: {order_book_id} is suspended!").format(
                        order_book_id=order_book_id, ))
                return False
        return True
Beispiel #2
0
 def submit_order(self, order):
     if order.position_effect == POSITION_EFFECT.MATCH:
         raise NotImplementedError(
             _("unsupported position_effect {}").format(
                 order.position_effect))
     account = self._env.get_account(order.order_book_id)
     self._env.event_bus.publish_event(
         Event(EVENT.ORDER_PENDING_NEW, account=account, order=order))
     if order.position_effect == POSITION_EFFECT.EXERCISE:
         return self._open_exercise_orders.append(order)
     if order.is_final():
         return
     if self._env.config.base.frequency == '1d' and not self._match_immediately:
         if ExecutionContext.phase() == EXECUTION_PHASE.OPEN_AUCTION:
             self._open_orders.append((account, order))
             order.active()
         else:
             self._delayed_orders.append((account, order))
         return
     if ExecutionContext.phase() == EXECUTION_PHASE.OPEN_AUCTION:
         self._open_auction_orders.append((account, order))
     else:
         self._open_orders.append((account, order))
     order.active()
     self._env.event_bus.publish_event(
         Event(EVENT.ORDER_CREATION_PASS, account=account, order=order))
     if self._match_immediately:
         self._match()
Beispiel #3
0
    def __getitem__(self, key):
        if not isinstance(key, six.string_types):
            raise patch_user_exc(ValueError('invalid key {} (use order_book_id please)'.format(key)))

        instrument = self._data_proxy.instruments(key)
        if instrument is None:
            raise patch_user_exc(ValueError('invalid order book id or symbol: {}'.format(key)))
        order_book_id = instrument.order_book_id

        try:
            return self._cache[order_book_id]
        except KeyError:
            try:
                if not self._dt:
                    return BarObject(instrument, NANDict, self._dt)
                if ExecutionContext.phase() == EXECUTION_PHASE.OPEN_AUCTION:
                    bar = self._data_proxy.get_open_auction_bar(order_book_id, self._dt)
                else:
                    bar = self._data_proxy.get_bar(order_book_id, self._dt, self._frequency)
            except PermissionError:
                raise
            except Exception as e:
                system_log.exception(e)
                raise patch_user_exc(KeyError(_(u"id_or_symbols {} does not exist").format(key)))
            if bar is None:
                return BarObject(instrument, NANDict, self._dt)
            else:
                self._cache[order_book_id] = bar
                return bar
Beispiel #4
0
    def init(self):
        if self._init:
            with ExecutionContext(EXECUTION_PHASE.ON_INIT):
                with ModifyExceptionFromType(EXC_TYPE.USER_EXC):
                    self._init(self._user_context)

        Environment.get_instance().event_bus.publish_event(
            Event(EVENT.POST_USER_INIT))
 def before_trading_(self, event):
     with ExecutionContext(EXECUTION_PHASE.BEFORE_TRADING):
         self._stage = 'before_trading'
         for day_rule, time_rule, func in self._registry:
             if day_rule() and time_rule():
                 with ModifyExceptionFromType(EXC_TYPE.USER_EXC):
                     func(self._ucontext, None)
         self._stage = None
Beispiel #6
0
 def handle_tick(self, event):
     if self._force_run_before_trading:
         self.before_trading(event)
     else:
         tick = event.tick
         with ExecutionContext(EXECUTION_PHASE.ON_TICK):
             with ModifyExceptionFromType(EXC_TYPE.USER_EXC):
                 self._handle_tick(self._user_context, tick)
Beispiel #7
0
 def handle_bar(self, event):
     if self._force_run_before_trading:
         self.before_trading(event)
     else:
         bar_dict = event.bar_dict
         with ExecutionContext(EXECUTION_PHASE.ON_BAR):
             with ModifyExceptionFromType(EXC_TYPE.USER_EXC):
                 self._handle_bar(self._user_context, bar_dict)
Beispiel #8
0
 def next_bar_(self, event):
     bars = event.bar_dict
     with ExecutionContext(EXECUTION_PHASE.SCHEDULED):
         self._current_minute = self._minutes_since_midnight(self._ucontext.now.hour, self._ucontext.now.minute)
         for day_rule, time_rule, func in self._registry:
             if day_rule() and time_rule():
                 with ModifyExceptionFromType(EXC_TYPE.USER_EXC):
                     func(self._ucontext, bars)
         self._last_minute = self._current_minute
Beispiel #9
0
    def end(self):
        if not self._end:
            return

        with ExecutionContext(EXECUTION_PHASE.FINALIZED):
            with ModifyExceptionFromType(EXC_TYPE.USER_EXC):
                self._end(self._user_context)

        Environment.get_instance().event_bus.publish_event(
            Event(EVENT.POST_USER_END))
Beispiel #10
0
def current_snapshot(id_or_symbol):
    """
    获得当前市场快照数据。只能在日内交易阶段调用,获取当日调用时点的市场快照数据。
    市场快照数据记录了每日从开盘到当前的数据信息,可以理解为一个动态的day bar数据。
    在目前分钟回测中,快照数据为当日所有分钟线累积而成,一般情况下,最后一个分钟线获取到的快照数据应当与当日的日线行情保持一致。
    需要注意,在实盘模拟中,该函数返回的是调用当时的市场快照情况,所以在同一个handle_bar中不同时点调用可能返回的数据不同。
    如果当日截止到调用时候对应股票没有任何成交,那么snapshot中的close, high, low, last几个价格水平都将以0表示。

    :param str order_book_id: 合约代码或简称

    :return: :class:`~Snapshot`

    :example:

    在handle_bar中调用该函数,假设策略当前时间是20160104 09:33:

    ..  code-block:: python3
        :linenos:

        [In]
        logger.info(current_snapshot('000001.XSHE'))
        [Out]
        2016-01-04 09:33:00.00  INFO
        Snapshot(order_book_id: '000001.XSHE', datetime: datetime.datetime(2016, 1, 4, 9, 33), open: 10.0, high: 10.025, low: 9.9667, last: 9.9917, volume: 2050320, total_turnover: 20485195, prev_close: 9.99)
    """
    env = Environment.get_instance()
    frequency = env.config.base.frequency
    order_book_id = assure_order_book_id(id_or_symbol)

    dt = env.calendar_dt

    if env.config.base.run_type == RUN_TYPE.BACKTEST:
        if ExecutionContext.phase() == EXECUTION_PHASE.BEFORE_TRADING:
            dt = env.data_proxy.get_previous_trading_date(
                env.trading_dt.date())
            return env.data_proxy.current_snapshot(order_book_id, "1d", dt)
        elif ExecutionContext.phase() == EXECUTION_PHASE.AFTER_TRADING:
            return env.data_proxy.current_snapshot(order_book_id, "1d", dt)

    # PT、实盘直接取最新快照,忽略 frequency, dt 参数
    return env.data_proxy.current_snapshot(order_book_id, frequency, dt)
Beispiel #11
0
def current_snapshot(id_or_symbol):
    """
    获得当前市场快照数据。只能在日内交易阶段调用,获取当日调用时点的市场快照数据。
    市场快照数据记录了每日从开盘到当前的数据信息,可以理解为一个动态的day bar数据。
    在目前分钟回测中,快照数据为当日所有分钟线累积而成,一般情况下,最后一个分钟线获取到的快照数据应当与当日的日线行情保持一致。
    需要注意,在实盘模拟中,该函数返回的是调用当时的市场快照情况,所以在同一个handle_bar中不同时点调用可能返回的数据不同。
    如果当日截止到调用时候对应股票没有任何成交,那么snapshot中的close, high, low, last几个价格水平都将以0表示。

    :param str order_book_id: 合约代码或简称

    :return: :class:`~Snapshot`

    :example:

    在handle_bar中调用该函数,假设策略当前时间是20160104 09:33:

    ..  code-block:: python3
        :linenos:

        [In]
        logger.info(current_snapshot('000001.XSHE'))
        [Out]
        2016-01-04 09:33:00.00  INFO
        Snapshot(order_book_id: '000001.XSHE', datetime: datetime.datetime(2016, 1, 4, 9, 33), open: 10.0, high: 10.025, low: 9.9667, last: 9.9917, volume: 2050320, total_turnover: 20485195, prev_close: 9.99)
    """
    env = Environment.get_instance()
    frequency = env.config.base.frequency
    order_book_id = assure_order_book_id(id_or_symbol)

    dt = env.calendar_dt

    if env.config.base.run_type == RUN_TYPE.BACKTEST:
        if ExecutionContext.phase() == EXECUTION_PHASE.BEFORE_TRADING:
            dt = env.data_proxy.get_previous_trading_date(env.trading_dt.date())
            return env.data_proxy.current_snapshot(order_book_id, "1d", dt)
        elif ExecutionContext.phase() == EXECUTION_PHASE.AFTER_TRADING:
            return env.data_proxy.current_snapshot(order_book_id, "1d", dt)

    # PT、实盘直接取最新快照,忽略 frequency, dt 参数
    return env.data_proxy.current_snapshot(order_book_id, frequency, dt)
Beispiel #12
0
    def order_pipeline(self, account, order):
        order_book_id = order.order_book_id
        bar_dict = ExecutionContext.get_current_bar_dict()
        portfolio = account.portfolio
        position = portfolio.positions[order_book_id]
        bar = bar_dict[order_book_id]

        if not self.validate_trading(order, bar):
            return False
        if not self.validate_available_cash(order, account, bar):
            return False
        if not self.validate_available_position(order, position):
            return False
        return True
Beispiel #13
0
    def mavg(self, intervals, frequency='1d'):
        if frequency == 'day':
            frequency = '1d'
        if frequency == 'minute':
            frequency = '1m'

        # copy form history
        env = Environment.get_instance()
        dt = env.calendar_dt

        if (env.config.base.frequency == '1m' and frequency == '1d') or ExecutionContext.phase() == EXECUTION_PHASE.BEFORE_TRADING:
            # 在分钟回测获取日线数据, 应该推前一天
            dt = env.data_proxy.get_previous_trading_date(env.calendar_dt.date())
        bars = env.data_proxy.fast_history(self._instrument.order_book_id, intervals, frequency, 'close', dt)
        return bars.mean()
Beispiel #14
0
    def mavg(self, intervals, frequency='1d'):
        if frequency == 'day':
            frequency = '1d'
        if frequency == 'minute':
            frequency = '1m'

        # copy form history
        env = Environment.get_instance()
        dt = env.calendar_dt

        if (env.config.base.frequency == '1m' and frequency == '1d') or ExecutionContext.phase() == EXECUTION_PHASE.BEFORE_TRADING:
            # 在分钟回测获取日线数据, 应该推前一天
            dt = env.data_proxy.get_previous_trading_date(env.calendar_dt.date())
        bars = env.data_proxy.fast_history(self._instrument.order_book_id, intervals, frequency, 'close', dt)
        return bars.mean()
Beispiel #15
0
 def _history_bars(self, order_book_id, bar_count, freq, dt):
     if self.fetch_data_by_api and ExecutionContext.phase() in (
             EXECUTION_PHASE.BEFORE_TRADING,
             EXECUTION_PHASE.ON_BAR,
             EXECUTION_PHASE.ON_TICK,
             EXECUTION_PHASE.AFTER_TRADING,
             EXECUTION_PHASE.SCHEDULED):
             bars = history_bars(
                 order_book_id, bar_count, freq, fields=None)
     else:
         bars = self.rqalpha_env.data_proxy.history_bars(
             order_book_id, bar_count, freq,
             field=["datetime", "open", "high", "low", "close", "volume"],
             dt=dt)
     return bars
Beispiel #16
0
 def _history_bars(self, order_book_id, bar_count, freq, dt):
     if self.fetch_data_by_api and ExecutionContext.phase() in (
             EXECUTION_PHASE.BEFORE_TRADING,
             EXECUTION_PHASE.ON_BAR,
             EXECUTION_PHASE.ON_TICK,
             EXECUTION_PHASE.AFTER_TRADING,
             EXECUTION_PHASE.SCHEDULED):
             bars = history_bars(
                 order_book_id, bar_count, freq, fields=None)
     else:
         bars = self.rqalpha_env.data_proxy.history_bars(
             order_book_id, bar_count, freq,
             field=["datetime", "open", "high", "low", "close", "volume"],
             dt=dt)
     return bars
Beispiel #17
0
    def vwap(self, intervals, frequency='1d'):
        if frequency == 'day':
            frequency = '1d'
        if frequency == 'minute':
            frequency = '1m'

        # copy form history
        env = Environment.get_instance()
        dt = env.calendar_dt

        if (env.config.base.frequency == '1m' and frequency == '1d') or ExecutionContext.phase() == EXECUTION_PHASE.BEFORE_TRADING:
            # 在分钟回测获取日线数据, 应该推前一天
            dt = env.data_proxy.get_previous_trading_date(env.calendar_dt.date())
        bars = env.data_proxy.fast_history(self._instrument.order_book_id, intervals, frequency, ['close', 'volume'], dt)
        sum = bars['volume'].sum()
        if sum == 0:
            # 全部停牌
            return 0

        return np.dot(bars['close'], bars['volume']) / sum
Beispiel #18
0
    def vwap(self, intervals, frequency='1d'):
        if frequency == 'day':
            frequency = '1d'
        if frequency == 'minute':
            frequency = '1m'

        # copy form history
        env = Environment.get_instance()
        dt = env.calendar_dt

        if (env.config.base.frequency == '1m' and frequency == '1d') or ExecutionContext.phase() == EXECUTION_PHASE.BEFORE_TRADING:
            # 在分钟回测获取日线数据, 应该推前一天
            dt = env.data_proxy.get_previous_trading_date(env.calendar_dt.date())
        bars = env.data_proxy.fast_history(self._instrument.order_book_id, intervals, frequency, ['close', 'volume'], dt)
        sum = bars['volume'].sum()
        if sum == 0:
            # 全部停牌
            return 0

        return np.dot(bars['close'], bars['volume']) / sum
Beispiel #19
0
def run(config, source_code=None, user_funcs=None):
    env = Environment(config)
    persist_helper = None
    init_succeed = False
    mod_handler = ModHandler()

    try:
        # avoid register handlers everytime
        # when running in ipython
        set_loggers(config)
        basic_system_log.debug("\n" + pformat(config.convert_to_dict()))

        if source_code is not None:
            env.set_strategy_loader(SourceCodeStrategyLoader(source_code))
        elif user_funcs is not None:
            env.set_strategy_loader(UserFuncStrategyLoader(user_funcs))
        else:
            env.set_strategy_loader(FileStrategyLoader(config.base.strategy_file))
        env.set_global_vars(GlobalVars())
        mod_handler.set_env(env)
        mod_handler.start_up()

        if not env.data_source:
            env.set_data_source(BaseDataSource(config.base.data_bundle_path))
        env.set_data_proxy(DataProxy(env.data_source))

        Scheduler.set_trading_dates_(env.data_source.get_trading_calendar())
        scheduler = Scheduler(config.base.frequency)
        mod_scheduler._scheduler = scheduler

        env._universe = StrategyUniverse()

        _adjust_start_date(env.config, env.data_proxy)

        _validate_benchmark(env.config, env.data_proxy)

        # FIXME
        start_dt = datetime.datetime.combine(config.base.start_date, datetime.datetime.min.time())
        env.calendar_dt = start_dt
        env.trading_dt = start_dt

        broker = env.broker
        assert broker is not None
        env.portfolio = broker.get_portfolio()
        env.benchmark_portfolio = create_benchmark_portfolio(env)

        event_source = env.event_source
        assert event_source is not None

        bar_dict = BarMap(env.data_proxy, config.base.frequency)
        env.set_bar_dict(bar_dict)

        if env.price_board is None:
            from .core.bar_dict_price_board import BarDictPriceBoard
            env.price_board = BarDictPriceBoard()

        ctx = ExecutionContext(const.EXECUTION_PHASE.GLOBAL)
        ctx._push()

        env.event_bus.publish_event(Event(EVENT.POST_SYSTEM_INIT))

        scope = create_base_scope()
        scope.update({
            "g": env.global_vars
        })

        apis = api_helper.get_apis()
        scope.update(apis)

        scope = env.strategy_loader.load(scope)

        if env.config.extra.enable_profiler:
            enable_profiler(env, scope)

        ucontext = StrategyContext()
        user_strategy = Strategy(env.event_bus, scope, ucontext)
        scheduler.set_user_context(ucontext)

        if not config.extra.force_run_init_when_pt_resume:
            with run_with_user_log_disabled(disabled=config.base.resume_mode):
                user_strategy.init()

        if config.extra.context_vars:
            for k, v in six.iteritems(config.extra.context_vars):
                setattr(ucontext, k, v)

        if config.base.persist:
            persist_provider = env.persist_provider
            persist_helper = PersistHelper(persist_provider, env.event_bus, config.base.persist_mode)
            persist_helper.register('core', CoreObjectsPersistProxy(scheduler))
            persist_helper.register('user_context', ucontext)
            persist_helper.register('global_vars', env.global_vars)
            persist_helper.register('universe', env._universe)
            if isinstance(event_source, Persistable):
                persist_helper.register('event_source', event_source)
            persist_helper.register('portfolio', env.portfolio)
            if env.benchmark_portfolio:
                persist_helper.register('benchmark_portfolio', env.benchmark_portfolio)
            for name, module in six.iteritems(env.mod_dict):
                if isinstance(module, Persistable):
                    persist_helper.register('mod_{}'.format(name), module)
            # broker will restore open orders from account
            if isinstance(broker, Persistable):
                persist_helper.register('broker', broker)

            persist_helper.restore()
            env.event_bus.publish_event(Event(EVENT.POST_SYSTEM_RESTORED))

        init_succeed = True

        # When force_run_init_when_pt_resume is active,
        # we should run `init` after restore persist data
        if config.extra.force_run_init_when_pt_resume:
            assert config.base.resume_mode == True
            with run_with_user_log_disabled(disabled=False):
                user_strategy.init()

        from .core.executor import Executor
        Executor(env).run(bar_dict)

        if env.profile_deco:
            output_profile_result(env)
    except CustomException as e:
        if init_succeed and env.config.base.persist and persist_helper:
            persist_helper.persist()

        code = _exception_handler(e)
        mod_handler.tear_down(code, e)
    except Exception as e:
        if init_succeed and env.config.base.persist and persist_helper:
            persist_helper.persist()

        exc_type, exc_val, exc_tb = sys.exc_info()
        user_exc = create_custom_exception(exc_type, exc_val, exc_tb, config.base.strategy_file)

        code = _exception_handler(user_exc)
        mod_handler.tear_down(code, user_exc)
    else:
        result = mod_handler.tear_down(const.EXIT_CODE.EXIT_SUCCESS)
        system_log.debug(_(u"strategy run successfully, normal exit"))
        return result
Beispiel #20
0
def run(config, source_code=None, user_funcs=None):
    env = Environment(config)
    persist_helper = None
    init_succeed = False
    mod_handler = ModHandler()  #初始化模块处理器,包含list和dict,存储模块名和配置信息

    try:
        # avoid register handlers everytime
        # when running in ipython
        set_loggers(config)
        basic_system_log.debug("\n" + pformat(config.convert_to_dict()))

        if source_code is not None:
            env.set_strategy_loader(SourceCodeStrategyLoader(source_code))
        elif user_funcs is not None:
            env.set_strategy_loader(UserFuncStrategyLoader(user_funcs))
        else:  #将文件路径赋予env中的属性
            env.set_strategy_loader(
                FileStrategyLoader(config.base.strategy_file))
        env.set_global_vars(GlobalVars())
        mod_handler.set_env(env)  #根据config读取mod,并绑定到env变量
        mod_handler.start_up()  #运行每个mod的启动函数,传入env.config,以及mod自己的config,后者冗余?

        if not env.data_source:
            env.set_data_source(data_k_bar)  #BaseDataSource:读取bar数据,存储到对象属性中
        env.set_data_proxy(DataProxy(env.data_source))

        Scheduler.set_trading_dates_(env.data_source.get_trading_calendar())
        scheduler = Scheduler(config.base.frequency)
        mod_scheduler._scheduler = scheduler

        env._universe = StrategyUniverse()

        _adjust_start_date(env.config, env.data_proxy)

        _validate_benchmark(env.config, env.data_proxy)

        # FIXME
        start_dt = datetime.datetime.combine(config.base.start_date,
                                             datetime.datetime.min.time())
        env.calendar_dt = start_dt
        env.trading_dt = start_dt

        broker = env.broker
        assert broker is not None
        env.portfolio = broker.get_portfolio()
        env.benchmark_portfolio = create_benchmark_portfolio(env)

        event_source = env.event_source
        assert event_source is not None
        #包含 data_proxy, frequency ...
        bar_dict = BarMap(env.data_proxy, config.base.frequency)
        env.set_bar_dict(bar_dict)  #本地历史行情对象,包含所有
        #获取最新价格
        if env.price_board is None:
            from .core.bar_dict_price_board import BarDictPriceBoard
            env.price_board = BarDictPriceBoard()

        ctx = ExecutionContext(const.EXECUTION_PHASE.GLOBAL)
        ctx._push()

        env.event_bus.publish_event(Event(EVENT.POST_SYSTEM_INIT))
        #全局文件路径、文件名、log入口等,作为参数传递给编译
        scope = create_base_scope()
        scope.update({"g": env.global_vars})
        #用户策略可调用的api,包括历史行情、下单函数等
        apis = api_helper.get_apis()
        scope.update(apis)
        #加载用户策略文件,并执行?
        scope = env.strategy_loader.load(scope)
        #是否启用性能分析
        if env.config.extra.enable_profiler:
            enable_profiler(env, scope)
        #生成用户策略运行时上下文变量
        ucontext = StrategyContext()
        user_strategy = Strategy(env.event_bus, scope, ucontext)
        scheduler.set_user_context(ucontext)
        #没有若策略运行时数据持久化,运行用户init
        if not config.extra.force_run_init_when_pt_resume:
            with run_with_user_log_disabled(disabled=config.base.resume_mode):
                user_strategy.init()
        #是否在参数中存在用户输入的运行时环境变量
        if config.extra.context_vars:
            for k, v in six.iteritems(config.extra.context_vars):
                setattr(ucontext, k, v)

        if config.base.persist:
            persist_provider = env.persist_provider
            if persist_provider is None:
                raise RuntimeError(
                    _(u"Missing persist provider. You need to set persist_provider before use persist"
                      ))
            persist_helper = PersistHelper(persist_provider, env.event_bus,
                                           config.base.persist_mode)
            env.set_persist_helper(persist_helper)
            persist_helper.register('core', CoreObjectsPersistProxy(scheduler))
            persist_helper.register('user_context', ucontext)
            persist_helper.register('global_vars', env.global_vars)
            persist_helper.register('universe', env._universe)
            if isinstance(event_source, Persistable):
                persist_helper.register('event_source', event_source)
            persist_helper.register('portfolio', env.portfolio)
            if env.benchmark_portfolio:
                persist_helper.register('benchmark_portfolio',
                                        env.benchmark_portfolio)
            for name, module in six.iteritems(env.mod_dict):
                if isinstance(module, Persistable):
                    persist_helper.register('mod_{}'.format(name), module)
            # broker will restore open orders from account
            if isinstance(broker, Persistable):
                persist_helper.register('broker', broker)

            env.event_bus.publish_event(Event(EVENT.BEFORE_SYSTEM_RESTORED))
            persist_helper.restore()
            env.event_bus.publish_event(Event(EVENT.POST_SYSTEM_RESTORED))

        init_succeed = True
        #若启用回测数据持久化,恢复时重新初始化用户策略
        # When force_run_init_when_pt_resume is active,
        # we should run `init` after restore persist data
        if config.extra.force_run_init_when_pt_resume:
            assert config.base.resume_mode == True
            with run_with_user_log_disabled(disabled=False):
                env._universe._set = set()
                user_strategy.init()

        from .core.executor import Executor
        Executor(env).run(bar_dict)

        if env.profile_deco:
            output_profile_result(env)
    except CustomException as e:
        if init_succeed and env.config.base.persist and persist_helper and env.config.base.persist_mode == const.PERSIST_MODE.ON_CRASH:
            persist_helper.persist()

        code = _exception_handler(e)
        mod_handler.tear_down(code, e)
    except Exception as e:
        if init_succeed and env.config.base.persist and persist_helper and env.config.base.persist_mode == const.PERSIST_MODE.ON_CRASH:
            persist_helper.persist()

        exc_type, exc_val, exc_tb = sys.exc_info()
        user_exc = create_custom_exception(exc_type, exc_val, exc_tb,
                                           config.base.strategy_file)

        code = _exception_handler(user_exc)
        mod_handler.tear_down(code, user_exc)
    else:
        if (env.config.base.persist and persist_helper
                and env.config.base.persist_mode
                == const.PERSIST_MODE.ON_NORMAL_EXIT):
            persist_helper.persist()
        result = mod_handler.tear_down(const.EXIT_CODE.EXIT_SUCCESS)
        system_log.debug(_(u"strategy run successfully, normal exit"))
        return result
Beispiel #21
0
 def _get_bar(self, order_book_id):
     if ExecutionContext.phase() == EXECUTION_PHASE.OPEN_AUCTION:
         return self._env.data_proxy.get_open_auction_bar(
             order_book_id, self._env.calendar_dt)
     return self._env.get_bar(order_book_id)
Beispiel #22
0
 def after_trading(self, event):
     with ExecutionContext(EXECUTION_PHASE.AFTER_TRADING):
         with ModifyExceptionFromType(EXC_TYPE.USER_EXC):
             self._after_trading(self._user_context)
Beispiel #23
0
 def before_trading(self, event):
     self._force_run_before_trading = False
     with ExecutionContext(EXECUTION_PHASE.BEFORE_TRADING):
         with ModifyExceptionFromType(EXC_TYPE.USER_EXC):
             self._before_trading(self._user_context)
Beispiel #24
0
 def handle_bar(self, event):
     bar_dict = event.bar_dict
     with ExecutionContext(EXECUTION_PHASE.ON_BAR):
         with ModifyExceptionFromType(EXC_TYPE.USER_EXC):
             self._handle_bar(self._user_context, bar_dict)
Beispiel #25
0
def history_bars(
    order_book_id,
    bar_count,
    frequency,
    fields=None,
    skip_suspended=True,
    include_now=False,
    adjust_type="pre",
):
    # type: (str, int, str, Optional[str], Optional[bool], Optional[bool], Optional[str]) -> np.ndarray
    """
    获取指定合约的历史 k 线行情,同时支持日以及分钟历史数据。不能在init中调用。

    日回测获取分钟历史数据:不支持

    日回测获取日历史数据

    =========================   ===================================================
    调用时间                      返回数据
    =========================   ===================================================
    T日before_trading            T-1日day bar
    T日handle_bar                T日day bar
    =========================   ===================================================

    分钟回测获取日历史数据

    =========================   ===================================================
    调用时间                      返回数据
    =========================   ===================================================
    T日before_trading            T-1日day bar
    T日handle_bar                T-1日day bar
    =========================   ===================================================

    分钟回测获取分钟历史数据

    =========================   ===================================================
    调用时间                      返回数据
    =========================   ===================================================
    T日before_trading            T-1日最后一个minute bar
    T日handle_bar                T日当前minute bar
    =========================   ===================================================

    :param order_book_id: 合约代码
    :param bar_count: 获取的历史数据数量,必填项
    :param frequency: 获取数据什么样的频率进行。'1d'或'1m'分别表示每日和每分钟,必填项
    :param fields: 返回数据字段。必填项。见下方列表。
    :param skip_suspended: 是否跳过停牌数据
    :param include_now: 是否包含当前数据
    :param adjust_type: 复权类型,默认为前复权 pre;可选 pre, none, post

    =========================   ===================================================
    fields                      字段名
    =========================   ===================================================
    datetime                    时间戳
    open                        开盘价
    high                        最高价
    low                         最低价
    close                       收盘价
    volume                      成交量
    total_turnover              成交额
    open_interest               持仓量(期货专用)
    basis_spread                期现差(股指期货专用)
    settlement                  结算价(期货日线专用)
    prev_settlement             结算价(期货日线专用)
    =========================   ===================================================

    :example:

    获取最近5天的日线收盘价序列(策略当前日期为20160706):

    ..  code-block:: python3
        :linenos:

        [In]
        logger.info(history_bars('000002.XSHE', 5, '1d', 'close'))
        [Out]
        [ 8.69  8.7   8.71  8.81  8.81]
    """
    order_book_id = assure_order_book_id(order_book_id)
    env = Environment.get_instance()
    dt = env.calendar_dt

    if frequency[-1] not in {"m", "d"}:
        raise RQInvalidArgument("invalid frequency {}".format(frequency))

    if frequency[-1] == "m" and env.config.base.frequency == "1d":
        raise RQInvalidArgument("can not get minute history in day back test")

    if frequency[-1] == "d" and frequency != "1d":
        raise RQInvalidArgument("invalid frequency")

    if adjust_type not in {"pre", "post", "none"}:
        raise RuntimeError("invalid adjust_type")

    if frequency == "1d":
        sys_frequency = Environment.get_instance().config.base.frequency
        if (sys_frequency in ["1m", "tick"] and not include_now
                and ExecutionContext.phase() != EXECUTION_PHASE.AFTER_TRADING
            ) or (ExecutionContext.phase() in (EXECUTION_PHASE.BEFORE_TRADING,
                                               EXECUTION_PHASE.OPEN_AUCTION)):
            dt = env.data_proxy.get_previous_trading_date(
                env.trading_dt.date())
            # 当 EXECUTION_PHASE.BEFORE_TRADING 的时候,强制 include_now 为 False
            include_now = False
        if sys_frequency == "1d":
            # 日回测不支持 include_now
            include_now = False

    if fields is None:
        fields = ["datetime", "open", "high", "low", "close", "volume"]

    return env.data_proxy.history_bars(
        order_book_id,
        bar_count,
        frequency,
        fields,
        dt,
        skip_suspended=skip_suspended,
        include_now=include_now,
        adjust_type=adjust_type,
        adjust_orig=env.trading_dt,
    )
Beispiel #26
0
 def wrapped_handler(event):
     with ExecutionContext(EXECUTION_PHASE.GLOBAL):
         with ModifyExceptionFromType(EXC_TYPE.USER_EXC):
             return handler(self._user_context, event)
Beispiel #27
0
def run(config, source_code=None, user_funcs=None):
    env = Environment(config)
    persist_helper = None
    init_succeed = False
    mod_handler = ModHandler()

    try:
        # avoid register handlers everytime
        # when running in ipython
        set_loggers(config)
        init_rqdatac(getattr(config.base, 'rqdatac_uri', None))
        system_log.debug("\n" + pformat(config.convert_to_dict()))

        env.set_strategy_loader(
            init_strategy_loader(env, source_code, user_funcs, config))
        mod_handler.set_env(env)
        mod_handler.start_up()

        if not env.data_source:
            env.set_data_source(
                BaseDataSource(config.base.data_bundle_path,
                               getattr(config.base, "future_info", {})))
        if env.price_board is None:
            from rqalpha.data.bar_dict_price_board import BarDictPriceBoard
            env.price_board = BarDictPriceBoard()
        env.set_data_proxy(DataProxy(env.data_source, env.price_board))

        _adjust_start_date(env.config, env.data_proxy)

        # FIXME
        start_dt = datetime.datetime.combine(config.base.start_date,
                                             datetime.datetime.min.time())
        env.calendar_dt = start_dt
        env.trading_dt = start_dt

        assert env.broker is not None
        assert env.event_source is not None
        if env.portfolio is None:
            from rqalpha.portfolio import Portfolio
            env.set_portfolio(
                Portfolio(config.base.accounts, config.base.init_positions))

        ctx = ExecutionContext(const.EXECUTION_PHASE.GLOBAL)
        ctx._push()

        env.event_bus.publish_event(Event(EVENT.POST_SYSTEM_INIT))

        scope = create_base_scope()
        scope.update({"g": env.global_vars})
        scope.update(get_strategy_apis())
        scope = env.strategy_loader.load(scope)

        if config.extra.enable_profiler:
            enable_profiler(env, scope)

        ucontext = StrategyContext()
        executor = Executor(env)

        persist_helper = init_persist_helper(env, ucontext, executor, config)
        user_strategy = Strategy(env.event_bus, scope, ucontext)
        env.user_strategy = user_strategy

        env.event_bus.publish_event(Event(EVENT.BEFORE_STRATEGY_RUN))
        if persist_helper:
            with LogCapture(user_log) as log_capture:
                user_strategy.init()
        else:
            user_strategy.init()

        if config.extra.context_vars:
            for k, v in six.iteritems(config.extra.context_vars):
                if isinstance(v, RqAttrDict):
                    v = v.__dict__
                setattr(ucontext, k, v)

        if persist_helper:
            env.event_bus.publish_event(Event(EVENT.BEFORE_SYSTEM_RESTORED))
            if persist_helper.restore(None):
                user_system_log.info(_('system restored'))
            else:
                log_capture.replay()
            env.event_bus.publish_event(Event(EVENT.POST_SYSTEM_RESTORED))

        init_succeed = True

        bar_dict = BarMap(env.data_proxy, config.base.frequency)
        executor.run(bar_dict)
        env.event_bus.publish_event(Event(EVENT.POST_STRATEGY_RUN))

        if env.profile_deco:
            output_profile_result(env)
    except CustomException as e:
        if init_succeed and persist_helper and env.config.base.persist_mode == const.PERSIST_MODE.ON_CRASH:
            persist_helper.persist()

        code = _exception_handler(e)
        mod_handler.tear_down(code, e)
    except Exception as e:
        if init_succeed and persist_helper and env.config.base.persist_mode == const.PERSIST_MODE.ON_CRASH:
            persist_helper.persist()

        exc_type, exc_val, exc_tb = sys.exc_info()
        user_exc = create_custom_exception(exc_type, exc_val, exc_tb,
                                           config.base.strategy_file)

        code = _exception_handler(user_exc)
        mod_handler.tear_down(code, user_exc)
    else:
        if persist_helper and env.config.base.persist_mode == const.PERSIST_MODE.ON_NORMAL_EXIT:
            persist_helper.persist()
        result = mod_handler.tear_down(const.EXIT_CODE.EXIT_SUCCESS)
        system_log.debug(_(u"strategy run successfully, normal exit"))
        return result
Beispiel #28
0
 def handle_tick(self, event):
     tick = event.tick
     with ExecutionContext(EXECUTION_PHASE.ON_TICK):
         with ModifyExceptionFromType(EXC_TYPE.USER_EXC):
             self._handle_tick(self._user_context, tick)
Beispiel #29
0
 def open_auction(self, event):
     bar_dict = event.bar_dict
     with ExecutionContext(EXECUTION_PHASE.OPEN_AUCTION):
         with ModifyExceptionFromType(EXC_TYPE.USER_EXC):
             self._open_auction(self._user_context, bar_dict)
Beispiel #30
0
def run(config, source_code=None, user_funcs=None):
    env = Environment(config)
    persist_helper = None
    init_succeed = False
    mod_handler = ModHandler()

    try:
        # avoid register handlers everytime
        # when running in ipython
        set_loggers(config)
        basic_system_log.debug("\n" + pformat(config.convert_to_dict()))

        env.set_strategy_loader(
            init_strategy_loader(env, source_code, user_funcs, config))
        env.set_global_vars(GlobalVars())
        mod_handler.set_env(env)
        mod_handler.start_up()

        try:
            future_info = config.base.future_info
        except AttributeError:
            pass
        else:
            deep_update(future_info, future_info_cn.CN_FUTURE_INFO)

        if not env.data_source:
            env.set_data_source(BaseDataSource(config.base.data_bundle_path))

        if env.price_board is None:
            from .core.bar_dict_price_board import BarDictPriceBoard
            env.price_board = BarDictPriceBoard()

        env.set_data_proxy(DataProxy(env.data_source, env.price_board))

        Scheduler.set_trading_dates_(env.data_source.get_trading_calendar())
        scheduler = Scheduler(config.base.frequency)
        mod_scheduler._scheduler = scheduler

        env._universe = StrategyUniverse()

        _adjust_start_date(env.config, env.data_proxy)

        # FIXME
        start_dt = datetime.datetime.combine(config.base.start_date,
                                             datetime.datetime.min.time())
        env.calendar_dt = start_dt
        env.trading_dt = start_dt

        broker = env.broker
        assert broker is not None
        env.portfolio = broker.get_portfolio()
        if env.benchmark_provider:
            env.benchmark_portfolio = BenchmarkPortfolio(
                env.benchmark_provider, env.portfolio.units)

        event_source = env.event_source
        assert event_source is not None

        bar_dict = BarMap(env.data_proxy, config.base.frequency)
        env.set_bar_dict(bar_dict)

        ctx = ExecutionContext(const.EXECUTION_PHASE.GLOBAL)
        ctx._push()

        env.event_bus.publish_event(Event(EVENT.POST_SYSTEM_INIT))

        scope = create_base_scope(config.base.run_type == RUN_TYPE.BACKTEST)
        scope.update({"g": env.global_vars})

        apis = api_helper.get_apis()
        scope.update(apis)

        scope = env.strategy_loader.load(scope)

        if env.config.extra.enable_profiler:
            enable_profiler(env, scope)

        ucontext = StrategyContext()
        scheduler.set_user_context(ucontext)

        from .core.executor import Executor
        executor = Executor(env)

        persist_helper = init_persist_helper(env, scheduler, ucontext,
                                             executor, config)

        if persist_helper:
            should_resume = persist_helper.should_resume()
            should_run_init = persist_helper.should_run_init()
        else:
            should_resume = False
            should_run_init = True

        user_strategy = Strategy(env.event_bus, scope, ucontext,
                                 should_run_init)
        env.user_strategy = user_strategy

        if (should_resume and not should_run_init) or not should_resume:
            with run_with_user_log_disabled(disabled=should_resume):
                user_strategy.init()

        if config.extra.context_vars:
            for k, v in six.iteritems(config.extra.context_vars):
                if isinstance(v, RqAttrDict):
                    v = v.__dict__
                setattr(ucontext, k, v)

        if persist_helper:
            env.event_bus.publish_event(Event(EVENT.BEFORE_SYSTEM_RESTORED))
            env.event_bus.publish_event(Event(EVENT.DO_RESTORE))
            env.event_bus.publish_event(Event(EVENT.POST_SYSTEM_RESTORED))

        init_succeed = True

        if should_resume and should_run_init:
            user_strategy.init()

        executor.run(bar_dict)

        if env.profile_deco:
            output_profile_result(env)
    except CustomException as e:
        if init_succeed and persist_helper and env.config.base.persist_mode == const.PERSIST_MODE.ON_CRASH:
            persist_helper.persist()

        code = _exception_handler(e)
        mod_handler.tear_down(code, e)
    except Exception as e:
        if init_succeed and persist_helper and env.config.base.persist_mode == const.PERSIST_MODE.ON_CRASH:
            persist_helper.persist()

        exc_type, exc_val, exc_tb = sys.exc_info()
        user_exc = create_custom_exception(exc_type, exc_val, exc_tb,
                                           config.base.strategy_file)

        code = _exception_handler(user_exc)
        mod_handler.tear_down(code, user_exc)
    else:
        if persist_helper and env.config.base.persist_mode == const.PERSIST_MODE.ON_NORMAL_EXIT:
            persist_helper.persist()
        result = mod_handler.tear_down(const.EXIT_CODE.EXIT_SUCCESS)
        system_log.debug(_(u"strategy run successfully, normal exit"))
        return result
Beispiel #31
0
def history_bars(order_book_id,
                 bar_count,
                 frequency,
                 fields=None,
                 skip_suspended=True,
                 include_now=False,
                 adjust_type='pre'):
    """
    获取指定合约的历史行情,同时支持日以及分钟历史数据。不能在init中调用。 注意,该API会自动跳过停牌数据。

    日回测获取分钟历史数据:不支持

    日回测获取日历史数据

    =========================   ===================================================
    调用时间                      返回数据
    =========================   ===================================================
    T日before_trading            T-1日day bar
    T日handle_bar                T日day bar
    =========================   ===================================================

    分钟回测获取日历史数据

    =========================   ===================================================
    调用时间                      返回数据
    =========================   ===================================================
    T日before_trading            T-1日day bar
    T日handle_bar                T-1日day bar
    =========================   ===================================================

    分钟回测获取分钟历史数据

    =========================   ===================================================
    调用时间                      返回数据
    =========================   ===================================================
    T日before_trading            T-1日最后一个minute bar
    T日handle_bar                T日当前minute bar
    =========================   ===================================================

    :param order_book_id: 合约代码
    :type order_book_id: `str`

    :param int bar_count: 获取的历史数据数量,必填项
    :param str frequency: 获取数据什么样的频率进行。'1d'或'1m'分别表示每日和每分钟,必填项
    :param str fields: 返回数据字段。必填项。见下方列表。

    =========================   ===================================================
    fields                      字段名
    =========================   ===================================================
    datetime                    时间戳
    open                        开盘价
    high                        最高价
    low                         最低价
    close                       收盘价
    volume                      成交量
    total_turnover              成交额
    open_interest               持仓量(期货专用)
    basis_spread                期现差(股指期货专用)
    settlement                  结算价(期货日线专用)
    prev_settlement             结算价(期货日线专用)
    =========================   ===================================================

    :param bool skip_suspended: 是否跳过停牌数据
    :param bool include_now: 是否包含当前数据
    :param str adjust_type: 复权类型,默认为前复权 pre;可选 pre, none, post

    :return: `ndarray`, 方便直接与talib等计算库对接,效率较history返回的DataFrame更高。

    :example:

    获取最近5天的日线收盘价序列(策略当前日期为20160706):

    ..  code-block:: python3
        :linenos:

        [In]
        logger.info(history_bars('000002.XSHE', 5, '1d', 'close'))
        [Out]
        [ 8.69  8.7   8.71  8.81  8.81]
    """
    order_book_id = assure_order_book_id(order_book_id)
    env = Environment.get_instance()
    dt = env.calendar_dt

    if frequency[-1] == 'm' and env.config.base.frequency == '1d':
        raise RQInvalidArgument('can not get minute history in day back test')

    if adjust_type not in {'pre', 'post', 'none'}:
        raise RuntimeError('invalid adjust_type')

    if frequency == '1d':
        sys_frequency = Environment.get_instance().config.base.frequency
        if ((sys_frequency in ['1m', 'tick'] and not include_now)
                or ExecutionContext.phase() == EXECUTION_PHASE.BEFORE_TRADING):
            dt = env.data_proxy.get_previous_trading_date(
                env.trading_dt.date())
            # 当 EXECUTION_PHASE.BEFORE_TRADING 的时候,强制 include_now 为 False
            include_now = False
        if sys_frequency == "1d":
            # 日回测不支持 include_now
            include_now = False

    if fields is None:
        fields = ["datetime", "open", "high", "low", "close", "volume"]

    return env.data_proxy.history_bars(order_book_id,
                                       bar_count,
                                       frequency,
                                       fields,
                                       dt,
                                       skip_suspended=skip_suspended,
                                       include_now=include_now,
                                       adjust_type=adjust_type,
                                       adjust_orig=env.trading_dt)
Beispiel #32
0
def history_bars(order_book_id, bar_count, frequency, fields=None, skip_suspended=True,
                 include_now=False, adjust_type='pre'):
    """
    获取指定合约的历史行情,同时支持日以及分钟历史数据。不能在init中调用。 注意,该API会自动跳过停牌数据。

    日回测获取分钟历史数据:不支持

    日回测获取日历史数据

    =========================   ===================================================
    调用时间                      返回数据
    =========================   ===================================================
    T日before_trading            T-1日day bar
    T日handle_bar                T日day bar
    =========================   ===================================================

    分钟回测获取日历史数据

    =========================   ===================================================
    调用时间                      返回数据
    =========================   ===================================================
    T日before_trading            T-1日day bar
    T日handle_bar                T-1日day bar
    =========================   ===================================================

    分钟回测获取分钟历史数据

    =========================   ===================================================
    调用时间                      返回数据
    =========================   ===================================================
    T日before_trading            T-1日最后一个minute bar
    T日handle_bar                T日当前minute bar
    =========================   ===================================================

    :param order_book_id: 合约代码
    :type order_book_id: `str`

    :param int bar_count: 获取的历史数据数量,必填项
    :param str frequency: 获取数据什么样的频率进行。'1d'或'1m'分别表示每日和每分钟,必填项
    :param str fields: 返回数据字段。必填项。见下方列表。

    =========================   ===================================================
    fields                      字段名
    =========================   ===================================================
    datetime                    时间戳
    open                        开盘价
    high                        最高价
    low                         最低价
    close                       收盘价
    volume                      成交量
    total_turnover              成交额
    open_interest               持仓量(期货专用)
    basis_spread                期现差(股指期货专用)
    settlement                  结算价(期货日线专用)
    prev_settlement             结算价(期货日线专用)
    =========================   ===================================================

    :param bool skip_suspended: 是否跳过停牌数据
    :param bool include_now: 是否包含当前数据
    :param str adjust_type: 复权类型,默认为前复权 pre;可选 pre, none, post

    :return: `ndarray`, 方便直接与talib等计算库对接,效率较history返回的DataFrame更高。

    :example:

    获取最近5天的日线收盘价序列(策略当前日期为20160706):

    ..  code-block:: python3
        :linenos:

        [In]
        logger.info(history_bars('000002.XSHE', 5, '1d', 'close'))
        [Out]
        [ 8.69  8.7   8.71  8.81  8.81]
    """
    order_book_id = assure_order_book_id(order_book_id)
    env = Environment.get_instance()
    dt = env.calendar_dt

    if frequency[-1] not in {'m', 'd'}:
        raise RQInvalidArgument('invalid frequency {}'.format(frequency))

    if frequency[-1] == 'm' and env.config.base.frequency == '1d':
        raise RQInvalidArgument('can not get minute history in day back test')

    if frequency[-1] == 'd' and frequency != '1d':
        raise RQInvalidArgument('invalid frequency')

    if adjust_type not in {'pre', 'post', 'none'}:
        raise RuntimeError('invalid adjust_type')

    if frequency == '1d':
        sys_frequency = Environment.get_instance().config.base.frequency
        if ((sys_frequency in ['1m', 'tick'] and not include_now) or ExecutionContext.phase() == EXECUTION_PHASE.BEFORE_TRADING):
            dt = env.data_proxy.get_previous_trading_date(env.trading_dt.date())
            # 当 EXECUTION_PHASE.BEFORE_TRADING 的时候,强制 include_now 为 False
            include_now = False
        if sys_frequency == "1d":
            # 日回测不支持 include_now
            include_now = False

    if fields is None:
        fields = ["datetime", "open", "high", "low", "close", "volume"]

    return env.data_proxy.history_bars(order_book_id, bar_count, frequency, fields, dt,
                                       skip_suspended=skip_suspended, include_now=include_now,
                                       adjust_type=adjust_type, adjust_orig=env.trading_dt)