Example #1
0
def _validate_benchmark(config, data_proxy):
    benchmark = config.base.benchmark
    if benchmark is None:
        return
    instrument = data_proxy.instruments(benchmark)
    if instrument is None:
        raise patch_user_exc(
            ValueError(_(u"invalid benchmark {}").format(benchmark)))

    if instrument.order_book_id == "000300.XSHG":
        # 000300.XSHG 数据进行了补齐,因此认为只要benchmark设置了000300.XSHG,就存在数据,不受限于上市日期。
        return
    config = Environment.get_instance().config
    start_date = config.base.start_date
    end_date = config.base.end_date
    if instrument.listed_date.date() > start_date:
        raise patch_user_exc(
            ValueError(
                _(u"benchmark {benchmark} has not been listed on {start_date}"
                  ).format(benchmark=benchmark, start_date=start_date)))
    if instrument.de_listed_date.date() < end_date:
        raise patch_user_exc(
            ValueError(
                _(u"benchmark {benchmark} has been de_listed on {end_date}").
                format(benchmark=benchmark, end_date=end_date)))
Example #2
0
    def run_monthly(self, func, tradingday=None, time_rule=None, **kwargs):
        _verify_function('run_monthly', func)
        if tradingday is None and 'monthday' in kwargs:
            tradingday = kwargs.pop('monthday')

        if kwargs:
            raise patch_user_exc(
                ValueError('unknown argument: {}'.format(kwargs)))

        if tradingday is None:
            raise patch_user_exc(ValueError('tradingday is required'))

        if not isinstance(tradingday, int):
            raise patch_user_exc(
                ValueError('tradingday: <int> excpected, {} got'.format(
                    repr(tradingday))))

        if tradingday > 23 or tradingday < -23 or tradingday == 0:
            raise patch_user_exc(
                ValueError(
                    'invalid tradingday, should be in [-23, 0), (0, 23]'))
        if tradingday > 0:
            tradingday -= 1

        time_checker = self._time_rule_for(time_rule)

        self._registry.append(
            (lambda: self._is_nth_trading_day_in_month(tradingday),
             time_checker, func))
Example #3
0
    def run_weekly(self, func, weekday=None, tradingday=None, time_rule=None):
        _verify_function('run_weekly', func)
        if (weekday is not None
                and tradingday is not None) or (weekday is None
                                                and tradingday is None):
            raise patch_user_exc(
                ValueError('select one of weekday/tradingday'))

        if weekday is not None:
            if weekday < 1 or weekday > 7:
                raise patch_user_exc(
                    ValueError('invalid weekday, should be in [1, 7]'))
            day_checker = lambda: self._is_weekday(weekday - 1)
        else:
            if tradingday > 5 or tradingday < -5 or tradingday == 0:
                raise patch_user_exc(
                    ValueError(
                        'invalid trading day, should be in [-5, 0), (0, 5]'))
            if tradingday > 0:
                tradingday -= 1
            day_checker = lambda: self._is_nth_trading_day_in_week(tradingday)

        time_checker = self._time_rule_for(time_rule)

        self._registry.append((day_checker, time_checker, func))
Example #4
0
def _verify_function(name, func):
    if not callable(func):
        raise patch_user_exc(
            ValueError('scheduler.{}: func should be callable'.format(name)))
    sig = signature(func)
    if len(sig.parameters) != 2:
        raise patch_user_exc(
            TypeError(
                'scheduler.{}: func should take exactly 2 arguments (context, bar_dict)'
                .format(name)))
Example #5
0
def compile_strategy(source_code, strategy, scope):
    try:
        code = compile(source_code, strategy, 'exec')
        six.exec_(code, scope)
        return scope
    except Exception as e:
        exc_type, exc_val, exc_tb = sys.exc_info()
        exc_val = patch_user_exc(exc_val, force=True)
        try:
            msg = str(exc_val)
        except Exception as e1:
            msg = ""
            six.print_(e1)

        error = CustomError()
        error.set_msg(msg)
        error.set_exc(exc_type, exc_val, exc_tb)
        stackinfos = list(traceback.extract_tb(exc_tb))

        if isinstance(e, (SyntaxError, IndentationError)):
            error.add_stack_info(exc_val.filename, exc_val.lineno, "",
                                 exc_val.text)
        else:
            for item in stackinfos:
                filename, lineno, func_name, code = item
                if strategy == filename:
                    error.add_stack_info(*item)
            # avoid empty stack
            if error.stacks_length == 0:
                error.add_stack_info(*item)

        raise CustomException(error)
Example #6
0
    def start_up(self, env, mod_config):

        if env.config.base.run_type == RUN_TYPE.LIVE_TRADING:
            return

        mod_config.matching_type = self.parse_matching_type(mod_config.matching_type)

        if env.config.base.margin_multiplier <= 0:
            raise patch_user_exc(ValueError(_(u"invalid margin multiplier value: value range is (0, +∞]")))

        if env.config.base.frequency == "tick":
            mod_config.volume_limit = False
            if mod_config.matching_type not in [
                MATCHING_TYPE.NEXT_TICK_LAST,
                MATCHING_TYPE.NEXT_TICK_BEST_OWN,
                MATCHING_TYPE.NEXT_TICK_BEST_COUNTERPARTY,
            ]:
                raise RuntimeError(_("Not supported matching type {}").format(mod_config.matching_type))
        else:
            if mod_config.matching_type not in [
                MATCHING_TYPE.NEXT_BAR_OPEN,
                MATCHING_TYPE.CURRENT_BAR_CLOSE,
            ]:
                raise RuntimeError(_("Not supported matching type {}").format(mod_config.matching_type))

        if mod_config.signal:
            env.set_broker(SignalBroker(env, mod_config))
        else:
            env.set_broker(SimulationBroker(env, mod_config))

        event_source = SimulationEventSource(env)
        env.set_event_source(event_source)
Example #7
0
    def start_up(self, env, mod_config):
        if mod_config.commission_multiplier < 0:
            raise patch_user_exc(
                ValueError(
                    _(u"invalid commission multiplier value: value range is [0, +∞)"
                      )))

        if env.config.base.market == MARKET.CN:
            env.set_transaction_cost_decider(
                DEFAULT_ACCOUNT_TYPE.STOCK,
                CNStockTransactionCostDecider(
                    mod_config.commission_multiplier,
                    mod_config.cn_stock_min_commission))

            env.set_transaction_cost_decider(
                DEFAULT_ACCOUNT_TYPE.FUTURE,
                CNFutureTransactionCostDecider(
                    mod_config.commission_multiplier))

        elif env.config.base.market == MARKET.HK:
            env.set_transaction_cost_decider(
                DEFAULT_ACCOUNT_TYPE.STOCK,
                HKStockTransactionCostDecider(
                    mod_config.commission_multiplier,
                    mod_config.hk_stock_min_commission))
Example #8
0
 def __init__(self, rate=0.):
     if 0 <= rate:
         self.rate = rate
     else:
         raise patch_user_exc(
             ValueError(
                 _(u"invalid slippage rate value: value range is greater than 0"
                   )))
Example #9
0
 def __init__(self, rate=0.):
     # Rate必须在0~1之间
     if 0 <= rate < 1:
         self.rate = rate
     else:
         raise patch_user_exc(
             ValueError(
                 _(u"invalid slippage rate value: value range is [0, 1)")))
Example #10
0
 def wrapper(*args, **kwargs):
     phase = cls.stack.top.phase
     if phase not in phases:
         raise patch_user_exc(
             RuntimeError(
                 _(u"You cannot call %s when executing %s") %
                 (func.__name__, phase.value)))
     return func(*args, **kwargs)
Example #11
0
 def _get_universe(self):
     universe = self._env.get_universe()
     if len(
             universe
     ) == 0 and DEFAULT_ACCOUNT_TYPE.STOCK.name not in self._config.base.accounts:
         raise patch_user_exc(RuntimeError(
             _("Current universe is empty. Please use subscribe function before trade"
               )),
                              force=True)
     return universe
Example #12
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:
                bar = self._data_proxy.get_bar(order_book_id, self._dt, self._frequency)
            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
Example #13
0
    def _time_rule_for(self, time_rule):
        if time_rule == 'before_trading':
            return lambda: self._is_before_trading()

        if time_rule is not None and not isinstance(time_rule, int):
            raise patch_user_exc(
                ValueError(
                    'invalid time_rule, "before_trading" or int expected, got {}'
                    .format(repr(time_rule))))

        time_rule = time_rule if time_rule else self._minutes_since_midnight(
            9, 31)
        return lambda: self._should_trigger(time_rule)
Example #14
0
    def get_trade_price(self, order, price):
        side = order.side
        tick_size = Environment.get_instance().data_proxy.instruments(
            order.order_book_id).tick_size()

        price = price + tick_size * self.rate * (1 if side == SIDE.BUY else -1)

        if price <= 0:
            raise patch_user_exc(
                ValueError(
                    _(u"invalid slippage rate value {} which cause price <= 0"
                      ).format(self.rate)))

        return price
Example #15
0
        def deco(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except RQInvalidArgument:
                raise
            except Exception as e:
                if isinstance(e, TypeError):
                    exc_info = sys.exc_info()
                    try:
                        ret = inspect.getcallargs(unwrapper(func), *args, **kwargs)
                    except TypeError:
                        t, v, tb = exc_info
                        raise patch_user_exc(v.with_traceback(tb))

                if getattr(e, EXC_EXT_NAME, EXC_TYPE.NOTSET) == EXC_TYPE.NOTSET:
                    patch_system_exc(e)

                raise
Example #16
0
def _adjust_start_date(config, data_proxy):
    origin_start_date, origin_end_date = config.base.start_date, config.base.end_date
    start, end = data_proxy.available_data_range(config.base.frequency)

    config.base.start_date = max(start, config.base.start_date)
    config.base.end_date = min(end, config.base.end_date)

    # for annualized risk indicator calculation
    config.base.natural_start_date = config.base.start_date
    config.base.natural_end_date = config.base.end_date

    config.base.trading_calendar = data_proxy.get_trading_dates(
        config.base.start_date, config.base.end_date)
    if len(config.base.trading_calendar) == 0:
        raise patch_user_exc(
            ValueError(
                _(u"There is no data between {start_date} and {end_date}. Please check your"
                  u" data bundle or select other backtest period.").format(
                      start_date=origin_start_date, end_date=origin_end_date)))
    config.base.start_date = config.base.trading_calendar[0].date()
    config.base.end_date = config.base.trading_calendar[-1].date()
    config.base.timezone = pytz.utc