Example #1
0
    def __convert_order_params_for_blotter(limit_price, stop_price, style):
        """
        Helper method for converting deprecated limit_price and stop_price
        arguments into ExecutionStyle instances.

        This function assumes that either style == None or (limit_price,
        stop_price) == (None, None).
        """
        if stop_price:
            raise OrderTypeNotSupported(order_type='stop')

        if style:
            if limit_price is not None:
                raise ValueError(
                    'An order style and a limit price was included in the '
                    'order. Please pick one to avoid any possible conflict.'
                )

            # Currently limiting order types or limit and market to
            # be in-line with CXXT and many exchanges. We'll consider
            # adding more order types in the future.
            if not isinstance(style, ExchangeLimitOrder) or \
                    not isinstance(style, MarketOrder):
                raise OrderTypeNotSupported(
                    order_type=style.__class__.__name__
                )

            return style

        if limit_price:
            return ExchangeLimitOrder(limit_price)
        else:
            return MarketOrder()
Example #2
0
    def test_orders(self):
        population = 3
        quote_currency = 'eth'
        order_amount = 0.1

        exchanges = select_random_exchanges(
            population=population,
            features=['fetchOrder'],
            is_authenticated=True,
            base_currency=quote_currency,
        )  # Type: list[Exchange]

        log_catcher = TestHandler()
        with log_catcher:
            for exchange in exchanges:
                exchange.init()

                assets = exchange.get_assets(quote_currency=quote_currency)
                asset = select_random_assets(assets, 1)[0]
                self.assertIsInstance(asset, TradingPair)

                tickers = exchange.tickers([asset])
                price = tickers[asset]['last_price']

                amount = order_amount / price

                limit_price = price * 0.8
                style = ExchangeLimitOrder(limit_price=limit_price)

                order = exchange.order(
                    asset=asset,
                    amount=amount,
                    style=style,
                )
                sleep(1)

                open_order, _ = exchange.get_order(order.id, asset)
                self.assertEqual(0, open_order.status)

                exchange.cancel_order(open_order, asset)
                sleep(1)

                canceled_order, _ = exchange.get_order(open_order.id, asset)
                warnings = [
                    record for record in log_catcher.records
                    if record.level == WARNING
                ]

                self.assertEqual(0, len(warnings))
                self.assertEqual(2, canceled_order.status)
                print('tested {exchange} / {symbol}, order: {order}'.format(
                    exchange=exchange.name,
                    symbol=asset.symbol,
                    order=order.id,
                ))
        pass
Example #3
0
 def test_order(self):
     log.info('creating order')
     asset = self.exchange.get_asset('eth_usdt')
     order_id = self.exchange.order(
         asset=asset,
         style=ExchangeLimitOrder(limit_price=1000),
         amount=1.01,
     )
     log.info('order created {}'.format(order_id))
     assert order_id is not None
     pass
Example #4
0
    def __convert_order_params_for_blotter(limit_price, stop_price, style):
        """
        Helper method for converting deprecated limit_price and stop_price
        arguments into ExecutionStyle instances.

        This function assumes that either style == None or (limit_price,
        stop_price) == (None, None).
        """
        if style:
            assert (limit_price, stop_price) == (None, None)
            return style
        if limit_price and stop_price:
            return ExchangeStopLimitOrder(limit_price, stop_price)
        if limit_price:
            return ExchangeLimitOrder(limit_price)
        if stop_price:
            return ExchangeStopOrder(stop_price)
        else:
            return MarketOrder()
    def test_orders(self):
        population = 3
        quote_currency = 'eth'
        order_amount = 0.1

        exchanges = select_random_exchanges(
            population=population,
            features=['fetchOrder'],
            is_authenticated=True,
            base_currency=quote_currency,
        )  # Type: list[Exchange]

        for exchange in exchanges:
            exchange.init()

            assets = exchange.get_assets(quote_currency=quote_currency)
            asset = select_random_assets(assets, 1)[0]
            assert asset

            tickers = exchange.tickers([asset])
            price = tickers[asset]['last_price']

            amount = order_amount / price

            limit_price = price * 0.8
            style = ExchangeLimitOrder(limit_price=limit_price)

            order = exchange.order(
                asset=asset,
                amount=amount,
                style=style,
            )
            sleep(1)

            open_order, _ = exchange.get_order(order.id, asset)
            assert open_order.status == 0

            exchange.cancel_order(open_order, asset)
            sleep(1)

            canceled_order, _ = exchange.get_order(open_order.id, asset)
            assert canceled_order.status == 2
        pass
Example #6
0
    def order(self,
              asset,
              amount,
              limit_price=None,
              stop_price=None,
              style=None):
        """Place an order.

        Parameters
        ----------
        asset : 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.
        limit_price : float, optional
            The limit price for the order.
        stop_price : float, optional
            The stop price for the order.
        style : ExecutionStyle, optional
            The execution style for the order.

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

        Notes
        -----
        The ``limit_price`` and ``stop_price`` arguments provide shorthands for
        passing common execution styles. Passing ``limit_price=N`` is
        equivalent to ``style=LimitOrder(N)``. Similarly, passing
        ``stop_price=M`` is equivalent to ``style=StopOrder(M)``, and passing
        ``limit_price=N`` and ``stop_price=M`` is equivalent to
        ``style=StopLimitOrder(N, M)``. It is an error to pass both a ``style``
        and ``limit_price`` or ``stop_price``.

        See Also
        --------
        :class:`catalyst.finance.execution.ExecutionStyle`
        :func:`catalyst.api.order_value`
        :func:`catalyst.api.order_percent`
        """
        if amount == 0:
            log.warn('skipping order amount of 0')
            return None

        if asset.base_currency != self.base_currency.lower():
            raise MismatchingBaseCurrencies(base_currency=asset.base_currency,
                                            algo_currency=self.base_currency)

        is_buy = (amount > 0)

        if limit_price is not None and stop_price is not None:
            style = ExchangeStopLimitOrder(limit_price,
                                           stop_price,
                                           exchange=self.name)
        elif limit_price is not None:
            style = ExchangeLimitOrder(limit_price, exchange=self.name)

        elif stop_price is not None:
            style = ExchangeStopOrder(stop_price, exchange=self.name)

        elif style is not None:
            raise InvalidOrderStyle(exchange=self.name.title(),
                                    style=style.__class__.__name__)
        else:
            raise ValueError('Incomplete order data.')

        display_price = limit_price if limit_price is not None else stop_price
        log.debug(
            'issuing {side} order of {amount} {symbol} for {type}: {price}'.
            format(side='buy' if is_buy else 'sell',
                   amount=amount,
                   symbol=asset.symbol,
                   type=style.__class__.__name__,
                   price='{}{}'.format(display_price, asset.base_currency)))
        order = self.create_order(asset, amount, is_buy, style)
        if order:
            self._portfolio.create_order(order)
            return order.id
        else:
            return None