示例#1
0
    def test_volume_limit(self, name,
                          first_order_amount,
                          second_order_amount,
                          first_order_fill_amount,
                          second_order_fill_amount):

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

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

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

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

        self.assertEquals(len(orders_txns), 2)

        _, first_txn = orders_txns[0]
        _, second_txn = orders_txns[1]
        self.assertEquals(first_txn['amount'], first_order_fill_amount)
        self.assertEquals(second_txn['amount'], second_order_fill_amount)
示例#2
0
    def test_orders_stop(self, name, order_data, event_data, expected):
        data = order_data
        data['asset'] = self.ASSET133
        order = Order(**data)

        if expected['transaction']:
            expected['transaction']['asset'] = self.ASSET133
        event_data['asset'] = self.ASSET133

        assets = (
            (133, pd.DataFrame(
                {
                    'open': [event_data['open']],
                    'high': [event_data['high']],
                    'low': [event_data['low']],
                    'close': [event_data['close']],
                    'volume': [event_data['volume']],
                },
                index=[pd.Timestamp('2006-01-05 14:31', tz='UTC')],
            )),
        )
        days = pd.date_range(
            start=normalize_date(self.minutes[0]),
            end=normalize_date(self.minutes[-1])
        )
        with tmp_bcolz_equity_minute_bar_reader(
                self.trading_calendar, days, assets) as reader:
            data_portal = DataPortal(
                self.asset_finder, self.trading_calendar,
                first_trading_day=reader.first_trading_day,
                equity_minute_reader=reader,
            )

            slippage_model = VolumeShareSlippage()

            try:
                dt = pd.Timestamp('2006-01-05 14:31', tz='UTC')
                bar_data = BarData(
                    data_portal,
                    lambda: dt,
                    self.sim_params.data_frequency,
                    self.trading_calendar,
                    NoRestrictions(),
                )

                _, txn = next(slippage_model.simulate(
                    bar_data,
                    self.ASSET133,
                    [order],
                ))
            except StopIteration:
                txn = None

            if expected['transaction'] is None:
                self.assertIsNone(txn)
            else:
                self.assertIsNotNone(txn)

                for key, value in expected['transaction'].items():
                    self.assertEquals(value, txn[key])
示例#3
0
    def generate_order_and_txns(self, sid, order_amount, fill_amounts):
        asset1 = self.asset_finder.retrieve_asset(sid)

        # one order
        order = Order(dt=None, asset=asset1, amount=order_amount)

        # three fills
        txn1 = Transaction(asset=asset1,
                           amount=fill_amounts[0],
                           dt=None,
                           price=100,
                           order_id=order.id)

        txn2 = Transaction(asset=asset1,
                           amount=fill_amounts[1],
                           dt=None,
                           price=101,
                           order_id=order.id)

        txn3 = Transaction(asset=asset1,
                           amount=fill_amounts[2],
                           dt=None,
                           price=102,
                           order_id=order.id)

        return order, [txn1, txn2, txn3]
示例#4
0
    def order(self, sid, amount, style, order_id=None):
        """Place an order.

        Parameters
        ----------
        asset : zipline.assets.Asset
            The asset that this order is for.
        amount : int
            The amount of shares to order. If ``amount`` is positive, this is
            the number of shares to buy or cover. If ``amount`` is negative,
            this is the number of shares to sell or short.
        style : zipline.finance.execution.ExecutionStyle
            The execution style for the order.
        order_id : str, optional
            The unique identifier for this order.

        Returns
        -------
        order_id : str or None
            The unique identifier for this order, or None if no order was
            placed.

        Notes
        -----
        amount > 0 :: Buy/Cover
        amount < 0 :: Sell/Short
        Market order:    order(sid, amount)
        Limit order:     order(sid, amount, style=LimitOrder(limit_price))
        Stop order:      order(sid, amount, style=StopOrder(stop_price))
        StopLimit order: order(sid, amount, style=StopLimitOrder(limit_price,
                               stop_price))
        """
        # something could be done with amount to further divide
        # between buy by share count OR buy shares up to a dollar amount
        # numeric == share count  AND  "$dollar.cents" == cost amount

        if amount == 0:
            # Don't bother placing orders for 0 shares.
            return None
        elif amount > self.max_shares:
            # Arbitrary limit of 100 billion (US) shares will never be
            # exceeded except by a buggy algorithm.
            raise OverflowError("Can't order more than %d shares" %
                                self.max_shares)

        is_buy = (amount > 0)
        order = Order(dt=self.current_dt,
                      sid=sid,
                      amount=amount,
                      stop=style.get_stop_price(is_buy),
                      limit=style.get_limit_price(is_buy),
                      id=order_id)

        self.open_orders[order.sid].append(order)
        self.orders[order.id] = order
        self.new_orders.append(order)

        return order.id
示例#5
0
    def test_fill_zero_shares(self):
        slippage_model = FixedBasisPointsSlippage(basis_points=5,
                                                  volume_limit=0.1)

        # since the volume limit for the bar is 20, the first order will be
        # filled and there will be a transaction for it, and the second order
        # will order zero shares so there should not be a transaction for it.
        open_orders = [
            Order(
                dt=datetime.datetime(2006, 1, 5, 14, 30, tzinfo=pytz.utc),
                amount=20,
                filled=0,
                asset=self.ASSET133,
            )
        ] * 2

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

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

        assert 1 == len(orders_txns)

        # ordering zero shares should result in zero transactions
        open_orders = [
            Order(
                dt=datetime.datetime(2006, 1, 5, 14, 30, tzinfo=pytz.utc),
                amount=0,
                filled=0,
                asset=self.ASSET133,
            )
        ]

        orders_txns = list(
            slippage_model.simulate(
                bar_data,
                self.ASSET133,
                open_orders,
            ))
        assert 0 == len(orders_txns)
示例#6
0
    def order(self, asset, amount, limit_price, stop_price, style):
        is_buy = (amount > 0)
        zp_order = ZPOrder(
            dt=pd.to_datetime('now', utc=True),
            asset=asset,
            amount=amount,
            stop=style.get_stop_price(is_buy),
            limit=style.get_limit_price(is_buy))

        contract = Contract()
        contract.m_symbol = str(asset.symbol)
        contract.m_currency = self.currency
        contract.m_exchange = 'SMART'
        contract.m_secType = 'STK'

        order = Order()
        order.m_totalQuantity = int(fabs(amount))
        order.m_action = "BUY" if amount > 0 else "SELL"

        order.m_lmtPrice = 0
        order.m_auxPrice = 0

        if isinstance(style, MarketOrder):
            order.m_orderType = "MKT"
        elif isinstance(style, LimitOrder):
            order.m_orderType = "LMT"
            order.m_lmtPrice = limit_price
        elif isinstance(style, StopOrder):
            order.m_orderType = "STP"
            order.m_auxPrice = stop_price
        elif isinstance(style, StopLimitOrder):
            order.m_orderType = "STP LMT"
            order.m_auxPrice = stop_price
            order.m_lmtPrice = limit_price

        order.m_tif = "DAY"

        ib_order_id = self._tws.next_order_id
        zp_order.broker_order_id = ib_order_id
        self.orders[zp_order.id] = zp_order

        self._tws.placeOrder(ib_order_id, contract, order)

        return zp_order.id
    def order(
        self,
        sid,
        amount,
        style,
        commission,
        order_id=None,
        give_price=None,
    ):

        # something could be done with amount to further divide
        # between buy by share count OR buy shares up to a dollar amount
        # numeric == share count  AND  "$dollar.cents" == cost amount
        # sid 为stock_id 股票代码,他么的。
        """
        amount > 0 :: Buy/Cover
        amount < 0 :: Sell/Short
        Market order:    order(sid, amount)
        Limit order:     order(sid, amount, style=LimitOrder(limit_price))
        Stop order:      order(sid, amount, style=StopOrder(stop_price))
        StopLimit order: order(sid, amount, style=StopLimitOrder(limit_price,
                               stop_price))
        """

        if amount == 0:
            # Don't bother placing orders for 0 shares.
            return
        elif amount > self.max_shares:
            # Arbitrary limit of 100 billion (US) shares will never be
            # exceeded except by a buggy algorithm.
            raise OverflowError("Can't order more than %d shares" %
                                self.max_shares)
        '''
        elif amount%100 !=0:
            original=amount
            n=amount%100
            amount=amount-n
            print (u"%s:买入股票数目应该为100倍数, 从 %d 调整为 %d"%(self.current_dt,original,amount))
        '''
        is_buy = (amount > 0)
        order = Order(dt=self.current_dt,
                      sid=sid,
                      amount=amount,
                      give_price=give_price,
                      stop=style.get_stop_price(is_buy),
                      limit=style.get_limit_price(is_buy),
                      id=order_id)
        #print u'这里的情况啊啊啊啊啊'

        self.open_orders[order.sid].append(order)
        self.orders[order.id] = order
        self.new_orders.append(order)

        return order.id
    def tdx_order_to_zipline_order(self, order):
        """
        status
        0	已报
        1	部分成交
        2	全部成交
        3	部分撤单
        4	全部撤单
        5	交易所拒单
        6	柜台未接受

        :param order:
        :return:
        """
        if order.status == "3" or '4' == order.status:
            zp_status = ZP_ORDER_STATUS.CANCELLED
        elif order.status == "0":
            zp_status = ZP_ORDER_STATUS.OPEN
        elif order.status == "1":
            zp_status = ZP_ORDER_STATUS.FILLED
        elif order.status == "2":
            zp_status = ZP_ORDER_STATUS.HELD
        elif order.status == "5" or order.status == "6":
            zp_status = ZP_ORDER_STATUS.REJECTED


        zp_order_id = self._tdx_to_zp_order_id(order.order_id)

        od = ZPOrder(
            dt=order.dt,
            asset=symbol(order.symbol),
            amount=order.amount,
            filled=order.filled,
            stop=None,
            limit=order.price,  # TODO 市价单和限价单
            id=zp_order_id,
        )
        od.broker_order_id = order.order_id
        od.status = zp_status

        return od
示例#9
0
 def test_calculate_impact_sell(self):
     answer_key = [
         # We ordered -10 contracts, but are capped at -(100 * 0.05) = -5
         (91485.499914831875, -5),
         (91486.499914830943, -5),
         (None, None),
     ]
     order = Order(
         dt=pd.Timestamp.now(tz='utc').round('min'),
         asset=self.ASSET,
         amount=-10,
     )
     self._calculate_impact(order, answer_key)
示例#10
0
 def test_calculate_impact_buy(self):
     answer_key = [
         # We ordered 10 contracts, but are capped at 100 * 0.05 = 5
         (91485.500085168125, 5),
         (91486.500085169057, 5),
         (None, None),
     ]
     order = Order(
         dt=pd.Timestamp.now(tz='utc').round('min'),
         asset=self.ASSET,
         amount=10,
     )
     self._calculate_impact(order, answer_key)
示例#11
0
    def test_low_transaction_volume(self):
        # With a volume limit of 0.001, and a bar volume of 100, we should
        # compute a transaction volume of 100 * 0.001 = 0.1, which gets rounded
        # down to zero. In this case we expect no amount to be transacted.
        model = VolatilityVolumeShare(volume_limit=0.001)

        minute = pd.Timestamp('2006-03-01 11:35AM', tz='UTC')
        data = self.create_bardata(simulation_dt_func=lambda: minute)
        order = Order(dt=data.current_dt, asset=self.ASSET, amount=10)
        price, amount = model.process_order(data, order)

        self.assertIsNone(price)
        self.assertIsNone(amount)
示例#12
0
    def tdx_order_to_zipline_order(self, order):
        if order.status is not None and 'CANCEL' == order.status:
            zp_status = ZP_ORDER_STATUS.CANCELLED
        elif order.filled == 0:
            zp_status = ZP_ORDER_STATUS.OPEN
        else:
            zp_status = ZP_ORDER_STATUS.FILLED

        zp_order_id = self._tdx_to_zp_order_id(order.order_id)

        od = ZPOrder(
            dt=pd.to_datetime(order.dt),
            asset=symbol(order.symbol),
            amount=order.amount,
            filled=order.filled,
            stop=None,
            limit=order.price,  # TODO 市价单和限价单
            id=zp_order_id,
        )
        od.broker_order_id = order.order_id
        od.status = zp_status

        return od
示例#13
0
    def order(self,
              sid,
              amount,
              style,
              order_id=None,
              base_price=None,
              open_price=None,
              close_price=None,
              when=None,
              current_volume=None):

        # something could be done with amount to further divide
        # between buy by share count OR buy shares up to a dollar amount
        # numeric == share count  AND  "$dollar.cents" == cost amount
        """
        amount > 0 :: Buy/Cover
        amount < 0 :: Sell/Short
        Market order:    order(sid, amount)
        Limit order:     order(sid, amount, style=LimitOrder(limit_price))
        Stop order:      order(sid, amount, style=StopOrder(stop_price))
        StopLimit order: order(sid, amount, style=StopLimitOrder(limit_price,
                               stop_price))
        """
        if amount == 0:
            # Don't bother placing orders for 0 shares.
            return
        elif amount > self.max_shares:
            # Arbitrary limit of 100 billion (US) shares will never be
            # exceeded except by a buggy algorithm.
            raise OverflowError("Can't order more than %d shares" %
                                self.max_shares)

        is_buy = (amount > 0)
        order = Order(dt=self.current_dt,
                      sid=sid,
                      amount=amount,
                      stop=style.get_stop_price(is_buy),
                      limit=style.get_limit_price(is_buy),
                      id=order_id,
                      base_price=base_price,
                      close_price=close_price,
                      open_price=open_price,
                      when=when,
                      current_volume=current_volume)

        self.open_orders[order.sid].append(order)
        self.orders[order.id] = order
        self.new_orders.append(order)

        return order.id
示例#14
0
    def tdx_order_to_zipline_order(self, order):
        if order.status == '已撤':
            zp_status = ZP_ORDER_STATUS.CANCELLED
        elif order.filled == 0:
            zp_status = ZP_ORDER_STATUS.OPEN
        else:
            zp_status = ZP_ORDER_STATUS.FILLED

        zp_order_id = self._tdx_to_zp_order_id(order.order_id)

        od = ZPOrder(
            dt=pd.to_datetime(order.dt),
            asset=symbol(order.symbol),
            amount=order.amount,
            filled=order.filled,
            stop=None,
            limit=order.price,  # TODO 市价单和限价单
            id=zp_order_id,
        )
        od.broker_order_id = order.order_id
        od.status = zp_status

        return od
示例#15
0
    def test_impacted_price_worse_than_limit(self):
        model = VolatilityVolumeShare(volume_limit=0.05)

        # Use all the same numbers from the 'calculate_impact' tests. Since the
        # impacted price is 59805.5, which is worse than the limit price of
        # 59800, the model should return None.
        minute = pd.Timestamp('2006-03-01 11:35AM', tz='UTC')
        data = self.create_bardata(simulation_dt_func=lambda: minute)
        order = Order(
            dt=data.current_dt, asset=self.ASSET, amount=10, limit=59800,
        )
        price, amount = model.process_order(data, order)

        self.assertIsNone(price)
        self.assertIsNone(amount)
示例#16
0
    def generate_order_and_txns(self):
        asset1 = self.asset_finder.retrieve_asset(1)

        # one order
        order = Order(dt=None, sid=asset1, amount=500)

        # three fills
        txn1 = Transaction(sid=asset1, amount=230, dt=None,
                           price=100, order_id=order.id)

        txn2 = Transaction(sid=asset1, amount=170, dt=None,
                           price=101, order_id=order.id)

        txn3 = Transaction(sid=asset1, amount=100, dt=None,
                           price=102, order_id=order.id)

        return order, [txn1, txn2, txn3]
示例#17
0
    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)

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

        assert len(orders_txns) == 1
        _, txn = orders_txns[0]

        expected_txn = {
            "price": expected_price,
            "dt": datetime.datetime(2006, 1, 5, 14, 31, tzinfo=pytz.utc),
            "amount": expected_amount,
            "asset": self.ASSET133,
            "type": DATASOURCE_TYPE.TRANSACTION,
            "order_id": open_orders[0].id,
        }

        assert txn is not None
        assert expected_txn == txn.__dict__
示例#18
0
    def test_prune_orders(self):
        blotter = Blotter(self.sim_params.data_frequency, self.asset_finder)

        blotter.order(self.asset_24, 100, MarketOrder())
        open_order = blotter.open_orders[self.asset_24][0]

        blotter.prune_orders([])
        self.assertEqual(1, len(blotter.open_orders[self.asset_24]))

        blotter.prune_orders([open_order])
        self.assertEqual(0, len(blotter.open_orders[self.asset_24]))

        # prune an order that isn't in our our open orders list, make sure
        # nothing blows up

        other_order = Order(dt=blotter.current_dt, sid=self.asset_25, amount=1)

        blotter.prune_orders([other_order])
示例#19
0
    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
        )

        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': expected_price,
            'dt': datetime.datetime(2006, 1, 5, 14, 31, tzinfo=pytz.utc),
            'amount': expected_amount,
            'asset': self.ASSET133,
            'type': DATASOURCE_TYPE.TRANSACTION,
            'order_id': open_orders[0].id
        }

        self.assertIsNotNone(txn)
        self.assertEquals(expected_txn, txn.__dict__)
示例#20
0
    def test_prune_orders(self):
        blotter = SimulationBlotter()

        blotter.order(self.asset_24, 100, MarketOrder())
        open_order = blotter.open_orders[self.asset_24][0]

        blotter.prune_orders([])
        self.assertEqual(1, len(blotter.open_orders[self.asset_24]))

        blotter.prune_orders([open_order])
        self.assertEqual(0, len(blotter.open_orders[self.asset_24]))

        # prune an order that isn't in our our open orders list, make sure
        # nothing blows up

        other_order = Order(dt=blotter.current_dt,
                            asset=self.asset_25,
                            amount=1)

        blotter.prune_orders([other_order])
示例#21
0
    def test_volume_share_slippage_with_future(self):
        slippage_model = VolumeShareSlippage(volume_limit=1, price_impact=0.3)

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

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

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

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

        # We expect to fill the order for all 10 contracts. The volume for the
        # futures contract in this bar is 100, so our volume share is:
        #     10.0 / 100 = 0.1
        # The current price is 5.0 and the price impact is 0.3, so the expected
        # impacted price is:
        #     5.0 + (5.0 * (0.1 ** 2) * 0.3) = 5.015
        expected_txn = {
            'price': 5.015,
            'dt': datetime.datetime(2006, 1, 5, 14, 31, tzinfo=pytz.utc),
            'amount': 10,
            'asset': self.ASSET1000,
            'commission': None,
            'type': DATASOURCE_TYPE.TRANSACTION,
            'order_id': open_orders[0].id,
        }

        self.assertIsNotNone(txn)
        self.assertEquals(expected_txn, txn.__dict__)
示例#22
0
    def _calculate_impact(self, test_order, answer_key):
        model = VolatilityVolumeShare(volume_limit=0.05)
        first_minute = pd.Timestamp('2006-03-31 11:35AM', tz='UTC')

        next_3_minutes = self.trading_calendar.minutes_window(first_minute, 3)
        remaining_shares = test_order.open_amount

        for i, minute in enumerate(next_3_minutes):
            data = self.create_bardata(simulation_dt_func=lambda: minute)
            new_order = Order(
                dt=data.current_dt, asset=self.ASSET, amount=remaining_shares,
            )
            price, amount = model.process_order(data, new_order)

            self.assertEqual(price, answer_key[i][0])
            self.assertEqual(amount, answer_key[i][1])

            amount = amount or 0
            if remaining_shares < 0:
                remaining_shares = min(0, remaining_shares - amount)
            else:
                remaining_shares = max(0, remaining_shares - amount)
示例#23
0
    def test_calculate_impact_without_history(self):
        model = VolatilityVolumeShare(volume_limit=1)
        minutes = [
            # Start day of the futures contract; no history yet.
            pd.Timestamp('2006-02-10 11:35AM', tz='UTC'),
            # Only a week's worth of history data.
            pd.Timestamp('2006-02-17 11:35AM', tz='UTC'),
        ]

        for minute in minutes:
            data = self.create_bardata(simulation_dt_func=lambda: minute)

            order = Order(dt=data.current_dt, asset=self.ASSET, amount=10)
            price, amount = model.process_order(data, order)

            avg_price = (data.current(self.ASSET, 'high') +
                         data.current(self.ASSET, 'low')) / 2
            expected_price = \
                avg_price + (avg_price * NO_DATA_VOLATILITY_SLIPPAGE_IMPACT)

            self.assertEqual(price, expected_price)
            self.assertEqual(amount, 10)
示例#24
0
    def test_volume_share_slippage_with_future(self):
        slippage_model = VolumeShareSlippage(volume_limit=1, price_impact=0.3)

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

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

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

        assert len(orders_txns) == 1
        _, txn = orders_txns[0]

        # We expect to fill the order for all 10 contracts. The volume for the
        # futures contract in this bar is 100, so our volume share is:
        #     10.0 / 100 = 0.1
        # The current price is 5.0 and the price impact is 0.3, so the expected
        # impacted price is:
        #     5.0 + (5.0 * (0.1 ** 2) * 0.3) = 5.015
        expected_txn = {
            "price": 5.015,
            "dt": datetime.datetime(2006, 1, 5, 14, 31, tzinfo=pytz.utc),
            "amount": 10,
            "asset": self.ASSET1000,
            "type": DATASOURCE_TYPE.TRANSACTION,
            "order_id": open_orders[0].id,
        }

        assert txn is not None
        assert expected_txn == txn.__dict__
示例#25
0
 def _order2zp(self, order):
     zp_order = ZPOrder(
         id=order.client_order_id,
         asset=symbol_lookup(order.symbol),
         amount=int(order.qty) if order.side == 'buy' else -int(order.qty),
         stop=float(order.stop_price) if order.stop_price else None,
         limit=float(order.limit_price) if order.limit_price else None,
         dt=order.submitted_at,
         commission=0,
     )
     zp_order.status = ZP_ORDER_STATUS.OPEN
     if order.canceled_at:
         zp_order.status = ZP_ORDER_STATUS.CANCELLED
     if order.failed_at:
         zp_order.status = ZP_ORDER_STATUS.REJECTED
     if order.filled_at:
         zp_order.status = ZP_ORDER_STATUS.FILLED
         zp_order.filled = int(order.filled_qty)
     return zp_order
示例#26
0
 def make_order(self, amount):
     return Order(
         self.minute,
         self.asset,
         amount,
     )
示例#27
0
    def test_orders_limit(self):
        slippage_model = VolumeShareSlippage()
        slippage_model.data_portal = self.data_portal

        # long, does not trade
        open_orders = [
            Order(
                **{
                    "dt": datetime.datetime(
                        2006, 1, 5, 14, 30, tzinfo=pytz.utc),
                    "amount": 100,
                    "filled": 0,
                    "asset": self.ASSET133,
                    "limit": 3.5,
                })
        ]

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

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

        assert len(orders_txns) == 0

        # long, does not trade - impacted price worse than limit price
        open_orders = [
            Order(
                **{
                    "dt": datetime.datetime(
                        2006, 1, 5, 14, 30, tzinfo=pytz.utc),
                    "amount": 100,
                    "filled": 0,
                    "asset": self.ASSET133,
                    "limit": 3.5,
                })
        ]

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

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

        assert len(orders_txns) == 0

        # long, does trade
        open_orders = [
            Order(
                **{
                    "dt": datetime.datetime(
                        2006, 1, 5, 14, 30, tzinfo=pytz.utc),
                    "amount": 100,
                    "filled": 0,
                    "asset": self.ASSET133,
                    "limit": 3.6,
                })
        ]

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

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

        assert len(orders_txns) == 1
        txn = orders_txns[0][1]

        expected_txn = {
            "price": float(3.50021875),
            "dt": datetime.datetime(2006, 1, 5, 14, 34, tzinfo=pytz.utc),
            # we ordered 100 shares, but default volume slippage only allows
            # for 2.5% of the volume.  2.5% * 2000 = 50 shares
            "amount": int(50),
            "asset": self.ASSET133,
            "order_id": open_orders[0].id,
        }

        assert txn is not None

        for key, value in expected_txn.items():
            assert value == txn[key]

        # short, does not trade
        open_orders = [
            Order(
                **{
                    "dt": datetime.datetime(
                        2006, 1, 5, 14, 30, tzinfo=pytz.utc),
                    "amount": -100,
                    "filled": 0,
                    "asset": self.ASSET133,
                    "limit": 3.5,
                })
        ]

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

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

        assert len(orders_txns) == 0

        # short, does not trade - impacted price worse than limit price
        open_orders = [
            Order(
                **{
                    "dt": datetime.datetime(
                        2006, 1, 5, 14, 30, tzinfo=pytz.utc),
                    "amount": -100,
                    "filled": 0,
                    "asset": self.ASSET133,
                    "limit": 3.5,
                })
        ]

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

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

        assert len(orders_txns) == 0

        # short, does trade
        open_orders = [
            Order(
                **{
                    "dt": datetime.datetime(
                        2006, 1, 5, 14, 30, tzinfo=pytz.utc),
                    "amount": -100,
                    "filled": 0,
                    "asset": self.ASSET133,
                    "limit": 3.4,
                })
        ]

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

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

        assert len(orders_txns) == 1
        _, txn = orders_txns[0]

        expected_txn = {
            "price": float(3.49978125),
            "dt": datetime.datetime(2006, 1, 5, 14, 32, tzinfo=pytz.utc),
            "amount": int(-50),
            "asset": self.ASSET133,
        }

        assert txn is not None

        for key, value in expected_txn.items():
            assert value == txn[key]
示例#28
0
    def test_orders_stop_limit(self):
        slippage_model = VolumeShareSlippage()
        slippage_model.data_portal = self.data_portal

        # long, does not trade
        open_orders = [
            Order(
                **{
                    "dt": datetime.datetime(
                        2006, 1, 5, 14, 30, tzinfo=pytz.utc),
                    "amount": 100,
                    "filled": 0,
                    "asset": self.ASSET133,
                    "stop": 4.0,
                    "limit": 3.0,
                })
        ]

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

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

        assert len(orders_txns) == 0

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

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

        assert len(orders_txns) == 0

        # long, does not trade - impacted price worse than limit price
        open_orders = [
            Order(
                **{
                    "dt": datetime.datetime(
                        2006, 1, 5, 14, 30, tzinfo=pytz.utc),
                    "amount": 100,
                    "filled": 0,
                    "asset": self.ASSET133,
                    "stop": 4.0,
                    "limit": 3.5,
                })
        ]

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

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

        assert len(orders_txns) == 0

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

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

        assert len(orders_txns) == 0

        # long, does trade
        open_orders = [
            Order(
                **{
                    "dt": datetime.datetime(
                        2006, 1, 5, 14, 30, tzinfo=pytz.utc),
                    "amount": 100,
                    "filled": 0,
                    "asset": self.ASSET133,
                    "stop": 4.0,
                    "limit": 3.6,
                })
        ]

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

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

        assert len(orders_txns) == 0

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

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

        assert len(orders_txns) == 1
        _, txn = orders_txns[0]

        expected_txn = {
            "price": float(3.50021875),
            "dt": datetime.datetime(2006, 1, 5, 14, 34, tzinfo=pytz.utc),
            "amount": int(50),
            "asset": self.ASSET133,
        }

        for key, value in expected_txn.items():
            assert value == txn[key]

        # short, does not trade

        open_orders = [
            Order(
                **{
                    "dt": datetime.datetime(
                        2006, 1, 5, 14, 30, tzinfo=pytz.utc),
                    "amount": -100,
                    "filled": 0,
                    "asset": self.ASSET133,
                    "stop": 3.0,
                    "limit": 4.0,
                })
        ]

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

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

        assert len(orders_txns) == 0

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

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

        assert len(orders_txns) == 0

        # short, does not trade - impacted price worse than limit price
        open_orders = [
            Order(
                **{
                    "dt": datetime.datetime(
                        2006, 1, 5, 14, 30, tzinfo=pytz.utc),
                    "amount": -100,
                    "filled": 0,
                    "asset": self.ASSET133,
                    "stop": 3.0,
                    "limit": 3.5,
                })
        ]

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

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

        assert len(orders_txns) == 0

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

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

        assert len(orders_txns) == 0

        # short, does trade
        open_orders = [
            Order(
                **{
                    "dt": datetime.datetime(
                        2006, 1, 5, 14, 30, tzinfo=pytz.utc),
                    "amount": -100,
                    "filled": 0,
                    "asset": self.ASSET133,
                    "stop": 3.0,
                    "limit": 3.4,
                })
        ]

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

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

        assert len(orders_txns) == 0

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

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

        assert len(orders_txns) == 1
        _, txn = orders_txns[0]

        expected_txn = {
            "price": float(3.49978125),
            "dt": datetime.datetime(2006, 1, 5, 14, 32, tzinfo=pytz.utc),
            "amount": int(-50),
            "asset": self.ASSET133,
        }

        for key, value in expected_txn.items():
            assert value == txn[key]
示例#29
0
    def test_volume_share_slippage(self):
        slippage_model = VolumeShareSlippage()

        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,
            ))

        assert len(orders_txns) == 1
        _, txn = orders_txns[0]

        expected_txn = {
            "price": float(3.0001875),
            "dt": datetime.datetime(2006, 1, 5, 14, 31, tzinfo=pytz.utc),
            "amount": int(5),
            "asset": self.ASSET133,
            "type": DATASOURCE_TYPE.TRANSACTION,
            "order_id": open_orders[0].id,
        }

        assert txn is not None

        # TODO: Make expected_txn an Transaction object and ensure there
        # is a __eq__ for that class.
        assert expected_txn == txn.__dict__

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

        # Set bar_data to be a minute ahead of last trade.
        # Volume share slippage should not execute when there is no trade.
        bar_data = self.create_bardata(
            simulation_dt_func=lambda: self.minutes[1], )

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

        assert len(orders_txns) == 0
示例#30
0
    def test_orders_stop_limit(self):
        slippage_model = VolumeShareSlippage()
        slippage_model.data_portal = self.data_portal

        # long, does not trade
        open_orders = [
            Order(
                **{
                    'dt': datetime.datetime(
                        2006, 1, 5, 14, 30, tzinfo=pytz.utc),
                    'amount': 100,
                    'filled': 0,
                    'asset': self.ASSET133,
                    'stop': 4.0,
                    'limit': 3.0
                })
        ]

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

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

        self.assertEquals(len(orders_txns), 0)

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

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

        self.assertEquals(len(orders_txns), 0)

        # long, does not trade - impacted price worse than limit price
        open_orders = [
            Order(
                **{
                    'dt': datetime.datetime(
                        2006, 1, 5, 14, 30, tzinfo=pytz.utc),
                    'amount': 100,
                    'filled': 0,
                    'asset': self.ASSET133,
                    'stop': 4.0,
                    'limit': 3.5
                })
        ]

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

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

        self.assertEquals(len(orders_txns), 0)

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

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

        self.assertEquals(len(orders_txns), 0)

        # long, does trade
        open_orders = [
            Order(
                **{
                    'dt': datetime.datetime(
                        2006, 1, 5, 14, 30, tzinfo=pytz.utc),
                    'amount': 100,
                    'filled': 0,
                    'asset': self.ASSET133,
                    'stop': 4.0,
                    'limit': 3.6
                })
        ]

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

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

        self.assertEquals(len(orders_txns), 0)

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

        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.50021875),
            'dt': datetime.datetime(2006, 1, 5, 14, 34, tzinfo=pytz.utc),
            'amount': int(50),
            'asset': self.ASSET133
        }

        for key, value in expected_txn.items():
            self.assertEquals(value, txn[key])

        # short, does not trade

        open_orders = [
            Order(
                **{
                    'dt': datetime.datetime(
                        2006, 1, 5, 14, 30, tzinfo=pytz.utc),
                    'amount': -100,
                    'filled': 0,
                    'asset': self.ASSET133,
                    'stop': 3.0,
                    'limit': 4.0
                })
        ]

        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), 0)

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

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

        self.assertEquals(len(orders_txns), 0)

        # short, does not trade - impacted price worse than limit price
        open_orders = [
            Order(
                **{
                    'dt': datetime.datetime(
                        2006, 1, 5, 14, 30, tzinfo=pytz.utc),
                    'amount': -100,
                    'filled': 0,
                    'asset': self.ASSET133,
                    'stop': 3.0,
                    'limit': 3.5
                })
        ]

        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), 0)

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

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

        self.assertEquals(len(orders_txns), 0)

        # short, does trade
        open_orders = [
            Order(
                **{
                    'dt': datetime.datetime(
                        2006, 1, 5, 14, 30, tzinfo=pytz.utc),
                    'amount': -100,
                    'filled': 0,
                    'asset': self.ASSET133,
                    'stop': 3.0,
                    'limit': 3.4
                })
        ]

        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), 0)

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

        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.49978125),
            'dt': datetime.datetime(2006, 1, 5, 14, 32, tzinfo=pytz.utc),
            'amount': int(-50),
            'asset': self.ASSET133,
        }

        for key, value in expected_txn.items():
            self.assertEquals(value, txn[key])
示例#31
0
    def test_orders_limit(self):
        slippage_model = VolumeShareSlippage()
        slippage_model.data_portal = self.data_portal

        # long, does not trade
        open_orders = [
            Order(
                **{
                    'dt': datetime.datetime(
                        2006, 1, 5, 14, 30, tzinfo=pytz.utc),
                    'amount': 100,
                    'filled': 0,
                    'asset': self.ASSET133,
                    'limit': 3.5
                })
        ]

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

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

        self.assertEquals(len(orders_txns), 0)

        # long, does not trade - impacted price worse than limit price
        open_orders = [
            Order(
                **{
                    'dt': datetime.datetime(
                        2006, 1, 5, 14, 30, tzinfo=pytz.utc),
                    'amount': 100,
                    'filled': 0,
                    'asset': self.ASSET133,
                    'limit': 3.5
                })
        ]

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

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

        self.assertEquals(len(orders_txns), 0)

        # long, does trade
        open_orders = [
            Order(
                **{
                    'dt': datetime.datetime(
                        2006, 1, 5, 14, 30, tzinfo=pytz.utc),
                    'amount': 100,
                    'filled': 0,
                    'asset': self.ASSET133,
                    'limit': 3.6
                })
        ]

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

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

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

        expected_txn = {
            'price': float(3.50021875),
            'dt': datetime.datetime(2006, 1, 5, 14, 34, tzinfo=pytz.utc),
            # we ordered 100 shares, but default volume slippage only allows
            # for 2.5% of the volume.  2.5% * 2000 = 50 shares
            'amount': int(50),
            'asset': self.ASSET133,
            'order_id': open_orders[0].id
        }

        self.assertIsNotNone(txn)

        for key, value in expected_txn.items():
            self.assertEquals(value, txn[key])

        # short, does not trade
        open_orders = [
            Order(
                **{
                    'dt': datetime.datetime(
                        2006, 1, 5, 14, 30, tzinfo=pytz.utc),
                    'amount': -100,
                    'filled': 0,
                    'asset': self.ASSET133,
                    'limit': 3.5
                })
        ]

        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), 0)

        # short, does not trade - impacted price worse than limit price
        open_orders = [
            Order(
                **{
                    'dt': datetime.datetime(
                        2006, 1, 5, 14, 30, tzinfo=pytz.utc),
                    'amount': -100,
                    'filled': 0,
                    'asset': self.ASSET133,
                    'limit': 3.5
                })
        ]

        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), 0)

        # short, does trade
        open_orders = [
            Order(
                **{
                    'dt': datetime.datetime(
                        2006, 1, 5, 14, 30, tzinfo=pytz.utc),
                    'amount': -100,
                    'filled': 0,
                    'asset': self.ASSET133,
                    'limit': 3.4
                })
        ]

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

        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.49978125),
            'dt': datetime.datetime(2006, 1, 5, 14, 32, tzinfo=pytz.utc),
            'amount': int(-50),
            'asset': self.ASSET133,
        }

        self.assertIsNotNone(txn)

        for key, value in expected_txn.items():
            self.assertEquals(value, txn[key])