Exemple #1
0
    def create_order(self, asset, amount, is_buy, style):
        """
        Creating order on the exchange.

        :param asset:
        :param amount:
        :param is_buy:
        :param style:
        :return:
        """
        exchange_symbol = self.get_symbol(asset)
        if isinstance(style, ExchangeLimitOrder) \
                or isinstance(style, ExchangeStopLimitOrder):
            price = style.get_limit_price(is_buy)
            order_type = 'limit'

        elif isinstance(style, ExchangeStopOrder):
            price = style.get_stop_price(is_buy)
            order_type = 'stop'

        else:
            raise InvalidOrderStyle(exchange=self.name,
                                    style=style.__class__.__name__)

        req = dict(
            symbol=exchange_symbol,
            amount=str(float(abs(amount))),
            price="{:.20f}".format(float(price)),
            side='buy' if is_buy else 'sell',
            type='exchange ' + order_type,  # TODO: support margin trades
            exchange=self.name,
            is_hidden=False,
            is_postonly=False,
            use_all_available=0,
            ocoorder=False,
            buy_price_oco=0,
            sell_price_oco=0)

        date = pd.Timestamp.utcnow()
        try:
            self.ask_request()
            response = self._request('order/new', req)
            order_status = response.json()
        except Exception as e:
            raise ExchangeRequestError(error=e)

        if 'message' in order_status:
            raise ExchangeRequestError(
                error='unable to create Bitfinex order {}'.format(
                    order_status['message']))

        order_id = str(order_status['id'])
        order = Order(dt=date,
                      asset=asset,
                      amount=amount,
                      stop=style.get_stop_price(is_buy),
                      limit=style.get_limit_price(is_buy),
                      id=order_id)

        return order
Exemple #2
0
    def get_order(self, order_id):
        """Lookup an order based on the order id returned from one of the
        order functions.

        Parameters
        ----------
        order_id : str
            The unique identifier for the order.

        Returns
        -------
        order : Order
            The order object.
        """
        try:
            self.ask_request()
            response = self._request('order/status',
                                     {'order_id': int(order_id)})
            order_status = response.json()
        except Exception as e:
            raise ExchangeRequestError(error=e)

        if 'message' in order_status:
            raise ExchangeRequestError(
                error='Unable to retrieve order status: {}'.format(
                    order_status['message']))
        return self._create_order(order_status)
Exemple #3
0
    def get_open_orders(self, asset=None):
        """Retrieve all of the current open orders.

        Parameters
        ----------
        asset : Asset
            If passed and not None, return only the open orders for the given
            asset instead of all open orders.

        Returns
        -------
        open_orders : dict[list[Order]] or list[Order]
            If no asset is passed this will return a dict mapping Assets
            to a list containing all the open orders for the asset.
            If an asset is passed then this will return a list of the open
            orders for this asset.
        """
        try:
            response = self._request('orders', None)
            order_statuses = response.json()
        except Exception as e:
            raise ExchangeRequestError(error=e)

        if 'message' in order_statuses:
            raise ExchangeRequestError(
                error='Unable to retrieve open orders: {}'.format(
                    order_statuses['message']))

        orders = list()
        for order_status in order_statuses:
            order, executed_price = self._create_order(order_status)
            if asset is None or asset == order.sid:
                orders.append(order)

        return orders
Exemple #4
0
    def get_open_orders(self, asset='all'):
        """Retrieve all of the current open orders.

        Parameters
        ----------
        asset : Asset
            If passed and not 'all', return only the open orders for the given
            asset instead of all open orders.

        Returns
        -------
        open_orders : dict[list[Order]] or list[Order]
            If 'all' is passed this will return a dict mapping Assets
            to a list containing all the open orders for the asset.
            If an asset is passed then this will return a list of the open
            orders for this asset.
        """

        return self.portfolio.open_orders

        """
            TODO: Why going to the exchange if we already have this info locally?
                  And why creating all these Orders if we later discard them?
        """

        try:
            if (asset == 'all'):
                response = self.api.returnopenorders('all')
            else:
                response = self.api.returnopenorders(self.get_symbol(asset))
        except Exception as e:
            raise ExchangeRequestError(error=e)

        if 'error' in response:
            raise ExchangeRequestError(
                error='Unable to retrieve open orders: {}'.format(
                    order_statuses['message'])
            )

        print(self.portfolio.open_orders)

        # TODO: Need to handle openOrders for 'all'
        orders = list()
        for order_status in response:
            order, executed_price = self._create_order(
                order_status)  # will Throw error b/c Polo doesn't track order['symbol']
            if asset is None or asset == order.sid:
                orders.append(order)

        return orders
Exemple #5
0
    def tickers(self, assets):
        """
        Fetch ticket data for assets
        https://docs.bitfinex.com/v2/reference#rest-public-tickers

        :param assets:
        :return:
        """
        symbols = self._get_v2_symbols(assets)
        log.debug('fetching tickers {}'.format(symbols))

        try:
            self.ask_request()
            response = requests.get(
                '{url}/v2/tickers?symbols={symbols}'.format(
                    url=self.url,
                    symbols=','.join(symbols),
                ))
        except Exception as e:
            raise ExchangeRequestError(error=e)

        if 'error' in response.content:
            raise ExchangeRequestError(error='Unable to retrieve tickers: {}'.
                                       format(response.content))

        try:
            tickers = response.json()
        except Exception as e:
            raise ExchangeRequestError(error=e)

        ticks = dict()
        for index, ticker in enumerate(tickers):
            if not len(ticker) == 11:
                raise ExchangeRequestError(
                    error='Invalid ticker in response: {}'.format(ticker))

            ticks[assets[index]] = dict(
                timestamp=pd.Timestamp.utcnow(),
                bid=ticker[1],
                ask=ticker[3],
                last_price=ticker[7],
                low=ticker[10],
                high=ticker[9],
                volume=ticker[8],
            )

        log.debug('got tickers {}'.format(ticks))
        return ticks
Exemple #6
0
    def get_order(self, order_id):
        """Lookup an order based on the order id returned from one of the
        order functions.

        Parameters
        ----------
        order_id : str
            The unique identifier for the order.

        Returns
        -------
        order : Order
            The order object.
        """

        try:
            order = self._portfolio.open_orders[order_id]
        except Exception as e:
            raise OrphanOrderError(order_id=order_id, exchange=self.name)

        return order

        # TODO: Need to decide whether we fetch orders locally or from exchnage
        # The code below is ignored

        try:
            response = self.api.returnopenorders(self.get_symbol(order.sid))
        except Exception as e:
            raise ExchangeRequestError(error=e)

        for o in response:
            if (int(o['orderNumber']) == int(order_id)):
                return order

        return None
Exemple #7
0
    def cancel_order(self, order_param):
        """Cancel an open order.

        Parameters
        ----------
        order_param : str or Order
            The order_id or order object to cancel.
        """

        if (isinstance(order_param, Order)):
            order = order_param
        else:
            order = self._portfolio.open_orders[order_param]

        try:
            response = self.api.cancelorder(order.id)
        except Exception as e:
            raise ExchangeRequestError(error=e)

        if 'error' in response:
            log.info(
                'Unable to cancel order {order_id} on exchange {exchange} '
                '{error}.'.format(order_id=order.id,
                                  exchange=self.name,
                                  error=response['error']))

            # raise OrderCancelError(
            #    order_id=order.id,
            #    exchange=self.name,
            #    error=response['error']
            # )

        self.portfolio.remove_order(order)
Exemple #8
0
    def tickers(self, assets):
        """
        As of v1.1, Bittrex only allows one ticker at the time.
        So we have to make multiple calls to fetch multiple assets.

        :param assets:
        :return:
        """
        log.info('retrieving tickers')

        ticks = dict()
        for asset in assets:
            symbol = self.get_symbol(asset)
            try:
                self.ask_request()
                ticker = self.api.getticker(symbol)
            except Exception as e:
                raise ExchangeRequestError(error=e)

            # TODO: catch invalid ticker
            ticks[asset] = dict(timestamp=pd.Timestamp.utcnow(),
                                bid=ticker['Bid'],
                                ask=ticker['Ask'],
                                last_price=ticker['Last'])

        log.debug('got tickers {}'.format(ticks))
        return ticks
Exemple #9
0
    def get_trades(self, asset, my_trades=True, start_dt=None, limit=100):
        if not my_trades:
            raise NotImplemented(
                'get_trades only supports "my trades"'
            )

        # TODO: is it possible to sort this? Limit is useless otherwise.
        ccxt_symbol = self.get_symbol(asset)
        try:
            trades = self.api.fetch_my_trades(
                symbol=ccxt_symbol,
                since=start_dt,
                limit=limit,
            )
        except RequestTimeout as e:
            log.warn(
                'unable to fetch trades {} / {}: {}'.format(
                    self.name, asset.symbol, e
                )
            )
            raise e
        except (ExchangeError, NetworkError) as e:
            log.warn(
                'unable to fetch trades {} / {}: {}'.format(
                    self.name, asset.symbol, e
                )
            )
            raise ExchangeRequestError(error=e)

        return trades
Exemple #10
0
    def init(self):
        if self._is_init:
            return

        exchange_folder = get_exchange_folder(self.name)
        filename = os.path.join(exchange_folder, 'cctx_markets.json')

        if os.path.exists(filename):
            timestamp = os.path.getmtime(filename)
            dt = pd.to_datetime(timestamp, unit='s', utc=True)

            if dt >= pd.Timestamp.utcnow().floor('1D'):
                with open(filename) as f:
                    self.markets = json.load(f)

                log.debug('loaded markets for {}'.format(self.name))

        if self.markets is None:
            try:
                markets_symbols = self.api.load_markets()
                log.debug(
                    'fetching {} markets:\n{}'.format(
                        self.name, markets_symbols
                    )
                )

                self.markets = self.api.fetch_markets()
                with open(filename, 'w+') as f:
                    json.dump(self.markets, f, indent=4)

            except ExchangeNotAvailable as e:
                raise ExchangeRequestError(error=e)

        self.load_assets()
        self._is_init = True
Exemple #11
0
    def get_order(self, order_id, asset_or_symbol=None, return_price=False):
        if asset_or_symbol is None:
            log.debug(
                'order not found in memory, the request might fail '
                'on some exchanges.'
            )
        try:
            symbol = self.get_symbol(asset_or_symbol) \
                if asset_or_symbol is not None else None
            order_status = self.api.fetch_order(id=order_id, symbol=symbol)
            order, executed_price = self._create_order(order_status)

            if return_price:
                return order, executed_price

            else:
                return order

        except (ExchangeError, NetworkError) as e:
            log.warn(
                'unable to fetch order {} / {}: {}'.format(
                    self.name, order_id, e
                )
            )
            raise ExchangeRequestError(error=e)
Exemple #12
0
    def create_order(self, asset, amount, is_buy, style):
        log.info('creating {} order'.format('buy' if is_buy else 'sell'))
        exchange_symbol = self.get_symbol(asset)

        if isinstance(style, LimitOrder) or isinstance(style, StopLimitOrder):
            if isinstance(style, StopLimitOrder):
                log.warn('{} will ignore the stop price'.format(self.name))

            price = style.get_limit_price(is_buy)
            try:
                if is_buy:
                    order_status = self.api.buylimit(exchange_symbol, amount,
                                                     price)
                else:
                    order_status = self.api.selllimit(exchange_symbol,
                                                      abs(amount), price)
            except Exception as e:
                raise ExchangeRequestError(error=e)

            if 'uuid' in order_status:
                order_id = order_status['uuid']
                order = Order(dt=pd.Timestamp.utcnow(),
                              asset=asset,
                              amount=amount,
                              stop=style.get_stop_price(is_buy),
                              limit=style.get_limit_price(is_buy),
                              id=order_id)
                return order
            else:
                raise CreateOrderError(exchange=self.name, error=order_status)
        else:
            raise InvalidOrderStyle(exchange=self.name,
                                    style=style.__class__.__name__)
Exemple #13
0
    def get_symbol_start_date(self, symbol):

        print(symbol)
        symbol_v2 = 't' + symbol.upper()
        """
            For each symbol we retrieve candles with Monhtly resolution
            We get the first month, and query again with daily resolution
            around that date, and we get the first date
        """
        url = '{url}/v2/candles/trade:1M:{symbol}/hist'.format(
            url=self.url, symbol=symbol_v2)

        try:
            self.ask_request()
            response = requests.get(url)
        except Exception as e:
            raise ExchangeRequestError(error=e)
        """
            If we don't get any data back for our monthly-resolution query
            it means that symbol started trading less than a month ago, so
            arbitrarily set the ref. date to 15 days ago to be safe with
            +/- 31 days
        """
        if (len(response.json())):
            startmonth = response.json()[-1][0]
        else:
            startmonth = int((time.time() - 15 * 24 * 3600) * 1000)
        """
            Query again with daily resolution setting the start and end around
            the startmonth we got above. Avoid end dates greater than
            now: time.time()
        """
        url = ('{url}/v2/candles/trade:1D:{symbol}/hist?start={start}'
               '&end={end}').format(url=self.url,
                                    symbol=symbol_v2,
                                    start=startmonth - 3600 * 24 * 31 * 1000,
                                    end=min(startmonth + 3600 * 24 * 31 * 1000,
                                            int(time.time() * 1000)))

        try:
            self.ask_request()
            response = requests.get(url)
        except Exception as e:
            raise ExchangeRequestError(error=e)

        return time.strftime('%Y-%m-%d',
                             time.gmtime(int(response.json()[-1][0] / 1000)))
Exemple #14
0
    def get_symbol_start_date(self, symbol):
        try:
            r = self.api.returnchartdata(symbol, 86400, pd.to_datetime(
                '2010-1-1').value // 10 ** 9)
        except Exception as e:
            raise ExchangeRequestError(error=e)

        return time.strftime('%Y-%m-%d', time.gmtime(int(r[0]['date'])))
Exemple #15
0
    def get_balances(self):
        balances = self.api.returnbalances()
        try:
            log.debug('retrieving wallets balances')
        except Exception as e:
            log.debug(e)
            raise ExchangeRequestError(error=e)

        if 'error' in balances:
            raise ExchangeRequestError(
                error='unable to fetch balance {}'.format(balances['error']))

        std_balances = dict()
        for (key, value) in iteritems(balances):
            currency = key.lower()
            std_balances[currency] = float(value)

        return std_balances
Exemple #16
0
    def tickers(self, assets):
        """
        Retrieve current tick data for the given assets

        Parameters
        ----------
        assets: list[TradingPair]

        Returns
        -------
        list[dict[str, float]

        """
        tickers = dict()
        try:
            for asset in assets:
                symbol = self.get_symbol(asset)
                # TODO: use fetch_tickers() for efficiency
                # I tried using fetch_tickers() but noticed some
                # inconsistencies, see issue:
                # https://github.com/ccxt/ccxt/issues/870
                ticker = self.api.fetch_ticker(symbol=symbol)
                if not ticker:
                    log.warn('ticker not found for {} {}'.format(
                        self.name, symbol
                    ))
                    continue

                ticker['last_traded'] = from_ms_timestamp(ticker['timestamp'])

                if 'last_price' not in ticker:
                    # TODO: any more exceptions?
                    ticker['last_price'] = ticker['last']

                if 'baseVolume' in ticker and ticker['baseVolume'] is not None:
                    # Using the volume represented in the base currency
                    ticker['volume'] = ticker['baseVolume']

                elif 'info' in ticker and 'bidQty' in ticker['info'] \
                        and 'askQty' in ticker['info']:
                    ticker['volume'] = float(ticker['info']['bidQty']) + \
                                       float(ticker['info']['askQty'])

                else:
                    ticker['volume'] = 0

                tickers[asset] = ticker

        except ExchangeNotAvailable as e:
            log.warn(
                'unable to fetch ticker: {} {}'.format(
                    self.name, asset.symbol
                )
            )
            raise ExchangeRequestError(error=e)

        return tickers
Exemple #17
0
    def create_order(self, asset, amount, is_buy, style):
        symbol = self.get_symbol(asset)

        if isinstance(style, ExchangeLimitOrder):
            price = style.get_limit_price(is_buy)
            order_type = 'limit'

        elif isinstance(style, MarketOrder):
            price = None
            order_type = 'market'

        else:
            raise InvalidOrderStyle(exchange=self.name,
                                    style=style.__class__.__name__)

        side = 'buy' if amount > 0 else 'sell'

        if hasattr(self.api, 'amount_to_lots'):
            adj_amount = self.api.amount_to_lots(
                symbol=symbol,
                amount=abs(amount),
            )
            if adj_amount != abs(amount):
                log.info(
                    'adjusted order amount {} to {} based on lot size'.format(
                        abs(amount),
                        adj_amount,
                    ))
        else:
            adj_amount = abs(amount)

        try:
            result = self.api.create_order(symbol=symbol,
                                           type=order_type,
                                           side=side,
                                           amount=adj_amount,
                                           price=price)
        except ExchangeNotAvailable as e:
            log.debug('unable to create order: {}'.format(e))
            raise ExchangeRequestError(error=e)

        except InvalidOrder as e:
            log.warn('the exchange rejected the order: {}'.format(e))
            raise CreateOrderError(exchange=self.name, error=e)

        if 'info' not in result:
            raise ValueError('cannot use order without info attribute')

        final_amount = adj_amount if side == 'buy' else -adj_amount
        order_id = result['id']
        order = Order(dt=pd.Timestamp.utcnow(),
                      asset=asset,
                      amount=final_amount,
                      stop=style.get_stop_price(is_buy),
                      limit=style.get_limit_price(is_buy),
                      id=order_id)
        return order
Exemple #18
0
    def get_balances(self):
        log.debug('retrieving wallets balances')
        try:
            response = self._request('balances', None)
            balances = response.json()
        except Exception as e:
            raise ExchangeRequestError(error=e)

        if 'message' in balances:
            raise ExchangeRequestError(
                error='unable to fetch balance {}'.format(balances['message']))

        std_balances = dict()
        for balance in balances:
            currency = balance['currency'].lower()
            std_balances[currency] = float(balance['available'])

        return std_balances
Exemple #19
0
    def get_balances(self):
        balances = self.api.getbalances()
        try:
            log.debug('retrieving wallet balances')
            self.ask_request()

        except Exception as e:
            raise ExchangeRequestError(error=e)

        std_balances = dict()
        try:
            for balance in balances:
                currency = balance['Currency'].lower()
                std_balances[currency] = balance['Available']

        except TypeError:
            raise ExchangeRequestError(error=balances)

        return std_balances
Exemple #20
0
    def get_order(self, order_id):
        log.info('retrieving order {}'.format(order_id))
        try:
            order_status = self.api.getorder(order_id)
        except Exception as e:
            raise ExchangeRequestError(error=e)

        if order_status is None:
            raise OrderNotFound(order_id=order_id, exchange=self.name)

        return self._create_order(order_status)
Exemple #21
0
    def get_order(self,
                  order_id,
                  asset_or_symbol=None,
                  return_price=False,
                  params={}):
        """Lookup an order based on the order id returned from one of the
        order functions.

        Parameters
        ----------
        order_id : str
            The unique identifier for the order.
        asset_or_symbol: Asset or str
            The asset or the tradingPair symbol of the order.
        return_price: bool
            get the trading price in addition to the order
        params: dict, optional
            Extra parameters to pass to the exchange

        Returns
        -------
        order : Order
            The order object.
        execution_price: float
            The execution price per unit of the order if return_price is True
        """
        if asset_or_symbol is None:
            log.debug('order not found in memory, the request might fail '
                      'on some exchanges.')
        try:
            symbol = self.get_symbol(asset_or_symbol) \
                if asset_or_symbol is not None else None
            # TODO review if Kucoin still needs this exception with API2.0
            if self.api.id == "kucoin":
                order_status = self.api.fetch_order(id=order_id,
                                                    symbol=symbol,
                                                    params=params)
            else:
                order_status = self.api.fetch_order(id=order_id,
                                                    symbol=symbol,
                                                    params={})
            order, executed_price = self._create_order(order_status)

            if return_price:
                return order, executed_price

            else:
                return order

        except (ExchangeError, NetworkError) as e:
            log.warn('unable to fetch order {} / {}: {}'.format(
                self.name, order_id, e))
            raise ExchangeRequestError(error=e)
Exemple #22
0
    def tickers(self, assets):
        """
        Fetch ticket data for assets
        https://docs.bitfinex.com/v2/reference#rest-public-tickers

        :param assets:
        :return:
        """
        symbols = self.get_symbols(assets)

        log.debug('fetching tickers {}'.format(symbols))

        try:
            response = self.api.returnticker()
        except Exception as e:
            raise ExchangeRequestError(error=e)

        if 'error' in response:
            raise ExchangeRequestError(
                error='Unable to retrieve tickers: {}'.format(
                    response['error'])
            )

        ticks = dict()

        for index, symbol in enumerate(symbols):
            ticks[assets[index]] = dict(
                timestamp=pd.Timestamp.utcnow(),
                bid=float(response[symbol]['highestBid']),
                ask=float(response[symbol]['lowestAsk']),
                last_price=float(response[symbol]['last']),
                low=float(response[symbol]['lowestAsk']),
                # TODO: Polo does not provide low
                high=float(response[symbol]['highestBid']),
                # TODO: Polo does not provide high
                volume=float(response[symbol]['baseVolume']),
            )

        log.debug('got tickers {}'.format(ticks))
        return ticks
Exemple #23
0
    def get_open_orders(self, asset):
        symbol = self.get_symbol(asset)
        try:
            open_orders = self.api.getopenorders(symbol)
        except Exception as e:
            raise ExchangeRequestError(error=e)

        orders = list()
        for order_status in open_orders:
            order = self._create_order(order_status)
            orders.append(order)

        return orders
Exemple #24
0
    def get_balances(self):
        try:
            log.debug('retrieving wallets balances')
            balances = self.api.fetch_balance()

            balances_lower = dict()
            for key in balances:
                balances_lower[key.lower()] = balances[key]

        except (ExchangeError, NetworkError) as e:
            log.warn('unable to fetch balance {}: {}'.format(self.name, e))
            raise ExchangeRequestError(error=e)

        return balances_lower
Exemple #25
0
    def process_order(self, order):
        # TODO: move to parent class after tracking features in the parent
        if not self.api.has['fetchMyTrades']:
            return self._process_order_fallback(order)

        try:
            all_trades = self.get_trades(order.asset)
        except RequestTimeout as e:
            raise ExchangeRequestError(error="Received timeout from exchange")
        except ExchangeRequestError as e:
            log.warn('unable to fetch account trades, trying an alternate '
                     'method to find executed order {} / {}: {}'.format(
                         order.id, order.asset.symbol, e))
            return self._process_order_fallback(order)

        transactions = []
        trades = [t for t in all_trades if t['order'] == order.id]
        if not trades:
            log.debug('order {} / {} not found in trades'.format(
                order.id, order.asset.symbol))
            return transactions

        trades.sort(key=lambda t: t['timestamp'], reverse=False)
        order.filled = 0
        order.commission = 0
        for trade in trades:
            # status property will update automatically
            filled = trade['amount'] * order.direction
            order.filled += filled

            commission = 0
            if 'fee' in trade and 'cost' in trade['fee']:
                commission = trade['fee']['cost']
                order.commission += commission

            order.check_triggers(
                price=trade['price'],
                dt=pd.to_datetime(trade['timestamp'], unit='ms', utc=True),
            )
            transaction = Transaction(asset=order.asset,
                                      amount=filled,
                                      dt=pd.Timestamp.utcnow(),
                                      price=trade['price'],
                                      order_id=order.id,
                                      commission=commission)
            transactions.append(transaction)

        order.filled = round(order.filled, order.asset.decimals)
        order.broker_order_id = ', '.join([t['id'] for t in trades])
        return transactions
Exemple #26
0
    def cancel_order(self, order_param):
        order_id = order_param.id \
            if isinstance(order_param, Order) else order_param
        log.info('cancelling order {}'.format(order_id))

        try:
            status = self.api.cancel(order_id)
        except Exception as e:
            raise ExchangeRequestError(error=e)

        if 'message' in status:
            raise OrderCancelError(order_id=order_id,
                                   exchange=self.name,
                                   error=status['message'])
Exemple #27
0
    def get_balances(self):
        try:
            log.debug('retrieving wallets balances')
            balances = self.api.fetch_balance()

            balances_lower = dict()
            for key in balances:
                balances_lower[key.lower()] = balances[key]

        except Exception as e:
            log.debug('error retrieving balances: {}', e)
            raise ExchangeRequestError(error=e)

        return balances_lower
Exemple #28
0
    def cancel_order(self, order_param, asset_or_symbol=None):
        order_id = order_param.id \
            if isinstance(order_param, Order) else order_param

        if asset_or_symbol is None:
            log.debug('order not found in memory, cancelling order might fail '
                      'on some exchanges.')
        try:
            symbol = self.get_symbol(asset_or_symbol) \
                if asset_or_symbol is not None else None
            self.api.cancel_order(id=order_id, symbol=symbol)

        except Exception as e:
            raise ExchangeRequestError(error=e)
Exemple #29
0
    def get_order(self, order_id, asset_or_symbol=None):
        if asset_or_symbol is None:
            log.debug('order not found in memory, the request might fail '
                      'on some exchanges.')
        try:
            symbol = self.get_symbol(asset_or_symbol) \
                if asset_or_symbol is not None else None
            order_status = self.api.fetch_order(id=order_id, symbol=symbol)
            order, executed_price = self._create_order(order_status)

        except Exception as e:
            raise ExchangeRequestError(error=e)

        return order, executed_price
Exemple #30
0
    def create_order(self, asset, amount, is_buy, style):
        """
        Creating order on the exchange.

        :param asset:
        :param amount:
        :param is_buy:
        :param style:
        :return:
        """
        exchange_symbol = self.get_symbol(asset)

        if isinstance(style, ExchangeLimitOrder) or isinstance(style,
                                                               ExchangeStopLimitOrder):
            if isinstance(style, ExchangeStopLimitOrder):
                log.warn('{} will ignore the stop price'.format(self.name))

            price = style.get_limit_price(is_buy)

            try:
                if (is_buy):
                    response = self.api.buy(exchange_symbol, amount, price)
                else:
                    response = self.api.sell(exchange_symbol, -amount, price)
            except Exception as e:
                raise ExchangeRequestError(error=e)

            date = pd.Timestamp.utcnow()

            if ('orderNumber' in response):
                order_id = str(response['orderNumber'])
                order = Order(
                    dt=date,
                    asset=asset,
                    amount=amount,
                    stop=style.get_stop_price(is_buy),
                    limit=style.get_limit_price(is_buy),
                    id=order_id
                )
                return order
            else:
                log.warn(
                    '{} order failed: {}'.format('buy' if is_buy else 'sell',
                                                 response['error']))
                return None
        else:
            raise InvalidOrderStyle(exchange=self.name,
                                    style=style.__class__.__name__)