Repository: quantopian/zipline
File: tests/finance/test_slippage.py (Python)

Code before:

    @classproperty
    def CREATE_BARDATA_DATA_FREQUENCY(cls):
        return cls.sim_params.data_frequency

    @classmethod
    def make_equity_minute_bar_data(cls):
        yield 133, pd.DataFrame(
            {
                'open': [3.00],
                'high': [3.15],
                'low': [2.85],
                'close': [3.00],
                'volume': [200],
            },
            index=[cls.minutes[0]],
        )

    @classmethod
    def init_class_fixtures(cls):
        super(FixedBasisPointsSlippageTestCase, cls).init_class_fixtures()
        cls.ASSET133 = cls.env.asset_finder.retrieve_asset(133)

    def test_fixed_bps_slippage(self):

        slippage_model = FixedBasisPointsSlippage()

        open_orders = [
            Order(
                dt=datetime.datetime(2006, 1, 5, 14, 30, tzinfo=pytz.utc),
                amount=100,
                filled=0,
                asset=self.ASSET133
            )
        ]

        bar_data = self.create_bardata(
            simulation_dt_func=lambda: self.minutes[0],
        )

        orders_txns = list(slippage_model.simulate(
            bar_data,
            self.ASSET133,
            open_orders,
        ))

        self.assertEquals(len(orders_txns), 1)
        _, txn = orders_txns[0]

        expected_txn = {
            'price': float(3.0015),

Review comment (suggestion):
We should test that this actually respects the basis points value that it's given.  One way to do that would be to use a parameterized test, either with `parameter_space` or with `nose.parameterized`.

Code after:
                'low': [2.85],
                'close': [3.00],
                'volume': [200],
            },
            index=[cls.first_minute],
        )

    @classmethod
    def init_class_fixtures(cls):
        super(FixedBasisPointsSlippageTestCase, cls).init_class_fixtures()
        cls.ASSET133 = cls.asset_finder.retrieve_asset(133)

    @parameterized.expand([
        # Volume limit of 10% on an order of 100 shares. Since the bar volume
        # is 200, we should hit the limit and only fill 20 shares.
        ('5bps_over_vol_limit', 5, 0.1, 100, 3.0015, 20),
        # Same as previous, but on the short side.
        ('5bps_negative_over_vol_limit', 5, 0.1, -100, 2.9985, -20),
        # Volume limit of 10% on an order of 10 shares. We should fill the full
        # amount.
        ('5bps_under_vol_limit', 5, 0.1, 10, 3.0015, 10),
        # Same as previous, but on the short side.
        ('5bps_negative_under_vol_limit', 5, 0.1, -10, 2.9985, -10),
        # Change the basis points value.
        ('10bps', 10, 0.1, 100, 3.003, 20),
        # Change the volume limit points value.
        ('20pct_volume_limit', 5, 0.2, 100, 3.0015, 40),
    ])
    def test_fixed_bps_slippage(self,
                                name,
                                basis_points,
                                volume_limit,
                                order_amount,
                                expected_price,
                                expected_amount):

        slippage_model = FixedBasisPointsSlippage(basis_points=basis_points,
                                                  volume_limit=volume_limit)

        open_orders = [
            Order(
                dt=datetime.datetime(2006, 1, 5, 14, 30, tzinfo=pytz.utc),
                amount=order_amount,
                filled=0,
                asset=self.ASSET133
            )
        ]

        bar_data = self.create_bardata(
            simulation_dt_func=lambda: self.first_minute
        )