コード例 #1
0
    def test_benchmark_file(self):
        """Test running with a benchmark file.
        """
        csv_file_path = self.tmpdir.getpath('b.csv')
        with open(csv_file_path, 'w') as csv_file:
            csv_file.write("date,return\n"
                           "2020-01-03 00:00:00+00:00,-0.1\n"
                           "2020-01-06 00:00:00+00:00,0.333\n"
                           "2020-01-07 00:00:00+00:00,0.167\n"
                           "2020-01-08 00:00:00+00:00,0.143\n"
                           "2020-01-09 00:00:00+00:00,6.375\n")

        spec = BenchmarkSpec.from_cli_params(
            no_benchmark=False,
            benchmark_sid=None,
            benchmark_file=csv_file_path,
        )

        sid, returns = self.resolve_spec(spec)

        self.assertIs(sid, None)

        expected_dates = pd.to_datetime(
            [
                '2020-01-03', '2020-01-06', '2020-01-07', '2020-01-08',
                '2020-01-09'
            ],
            utc=True,
        )
        expected_values = [-0.1, 0.333, 0.167, 0.143, 6.375]
        expected_returns = pd.Series(index=expected_dates,
                                     data=expected_values)

        assert_series_equal(returns, expected_returns, check_names=False)
コード例 #2
0
def run(ctx, algofile, algotext, define, data_frequency, capital_base, bundle,
        bundle_timestamp, benchmark_file, benchmark_symbol, benchmark_sid,
        no_benchmark, start, end, output, trading_calendar, print_algo,
        metrics_set, local_namespace, blotter):
    """Run a backtest for the given algorithm.
    """
    # check that the start and end dates are passed correctly
    if start is None and end is None:
        # check both at the same time to avoid the case where a user
        # does not pass either of these and then passes the first only
        # to be told they need to pass the second argument also
        ctx.fail(
            "must specify dates with '-s' / '--start' and '-e' / '--end'", )
    if start is None:
        ctx.fail("must specify a start date with '-s' / '--start'")
    if end is None:
        ctx.fail("must specify an end date with '-e' / '--end'")

    if (algotext is not None) == (algofile is not None):
        ctx.fail(
            "must specify exactly one of '-f' / '--algofile' or"
            " '-t' / '--algotext'", )

    trading_calendar = get_calendar(trading_calendar)

    benchmark_spec = BenchmarkSpec.from_cli_params(
        no_benchmark=no_benchmark,
        benchmark_sid=benchmark_sid,
        benchmark_symbol=benchmark_symbol,
        benchmark_file=benchmark_file,
    )

    return _run(
        initialize=None,
        handle_data=None,
        before_trading_start=None,
        analyze=None,
        algofile=algofile,
        algotext=algotext,
        defines=define,
        data_frequency=data_frequency,
        capital_base=capital_base,
        bundle=bundle,
        bundle_timestamp=bundle_timestamp,
        start=start,
        end=end,
        output=output,
        trading_calendar=trading_calendar,
        print_algo=print_algo,
        metrics_set=metrics_set,
        local_namespace=local_namespace,
        environ=os.environ,
        blotter=blotter,
        benchmark_spec=benchmark_spec,
    )
コード例 #3
0
    def test_benchmark_sid(self, input_sid):
        """Test running with no benchmark provided, with no_benchmark flag.
        """
        spec = BenchmarkSpec.from_cli_params(
            no_benchmark=False,
            benchmark_sid=input_sid,
            benchmark_file=None,
        )

        sid, returns = self.resolve_spec(spec)

        assert_equal(sid, input_sid)
        self.assertIs(returns, None)
コード例 #4
0
    def test_no_benchmark_explicitly_disabled(self):
        """Test running with no benchmark provided, with no_benchmark flag.
        """
        spec = BenchmarkSpec.from_cli_params(
            no_benchmark=True,
            benchmark_sid=None,
            benchmark_file=None,
        )

        sid, returns = self.resolve_spec(spec)

        self.assertIs(sid, None)
        assert_series_equal(returns, self.zero_returns)
コード例 #5
0
    def test_no_benchmark(self):
        """Test running with no benchmark provided.

        We should have no benchmark sid and have a returns series of all zeros.
        """
        spec = BenchmarkSpec.from_cli_params(
            no_benchmark=False,
            benchmark_sid=None,
            benchmark_file=None,
        )

        sid, returns = self.resolve_spec(spec)

        self.assertIs(sid, None)
        self.assertIs(returns, None)
コード例 #6
0
    def test_benchmark_sid(self, input_sid):
        """Test running with no benchmark provided, with no_benchmark flag."""
        spec = BenchmarkSpec.from_cli_params(
            no_benchmark=False,
            benchmark_sid=input_sid,
            benchmark_symbol=None,
            benchmark_file=None,
        )

        sid, returns = self.resolve_spec(spec)

        assert_equal(sid, input_sid)
        assert returns is None

        warnings = self.logs_at_level(logbook.WARNING)
        expected = []
        assert_equal(warnings, expected)
コード例 #7
0
    def test_no_benchmark_explicitly_disabled(self):
        """Test running with no benchmark provided, with no_benchmark flag."""
        spec = BenchmarkSpec.from_cli_params(
            no_benchmark=True,
            benchmark_sid=None,
            benchmark_symbol=None,
            benchmark_file=None,
        )

        sid, returns = self.resolve_spec(spec)

        assert sid is None
        assert_series_equal(returns, self.zero_returns)

        warnings = self.logs_at_level(logbook.WARNING)
        expected = []
        assert_equal(warnings, expected)
コード例 #8
0
    def test_benchmark_symbol(self, case):
        """Test running with no benchmark provided, with no_benchmark flag.
        """
        symbol, expected_sid = case

        spec = BenchmarkSpec.from_cli_params(
            no_benchmark=False,
            benchmark_sid=None,
            benchmark_symbol=symbol,
            benchmark_file=None,
        )

        sid, returns = self.resolve_spec(spec)

        assert_equal(sid, expected_sid)
        self.assertIs(returns, None)

        warnings = self.logs_at_level(logbook.WARNING)
        expected = []
        assert_equal(warnings, expected)
コード例 #9
0
    def test_benchmark_file(self):
        """Test running with a benchmark file."""
        csv_file_path = self.tmpdir.getpath("b.csv")
        with open(csv_file_path, "w") as csv_file:
            csv_file.write("date,return\n"
                           "2020-01-03 00:00:00+00:00,-0.1\n"
                           "2020-01-06 00:00:00+00:00,0.333\n"
                           "2020-01-07 00:00:00+00:00,0.167\n"
                           "2020-01-08 00:00:00+00:00,0.143\n"
                           "2020-01-09 00:00:00+00:00,6.375\n")

        spec = BenchmarkSpec.from_cli_params(
            no_benchmark=False,
            benchmark_sid=None,
            benchmark_symbol=None,
            benchmark_file=csv_file_path,
        )

        sid, returns = self.resolve_spec(spec)

        assert sid is None

        expected_dates = pd.to_datetime(
            [
                "2020-01-03", "2020-01-06", "2020-01-07", "2020-01-08",
                "2020-01-09"
            ],
            utc=True,
        )
        expected_values = [-0.1, 0.333, 0.167, 0.143, 6.375]
        expected_returns = pd.Series(index=expected_dates,
                                     data=expected_values)

        assert_series_equal(returns, expected_returns, check_names=False)

        warnings = self.logs_at_level(logbook.WARNING)
        expected = []
        assert_equal(warnings, expected)
コード例 #10
0
    def test_no_benchmark(self):
        """Test running with no benchmark provided.

        We should have no benchmark sid and have a returns series of all zeros.
        """
        spec = BenchmarkSpec.from_cli_params(
            no_benchmark=False,
            benchmark_sid=None,
            benchmark_symbol=None,
            benchmark_file=None,
        )

        sid, returns = self.resolve_spec(spec)

        self.assertIs(sid, None)
        self.assertIs(returns, None)

        warnings = self.logs_at_level(logbook.WARNING)
        expected = [
            'No benchmark configured. Assuming algorithm calls set_benchmark.',
            'Pass --benchmark-sid, --benchmark-symbol, or --benchmark-file to set a source of benchmark returns.',  # noqa
            "Pass --no-benchmark to use a dummy benchmark of zero returns.",
        ]
        assert_equal(warnings, expected)
コード例 #11
0
def run(ctx,
        algofile,
        algotext,
        define,
        data_frequency,
        capital_base,
        bundle,
        bundle_timestamp,
        benchmark_file,
        benchmark_symbol,
        benchmark_sid,
        no_benchmark,
        start,
        end,
        output,
        trading_calendar,
        print_algo,
        metrics_set,
        local_namespace,
        blotter,
        broker,
        broker_uri,
        state_file,
        realtime_bar_target,
        list_brokers):
    """Run a backtest for the given algorithm.
    """

    if list_brokers:
        click.echo("Supported brokers:")
        for _, name, _ in pkgutil.iter_modules(brokers.__path__):
            if name != 'broker':
                click.echo(name)
        return

    # check that the start and end dates are passed correctly
    if not broker and start is None and end is None:
        # check both at the same time to avoid the case where a user
        # does not pass either of these and then passes the first only
        # to be told they need to pass the second argument also
        ctx.fail(
            "must specify dates with '-s' / '--start' and '-e' / '--end'",
        )

    if not broker and start is None:
        ctx.fail("must specify a start date with '-s' / '--start'")
    if not broker and end is None:
        ctx.fail("must specify an end date with '-e' / '--end'")

    if broker and broker_uri is None:
        ctx.fail("must specify broker-uri if broker is specified")

    if broker and state_file is None:
        ctx.fail("must specify state-file with live trading")

    if broker and realtime_bar_target is None:
        ctx.fail("must specify realtime-bar-target with live trading")

    brokerobj = None
    if broker:
        mod_name = 'zipline.gens.brokers.%s_broker' % broker.lower()
        try:
            bmod = import_module(mod_name)
        except ImportError:
            ctx.fail("unsupported broker: can't import module %s" % mod_name)

        cl_name = '%sBroker' % broker.upper()
        try:
            bclass = getattr(bmod, cl_name)
        except AttributeError:
            ctx.fail("unsupported broker: can't import class %s from %s" %
                     (cl_name, mod_name))
        brokerobj = bclass(broker_uri)
    if end is None:
            end = pd.Timestamp.utcnow() + pd.Timedelta(days=1, seconds=1)  # Add 1-second to assure that end is > 1day

    if (algotext is not None) == (algofile is not None):
        ctx.fail(
            "must specify exactly one of '-f' / '--algofile' or"
            " '-t' / '--algotext'",
        )

    trading_calendar = get_calendar(trading_calendar)

    benchmark_spec = BenchmarkSpec.from_cli_params(
        no_benchmark=no_benchmark,
        benchmark_sid=benchmark_sid,
        benchmark_symbol=benchmark_symbol,
        benchmark_file=benchmark_file,
    )

    return _run(
        initialize=None,
        handle_data=None,
        before_trading_start=None,
        analyze=None,
        teardown=None,
        algofile=algofile,
        algotext=algotext,
        defines=define,
        data_frequency=data_frequency,
        capital_base=capital_base,
        bundle=bundle,
        bundle_timestamp=bundle_timestamp,
        start=start,
        end=end,
        output=output,
        trading_calendar=trading_calendar,
        print_algo=print_algo,
        metrics_set=metrics_set,
        local_namespace=local_namespace,
        environ=os.environ,
        blotter=blotter,
        benchmark_spec=benchmark_spec,
        broker=brokerobj,
        state_filename=state_file,
        realtime_bar_target=realtime_bar_target,
        performance_callback=None,
        stop_execution_callback=None,
        execution_id=None
    )
コード例 #12
0
def run_algorithm(start,
                  end,
                  initialize,
                  capital_base=5e+6,
                  handle_data=None,
                  before_trading_start=None,
                  analyze=None,
                  data_frequency='daily',
                  bundle='mydb',
                  bundle_timestamp=None,
                  trading_calendar=None,
                  metrics_set='default',
                  benchmark_returns=None,
                  default_extension=True,
                  extensions=(),
                  strict_extensions=True,
                  environ=os.environ,
                  blotter='cn_blotter'):
    """
    运行交易策略算法.

    Parameters
    ----------
    start : datetime
        回测的开始时间.
    end : datetime
        回测的结束时间.
    initialize : callable[context -> None]
        策略算法的初始化函数, 每个回测开始前只运行一次, 用来设置策略算法的全局变量.
    capital_base : float
        回测的初始资金.
    handle_data : callable[(context, BarData) -> None], optional
        策略算法处理行情/执行下单操作的函数, 按照设置的策略频率执行.
    before_trading_start : callable[(context, BarData) -> None], optional
        每个交易日开盘前执行的函数(在第一天的初始化函数结束后执行)
    analyze : callable[(context, pd.DataFrame) -> None], optional
        在回测结束以后执行的分析函数. 传入参数为 ``context`` 和回测结果数据.
    data_frequency : {'daily', 'minute'}, optional
        策略的执行频率.
    bundle : str, optional
        *zipline* 专用的数据格式组成的数据包.
    bundle_timestamp : datetime, optional
        数据包的时间戳, 用来区分不同时间点的数据.
    trading_calendar : TradingCalendar, optional
        回测用的交易日历.
    metrics_set : iterable[Metric] or str, optional
        记录的回测性能指标集, :func:`zipline.finance.metrics.load` 根据名称调用.
    default_extension : bool, optional
        Should the default zipline extension be loaded. This is found at
        ``$ZIPLINE_ROOT/extension.py``
    extensions : iterable[str], optional
        The names of any other extensions to load. Each element may either be
        a dotted module path like ``a.b.c`` or a path to a python file ending
        in ``.py`` like ``a/b/c.py``.
    strict_extensions : bool, optional
        Should the run fail if any extensions fail to load. If this is false,
        a warning will be raised instead.
    environ : mapping[str -> str], optional
        The os environment to use. Many extensions use this to get parameters.
        This defaults to ``os.environ``.
    blotter : str or zipline.finance.blotter.Blotter, optional
        交易信息记录类, 调用前需要用 ``zipline.extensions.register`` 先注册.
        默认为 :class:`zipline.finance.blotter.SimulationBlotter`, 永远不会取消订单.

    Returns
    -------
    perf : pd.DataFrame
        交易策略的每日回测结果.

    See Also
    --------
    zipline.data.bundles.bundles : 可用的数据包.
    """
    from trading_calendars import register_calendar
    from zipline_extensions_cn.utils import AShareCalendar
    from trading_calendars.errors import CalendarNameCollision

    try:
        register_calendar('AShare', AShareCalendar())
    except CalendarNameCollision:
        pass

    #load_extensions(default_extension, extensions, strict_extensions, environ)

    if benchmark_returns is not None:
        benchmark_spec = BenchmarkSpec.from_returns(benchmark_returns)
    else:
        benchmark_spec = BenchmarkSpec(None, None, None, None, True)

    return _run(
        handle_data=handle_data,
        initialize=initialize,
        before_trading_start=before_trading_start,
        analyze=analyze,
        algofile=None,
        algotext=None,
        defines=(),
        data_frequency=data_frequency,
        capital_base=capital_base,
        bundle=bundle,
        bundle_timestamp=bundle_timestamp,
        start=start,
        end=end,
        output=os.devnull,
        trading_calendar=trading_calendar,
        print_algo=False,
        metrics_set=metrics_set,
        local_namespace=False,
        environ=environ,
        blotter=blotter,
        benchmark_spec=benchmark_spec,
    )