コード例 #1
0
ファイル: test_restrictions.py プロジェクト: zhygit/zipline
    def test_union_restrictions(self):
        """
        Test that we appropriately union restrictions together, including
        eliminating redundancy (ignoring NoRestrictions) and flattening out
        the underlying sub-restrictions of _UnionRestrictions
        """

        no_restrictions_rl = NoRestrictions()

        st_restrict_asset1 = StaticRestrictions([self.ASSET1])
        st_restrict_asset2 = StaticRestrictions([self.ASSET2])
        st_restricted_assets = [self.ASSET1, self.ASSET2]

        before_frozen_dt = str_to_ts('2011-01-05')
        freeze_dt_1 = str_to_ts('2011-01-06')
        unfreeze_dt = str_to_ts('2011-01-06 16:00')
        hist_restrict_asset3_1 = HistoricalRestrictions([
            Restriction(self.ASSET3, freeze_dt_1, FROZEN),
            Restriction(self.ASSET3, unfreeze_dt, ALLOWED)
        ])

        freeze_dt_2 = str_to_ts('2011-01-07')
        hist_restrict_asset3_2 = HistoricalRestrictions([
            Restriction(self.ASSET3, freeze_dt_2, FROZEN)
        ])

        # A union of a NoRestrictions with a non-trivial restriction should
        # yield the original restriction
        trivial_union_restrictions = no_restrictions_rl | st_restrict_asset1
        self.assertIsInstance(trivial_union_restrictions, StaticRestrictions)

        # A union of two non-trivial restrictions should yield a
        # UnionRestrictions
        st_union_restrictions = st_restrict_asset1 | st_restrict_asset2
        self.assertIsInstance(st_union_restrictions, _UnionRestrictions)

        arb_dt = str_to_ts('2011-01-04')
        self.assert_is_restricted(st_restrict_asset1, self.ASSET1, arb_dt)
        self.assert_not_restricted(st_restrict_asset1, self.ASSET2, arb_dt)
        self.assert_not_restricted(st_restrict_asset2, self.ASSET1, arb_dt)
        self.assert_is_restricted(st_restrict_asset2, self.ASSET2, arb_dt)
        self.assert_is_restricted(st_union_restrictions, self.ASSET1, arb_dt)
        self.assert_is_restricted(st_union_restrictions, self.ASSET2, arb_dt)
        self.assert_many_restrictions(
            st_restrict_asset1,
            st_restricted_assets,
            [True, False],
            arb_dt
        )
        self.assert_many_restrictions(
            st_restrict_asset2,
            st_restricted_assets,
            [False, True],
            arb_dt
        )
        self.assert_many_restrictions(
            st_union_restrictions,
            st_restricted_assets,
            [True, True],
            arb_dt
        )

        # A union of a 2-sub-restriction UnionRestrictions and a
        # non-trivial restrictions should yield a UnionRestrictions with
        # 3 sub restrictions. Works with UnionRestrictions on both the left
        # side or right side
        for r1, r2 in [
            (st_union_restrictions, hist_restrict_asset3_1),
            (hist_restrict_asset3_1, st_union_restrictions)
        ]:
            union_or_hist_restrictions = r1 | r2
            self.assertIsInstance(
                union_or_hist_restrictions, _UnionRestrictions)
            self.assertEqual(
                len(union_or_hist_restrictions.sub_restrictions), 3)

            # Includes the two static restrictions on ASSET1 and ASSET2,
            # and the historical restriction on ASSET3 starting on freeze_dt_1
            # and ending on unfreeze_dt
            self.assert_all_restrictions(
                union_or_hist_restrictions,
                [True, True, False],
                before_frozen_dt
            )
            self.assert_all_restrictions(
                union_or_hist_restrictions,
                [True, True, True],
                freeze_dt_1
            )
            self.assert_all_restrictions(
                union_or_hist_restrictions,
                [True, True, False],
                unfreeze_dt
            )
            self.assert_all_restrictions(
                union_or_hist_restrictions,
                [True, True, False],
                freeze_dt_2
            )

        # A union of two 2-sub-restrictions UnionRestrictions should yield a
        # UnionRestrictions with 4 sub restrictions.
        hist_union_restrictions = \
            hist_restrict_asset3_1 | hist_restrict_asset3_2
        multi_union_restrictions = \
            st_union_restrictions | hist_union_restrictions

        self.assertIsInstance(multi_union_restrictions, _UnionRestrictions)
        self.assertEqual(len(multi_union_restrictions.sub_restrictions), 4)

        # Includes the two static restrictions on ASSET1 and ASSET2, the
        # first historical restriction on ASSET3 starting on freeze_dt_1 and
        # ending on unfreeze_dt, and the second historical restriction on
        # ASSET3 starting on freeze_dt_2
        self.assert_all_restrictions(
            multi_union_restrictions,
            [True, True, False],
            before_frozen_dt
        )
        self.assert_all_restrictions(
            multi_union_restrictions,
            [True, True, True],
            freeze_dt_1
        )
        self.assert_all_restrictions(
            multi_union_restrictions,
            [True, True, False],
            unfreeze_dt
        )
        self.assert_all_restrictions(
            multi_union_restrictions,
            [True, True, True],
            freeze_dt_2
        )
コード例 #2
0
ファイル: test_finance.py プロジェクト: zahid0/zipline-trader
    def transaction_sim(self, **params):
        """This is a utility method that asserts expected
        results for conversion of orders to transactions given a
        trade history
        """
        trade_count = params['trade_count']
        trade_interval = params['trade_interval']
        order_count = params['order_count']
        order_amount = params['order_amount']
        order_interval = params['order_interval']
        expected_txn_count = params['expected_txn_count']
        expected_txn_volume = params['expected_txn_volume']

        # optional parameters
        # ---------------------
        # if present, alternate between long and short sales
        alternate = params.get('alternate')

        # if present, expect transaction amounts to match orders exactly.
        complete_fill = params.get('complete_fill')

        asset1 = self.asset_finder.retrieve_asset(1)
        with TempDirectory() as tempdir:

            if trade_interval < timedelta(days=1):
                sim_params = factory.create_simulation_parameters(
                    start=self.start, end=self.end, data_frequency="minute")

                minutes = self.trading_calendar.minutes_window(
                    sim_params.first_open,
                    int((trade_interval.total_seconds() / 60) * trade_count) +
                    100)

                price_data = np.array([10.1] * len(minutes))
                assets = {
                    asset1.sid:
                    pd.DataFrame({
                        "open": price_data,
                        "high": price_data,
                        "low": price_data,
                        "close": price_data,
                        "volume": np.array([100] * len(minutes)),
                        "dt": minutes
                    }).set_index("dt")
                }

                write_bcolz_minute_data(
                    self.trading_calendar,
                    self.trading_calendar.sessions_in_range(
                        self.trading_calendar.minute_to_session_label(
                            minutes[0]),
                        self.trading_calendar.minute_to_session_label(
                            minutes[-1])),
                    tempdir.path,
                    iteritems(assets),
                )

                equity_minute_reader = BcolzMinuteBarReader(tempdir.path)

                data_portal = DataPortal(
                    self.asset_finder,
                    self.trading_calendar,
                    first_trading_day=equity_minute_reader.first_trading_day,
                    equity_minute_reader=equity_minute_reader,
                )
            else:
                sim_params = factory.create_simulation_parameters(
                    data_frequency="daily")

                days = sim_params.sessions

                assets = {
                    1:
                    pd.DataFrame(
                        {
                            "open": [10.1] * len(days),
                            "high": [10.1] * len(days),
                            "low": [10.1] * len(days),
                            "close": [10.1] * len(days),
                            "volume": [100] * len(days),
                            "day": [day.value for day in days]
                        },
                        index=days)
                }

                path = os.path.join(tempdir.path, "testdata.bcolz")
                BcolzDailyBarWriter(path, self.trading_calendar, days[0],
                                    days[-1]).write(assets.items())

                equity_daily_reader = BcolzDailyBarReader(path)

                data_portal = DataPortal(
                    self.asset_finder,
                    self.trading_calendar,
                    first_trading_day=equity_daily_reader.first_trading_day,
                    equity_daily_reader=equity_daily_reader,
                )

            if "default_slippage" not in params or \
               not params["default_slippage"]:
                slippage_func = FixedBasisPointsSlippage()
            else:
                slippage_func = None

            blotter = SimulationBlotter(slippage_func)

            start_date = sim_params.first_open

            if alternate:
                alternator = -1
            else:
                alternator = 1

            tracker = MetricsTracker(
                trading_calendar=self.trading_calendar,
                first_session=sim_params.start_session,
                last_session=sim_params.end_session,
                capital_base=sim_params.capital_base,
                emission_rate=sim_params.emission_rate,
                data_frequency=sim_params.data_frequency,
                asset_finder=self.asset_finder,
                metrics=load_metrics_set('none'),
            )

            # replicate what tradesim does by going through every minute or day
            # of the simulation and processing open orders each time
            if sim_params.data_frequency == "minute":
                ticks = minutes
            else:
                ticks = days

            transactions = []

            order_list = []
            order_date = start_date
            for tick in ticks:
                blotter.current_dt = tick
                if tick >= order_date and len(order_list) < order_count:
                    # place an order
                    direction = alternator**len(order_list)
                    order_id = blotter.order(
                        asset1,
                        order_amount * direction,
                        MarketOrder(),
                    )
                    order_list.append(blotter.orders[order_id])
                    order_date = order_date + order_interval
                    # move after market orders to just after market next
                    # market open.
                    if order_date.hour >= 21:
                        if order_date.minute >= 00:
                            order_date = order_date + timedelta(days=1)
                            order_date = order_date.replace(hour=14, minute=30)
                else:
                    bar_data = BarData(
                        data_portal=data_portal,
                        simulation_dt_func=lambda: tick,
                        data_frequency=sim_params.data_frequency,
                        trading_calendar=self.trading_calendar,
                        restrictions=NoRestrictions(),
                    )
                    txns, _, closed_orders = blotter.get_transactions(bar_data)
                    for txn in txns:
                        tracker.process_transaction(txn)
                        transactions.append(txn)

                    blotter.prune_orders(closed_orders)

            for i in range(order_count):
                order = order_list[i]
                self.assertEqual(order.asset, asset1)
                self.assertEqual(order.amount, order_amount * alternator**i)

            if complete_fill:
                self.assertEqual(len(transactions), len(order_list))

            total_volume = 0
            for i in range(len(transactions)):
                txn = transactions[i]
                total_volume += txn.amount
                if complete_fill:
                    order = order_list[i]
                    self.assertEqual(order.amount, txn.amount)

            self.assertEqual(total_volume, expected_txn_volume)

            self.assertEqual(len(transactions), expected_txn_count)

            if total_volume == 0:
                self.assertRaises(KeyError, lambda: tracker.positions[asset1])
            else:
                cumulative_pos = tracker.positions[asset1]
                self.assertEqual(total_volume, cumulative_pos.amount)

            # the open orders should not contain the asset.
            oo = blotter.open_orders
            self.assertNotIn(asset1, oo,
                             "Entry is removed when no open orders")
コード例 #3
0
ファイル: test_testing.py プロジェクト: fangchenli/zipline
 def init_instance_fixtures(self):
     super().init_instance_fixtures()
     self.bar_data = BarData(self.data_portal, lambda: self.minute,
                             "minute", self.trading_calendar,
                             NoRestrictions())
コード例 #4
0
ファイル: bardata.py プロジェクト: gazsim/zipline
def get_data(dt, bundle=None, data_frequency=None):
    """
    Return a zipline.protocol.BarData object for the specified bundle (or default bundle)
    as of the specified datetime. This is the same object that is passed
    as the `data` parameter to `handle_data` and other backtest functions.

    Parameters
    ----------
    dt : str (YYYY-MM-DD[ HH:MM:SS]), required
        The datetime (for minute data) or date (for daily data) which the
        data object should be anchored to.

    bundle : str, optional
        the bundle code. If omitted, the default bundle will be used (and
        must be set).

    data_frequency : str, optional
        the data frequency. Possible choices: daily, minute. The default is
        "daily" for daily bundles and "minute" for minute bundles. Minute
        bundles also support "daily".

    Returns
    -------
    data : zipline.protocol.BarData

    Examples
    --------
    Get the data object for July 7, 2020 at 11 AM for the usstock minute
    bundle:

    >>> data = get_data('2020-07-07 11:00:00', bundle="usstock-1min")

    Get the data object for July 7, 2020 for a daily bundle:

    >>> data = get_data('2020-07-07', bundle="xjpx-1d-bundle")
    """
    if not bundle:
        bundle = get_default_bundle()
        if not bundle:
            raise ValidationError(
                "you must specify a bundle or set a default bundle")
        bundle = bundle["default_bundle"]

    load_extensions(code=bundle)

    bundle_data = bundles.load(
        bundle,
        os.environ,
        pd.Timestamp.utcnow(),
    )
    if not data_frequency:
        config = get_bundle_config(bundle)
        data_frequency = config["data_frequency"]

    calendar_name = bundles.bundles[bundle].calendar_name
    trading_calendar = get_calendar(calendar_name)

    session_minute = pd.Timestamp(dt, tz=trading_calendar.tz)
    session = session_minute.normalize().tz_localize(None).tz_localize("UTC")

    first_session = max(bundles.bundles[bundle].start_session,
                        trading_calendar.first_session)
    if session < first_session:
        raise ValidationError(
            f"date cannot be earlier than {first_session.date().isoformat()} for this bundle"
        )

    if not trading_calendar.is_session(session):
        raise ValidationError(
            f"requested date {session.date().isoformat()} is not in {calendar_name} calendar"
        )

    if data_frequency == "minute" and not trading_calendar.is_open_on_minute(
            session_minute):
        raise ValidationError(
            f"requested time {session_minute.isoformat()} is not in {calendar_name} calendar"
        )

    if data_frequency == "minute":
        equity_minute_reader = future_minute_reader = bundle_data.equity_minute_bar_reader
    else:
        equity_minute_reader = future_minute_reader = None

    asset_finder = asset_finder_cache.get(bundle, bundle_data.asset_finder)
    asset_finder_cache[bundle] = asset_finder

    data_portal = DataPortal(
        asset_finder,
        trading_calendar=trading_calendar,
        first_trading_day=bundle_data.equity_minute_bar_reader.
        first_trading_day,
        equity_minute_reader=equity_minute_reader,
        equity_daily_reader=bundle_data.equity_daily_bar_reader,
        future_minute_reader=future_minute_reader,
        future_daily_reader=bundle_data.equity_daily_bar_reader,
        adjustment_reader=bundle_data.adjustment_reader)

    data = BarData(
        data_portal=data_portal,
        simulation_dt_func=lambda: session_minute,
        data_frequency=data_frequency,
        trading_calendar=trading_calendar,
        restrictions=NoRestrictions(),
        universe_func=lambda: asset_finder.retrieve_all(asset_finder.sids))

    return data
コード例 #5
0
 def create_bardata(self, simulation_dt_func, restrictions=None):
     return BarData(self.data_portal, simulation_dt_func,
                    self.CREATE_BARDATA_DATA_FREQUENCY,
                    self.trading_calendar, restrictions or NoRestrictions())