コード例 #1
0
ファイル: kraken.py プロジェクト: derek-walter/GCT
    def get_balances(self) -> dict:
        if self._config['dry_run']:
            return {}

        try:
            balances = self._api.fetch_balance()
            # Remove additional info from ccxt results
            balances.pop("info", None)
            balances.pop("free", None)
            balances.pop("total", None)
            balances.pop("used", None)

            orders = self._api.fetch_open_orders()
            order_list = [
                (
                    x["symbol"].split("/")[0 if x["side"] == "sell" else 1],
                    x["remaining"],
                    # Don't remove the below comment, this can be important for debuggung
                    # x["side"], x["amount"],
                ) for x in orders
            ]
            for bal in balances:
                balances[bal]['used'] = sum(order[1] for order in order_list
                                            if order[0] == bal)
                balances[bal][
                    'free'] = balances[bal]['total'] - balances[bal]['used']

            return balances
        except (ccxt.NetworkError, ccxt.ExchangeError) as e:
            raise TemporaryError(
                f'Could not get balance due to {e.__class__.__name__}. Message: {e}'
            ) from e
        except ccxt.BaseError as e:
            raise OperationalException(e) from e
コード例 #2
0
    def create_order(self,
                     pair: str,
                     ordertype: str,
                     side: str,
                     amount: float,
                     rate: float,
                     params: Dict = {}) -> Dict:
        try:
            # Set the precision for amount and price(rate) as accepted by the exchange
            amount = self.amount_to_precision(pair, amount)
            needs_price = (ordertype != 'market' or self._api.options.get(
                "createMarketBuyOrderRequiresPrice", False))
            rate_for_order = self.price_to_precision(
                pair, rate) if needs_price else None

            return self._api.create_order(pair, ordertype, side, amount,
                                          rate_for_order, params)

        except ccxt.InsufficientFunds as e:
            raise DependencyException(
                f'Insufficient funds to create {ordertype} {side} order on market {pair}.'
                f'Tried to {side} amount {amount} at rate {rate}.'
                f'Message: {e}') from e
        except ccxt.InvalidOrder as e:
            raise DependencyException(
                f'Could not create {ordertype} {side} order on market {pair}.'
                f'Tried to {side} amount {amount} at rate {rate}.'
                f'Message: {e}') from e
        except (ccxt.NetworkError, ccxt.ExchangeError) as e:
            raise TemporaryError(
                f'Could not place {side} order due to {e.__class__.__name__}. Message: {e}'
            ) from e
        except ccxt.BaseError as e:
            raise OperationalException(e) from e
コード例 #3
0
ファイル: ftx.py プロジェクト: yzcs/freqtrade
    def fetch_stoploss_order(self, order_id: str, pair: str) -> Dict:
        if self._config['dry_run']:
            try:
                order = self._dry_run_open_orders[order_id]
                return order
            except KeyError as e:
                # Gracefully handle errors with dry-run orders.
                raise InvalidOrderException(
                    f'Tried to get an invalid dry-run-order (id: {order_id}). Message: {e}'
                ) from e
        try:
            orders = self._api.fetch_orders(pair,
                                            None,
                                            params={'type': 'stop'})

            order = [order for order in orders if order['id'] == order_id]
            if len(order) == 1:
                return order[0]
            else:
                raise InvalidOrderException(
                    f"Could not get stoploss order for id {order_id}")

        except ccxt.InvalidOrder as e:
            raise InvalidOrderException(
                f'Tried to get an invalid order (id: {order_id}). Message: {e}'
            ) from e
        except ccxt.DDoSProtection as e:
            raise DDosProtection(e) from e
        except (ccxt.NetworkError, ccxt.ExchangeError) as e:
            raise TemporaryError(
                f'Could not get order due to {e.__class__.__name__}. Message: {e}'
            ) from e
        except ccxt.BaseError as e:
            raise OperationalException(e) from e
コード例 #4
0
def test_rpc_balance_handle_error(default_conf, mocker):
    mock_balance = {
        'BTC': {
            'free': 10.0,
            'total': 12.0,
            'used': 2.0,
        },
        'ETH': {
            'free': 1.0,
            'total': 5.0,
            'used': 4.0,
        }
    }
    # ETH will be skipped due to mocked Error below

    mocker.patch.multiple(
        'freqtrade.rpc.fiat_convert.CoinGeckoAPI',
        get_price=MagicMock(return_value={'bitcoin': {'usd': 15000.0}}),
    )
    mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0)
    mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
    mocker.patch.multiple(
        'freqtrade.exchange.Exchange',
        get_balances=MagicMock(return_value=mock_balance),
        get_tickers=MagicMock(side_effect=TemporaryError('Could not load ticker due to xxx'))
    )

    freqtradebot = get_patched_freqtradebot(mocker, default_conf)
    patch_get_signal(freqtradebot, (True, False))
    rpc = RPC(freqtradebot)
    rpc._fiat_converter = CryptoToFiatConverter()
    with pytest.raises(RPCException, match="Error getting current tickers."):
        rpc._rpc_balance(default_conf['stake_currency'], default_conf['fiat_display_currency'])
コード例 #5
0
ファイル: exchange.py プロジェクト: uncaughtgregory/freqtrade
    def get_trades_for_order(self, order_id: str, pair: str, since: datetime) -> List:
        """
        Fetch Orders using the "fetch_my_trades" endpoint and filter them by order-id.
        The "since" argument passed in is coming from the database and is in UTC,
        as timezone-native datetime object.
        From the python documentation:
            > Naive datetime instances are assumed to represent local time
        Therefore, calling "since.timestamp()" will get the UTC timestamp, after applying the
        transformation from local timezone to UTC.
        This works for timezones UTC+ since then the result will contain trades from a few hours
        instead of from the last 5 seconds, however fails for UTC- timezones,
        since we're then asking for trades with a "since" argument in the future.

        :param order_id order_id: Order-id as given when creating the order
        :param pair: Pair the order is for
        :param since: datetime object of the order creation time. Assumes object is in UTC.
        """
        if self._config['dry_run']:
            return []
        if not self.exchange_has('fetchMyTrades'):
            return []
        try:
            # Allow 5s offset to catch slight time offsets (discovered in #1185)
            # since needs to be int in milliseconds
            my_trades = self._api.fetch_my_trades(
                pair, int((since.replace(tzinfo=timezone.utc).timestamp() - 5) * 1000))
            matched_trades = [trade for trade in my_trades if trade['order'] == order_id]

            return matched_trades

        except ccxt.NetworkError as e:
            raise TemporaryError(
                f'Could not get trades due to networking error. Message: {e}') from e
        except ccxt.BaseError as e:
            raise OperationalException(e) from e
コード例 #6
0
ファイル: exchange.py プロジェクト: uncaughtgregory/freqtrade
 async def _async_fetch_trades(self, pair: str,
                               since: Optional[int] = None,
                               params: Optional[dict] = None) -> List[Dict]:
     """
     Asyncronously gets trade history using fetch_trades.
     Handles exchange errors, does one call to the exchange.
     :param pair: Pair to fetch trade data for
     :param since: Since as integer timestamp in milliseconds
     returns: List of dicts containing trades
     """
     try:
         # fetch trades asynchronously
         if params:
             logger.debug("Fetching trades for pair %s, params: %s ", pair, params)
             trades = await self._api_async.fetch_trades(pair, params=params, limit=1000)
         else:
             logger.debug(
                 "Fetching trades for pair %s, since %s %s...",
                 pair,  since,
                 '(' + arrow.get(since // 1000).isoformat() + ') ' if since is not None else ''
             )
             trades = await self._api_async.fetch_trades(pair, since=since, limit=1000)
         return trades
     except ccxt.NotSupported as e:
         raise OperationalException(
             f'Exchange {self._api.name} does not support fetching historical trade data.'
             f'Message: {e}') from e
     except (ccxt.NetworkError, ccxt.ExchangeError) as e:
         raise TemporaryError(f'Could not load trade history due to {e.__class__.__name__}. '
                              f'Message: {e}') from e
     except ccxt.BaseError as e:
         raise OperationalException(f'Could not fetch trade data. Msg: {e}') from e
コード例 #7
0
ファイル: ftx.py プロジェクト: iamjamilspain/freqtrade
    def stoploss(self, pair: str, amount: float, stop_price: float,
                 order_types: Dict) -> Dict:
        """
        Creates a stoploss order.
        depending on order_types.stoploss configuration, uses 'market' or limit order.

        Limit orders are defined by having orderPrice set, otherwise a market order is used.
        """
        limit_price_pct = order_types.get('stoploss_on_exchange_limit_ratio',
                                          0.99)
        limit_rate = stop_price * limit_price_pct

        ordertype = "stop"

        stop_price = self.price_to_precision(pair, stop_price)

        if self._config['dry_run']:
            dry_order = self.create_dry_run_order(pair, ordertype, "sell",
                                                  amount, stop_price)
            return dry_order

        try:
            params = self._params.copy()
            if order_types.get('stoploss', 'market') == 'limit':
                # set orderPrice to place limit order, otherwise it's a market order
                params['orderPrice'] = limit_rate

            params['stopPrice'] = stop_price
            amount = self.amount_to_precision(pair, amount)

            order = self._api.create_order(symbol=pair,
                                           type=ordertype,
                                           side='sell',
                                           amount=amount,
                                           params=params)
            self._log_exchange_response('create_stoploss_order', order)
            logger.info('stoploss order added for %s. '
                        'stop price: %s.', pair, stop_price)
            return order
        except ccxt.InsufficientFunds as e:
            raise InsufficientFundsError(
                f'Insufficient funds to create {ordertype} sell order on market {pair}. '
                f'Tried to create stoploss with amount {amount} at stoploss {stop_price}. '
                f'Message: {e}') from e
        except ccxt.InvalidOrder as e:
            raise InvalidOrderException(
                f'Could not create {ordertype} sell order on market {pair}. '
                f'Tried to create stoploss with amount {amount} at stoploss {stop_price}. '
                f'Message: {e}') from e
        except ccxt.DDoSProtection as e:
            raise DDosProtection(e) from e
        except (ccxt.NetworkError, ccxt.ExchangeError) as e:
            raise TemporaryError(
                f'Could not place sell order due to {e.__class__.__name__}. Message: {e}'
            ) from e
        except ccxt.BaseError as e:
            raise OperationalException(e) from e
コード例 #8
0
ファイル: binance.py プロジェクト: alexytlee/freqtrade-1
    def stoploss(self, pair: str, amount: float, stop_price: float, order_types: Dict) -> Dict:
        """
        creates a stoploss limit order.
        this stoploss-limit is binance-specific.
        It may work with a limited number of other exchanges, but this has not been tested yet.
        """
        # Limit price threshold: As limit price should always be below stop-price
        limit_price_pct = order_types.get('stoploss_on_exchange_limit_ratio', 0.99)
        rate = stop_price * limit_price_pct

        ordertype = "stop_loss_limit"

        stop_price = self.price_to_precision(pair, stop_price)

        # Ensure rate is less than stop price
        if stop_price <= rate:
            raise OperationalException(
                'In stoploss limit order, stop price should be more than limit price')

        if self._config['dry_run']:
            dry_order = self.dry_run_order(
                pair, ordertype, "sell", amount, stop_price)
            return dry_order

        try:
            params = self._params.copy()
            params.update({'stopPrice': stop_price})

            amount = self.amount_to_precision(pair, amount)

            rate = self.price_to_precision(pair, rate)

            order = self._api.create_order(symbol=pair, type=ordertype, side='sell',
                                           amount=amount, price=rate, params=params)
            logger.info('stoploss limit order added for %s. '
                        'stop price: %s. limit: %s', pair, stop_price, rate)
            return order
        except ccxt.InsufficientFunds as e:
            raise InsufficientFundsError(
                f'Insufficient funds to create {ordertype} sell order on market {pair}. '
                f'Tried to sell amount {amount} at rate {rate}. '
                f'Message: {e}') from e
        except ccxt.InvalidOrder as e:
            # Errors:
            # `binance Order would trigger immediately.`
            raise InvalidOrderException(
                f'Could not create {ordertype} sell order on market {pair}. '
                f'Tried to sell amount {amount} at rate {rate}. '
                f'Message: {e}') from e
        except ccxt.DDoSProtection as e:
            raise DDosProtection(e) from e
        except (ccxt.NetworkError, ccxt.ExchangeError) as e:
            raise TemporaryError(
                f'Could not place sell order due to {e.__class__.__name__}. Message: {e}') from e
        except ccxt.BaseError as e:
            raise OperationalException(e) from e
コード例 #9
0
ファイル: kraken.py プロジェクト: Uncodedtech/freqtrade
    def stoploss(self, pair: str, amount: float, stop_price: float,
                 order_types: Dict, side: str, leverage: float) -> Dict:
        """
        Creates a stoploss market order.
        Stoploss market orders is the only stoploss type supported by kraken.
        TODO: investigate if this can be combined with generic implementation
              (careful, prices are reversed)
        """
        params = self._params.copy()
        if self.trading_mode == TradingMode.FUTURES:
            params.update({'reduceOnly': True})

        if order_types.get('stoploss', 'market') == 'limit':
            ordertype = "stop-loss-limit"
            limit_price_pct = order_types.get('stoploss_on_exchange_limit_ratio', 0.99)
            if side == "sell":
                limit_rate = stop_price * limit_price_pct
            else:
                limit_rate = stop_price * (2 - limit_price_pct)
            params['price2'] = self.price_to_precision(pair, limit_rate)
        else:
            ordertype = "stop-loss"

        stop_price = self.price_to_precision(pair, stop_price)

        if self._config['dry_run']:
            dry_order = self.create_dry_run_order(
                pair, ordertype, side, amount, stop_price, leverage, stop_loss=True)
            return dry_order

        try:
            amount = self.amount_to_precision(pair, amount)

            order = self._api.create_order(symbol=pair, type=ordertype, side=side,
                                           amount=amount, price=stop_price, params=params)
            self._log_exchange_response('create_stoploss_order', order)
            logger.info('stoploss order added for %s. '
                        'stop price: %s.', pair, stop_price)
            return order
        except ccxt.InsufficientFunds as e:
            raise InsufficientFundsError(
                f'Insufficient funds to create {ordertype} {side} order on market {pair}. '
                f'Tried to create stoploss with amount {amount} at stoploss {stop_price}. '
                f'Message: {e}') from e
        except ccxt.InvalidOrder as e:
            raise InvalidOrderException(
                f'Could not create {ordertype} {side} order on market {pair}. '
                f'Tried to create stoploss with amount {amount} at stoploss {stop_price}. '
                f'Message: {e}') from e
        except ccxt.DDoSProtection as e:
            raise DDosProtection(e) from e
        except (ccxt.NetworkError, ccxt.ExchangeError) as e:
            raise TemporaryError(
                f'Could not place {side} order due to {e.__class__.__name__}. Message: {e}') from e
        except ccxt.BaseError as e:
            raise OperationalException(e) from e
コード例 #10
0
ファイル: kraken.py プロジェクト: s-s-boika/freqtrade
    def stoploss(self, pair: str, amount: float, stop_price: float,
                 order_types: Dict) -> Dict:
        """
        Creates a stoploss market order.
        Stoploss market orders is the only stoploss type supported by kraken.
        """
        params = self._params.copy()

        if order_types.get('stoploss', 'market') == 'limit':
            ordertype = "stop-loss-limit"
            limit_price_pct = order_types.get(
                'stoploss_on_exchange_limit_ratio', 0.99)
            limit_rate = stop_price * limit_price_pct
            params['price2'] = self.price_to_precision(pair, limit_rate)
        else:
            ordertype = "stop-loss"

        stop_price = self.price_to_precision(pair, stop_price)

        if self._config['dry_run']:
            dry_order = self.create_dry_run_order(pair, ordertype, "sell",
                                                  amount, stop_price)
            return dry_order

        try:
            amount = self.amount_to_precision(pair, amount)

            order = self._api.create_order(symbol=pair,
                                           type=ordertype,
                                           side='sell',
                                           amount=amount,
                                           price=stop_price,
                                           params=params)
            self._log_exchange_response('create_stoploss_order', order)
            logger.info('stoploss order added for %s. '
                        'stop price: %s.', pair, stop_price)
            return order
        except ccxt.InsufficientFunds as e:
            raise InsufficientFundsError(
                f'Insufficient funds to create {ordertype} sell order on market {pair}. '
                f'Tried to create stoploss with amount {amount} at stoploss {stop_price}. '
                f'Message: {e}') from e
        except ccxt.InvalidOrder as e:
            raise InvalidOrderException(
                f'Could not create {ordertype} sell order on market {pair}. '
                f'Tried to create stoploss with amount {amount} at stoploss {stop_price}. '
                f'Message: {e}') from e
        except ccxt.DDoSProtection as e:
            raise DDosProtection(e) from e
        except (ccxt.NetworkError, ccxt.ExchangeError) as e:
            raise TemporaryError(
                f'Could not place sell order due to {e.__class__.__name__}. Message: {e}'
            ) from e
        except ccxt.BaseError as e:
            raise OperationalException(e) from e
コード例 #11
0
ファイル: exchange.py プロジェクト: uncaughtgregory/freqtrade
    def get_balance(self, currency: str) -> float:
        if self._config['dry_run']:
            return self._config['dry_run_wallet']

        # ccxt exception is already handled by get_balances
        balances = self.get_balances()
        balance = balances.get(currency)
        if balance is None:
            raise TemporaryError(
                f'Could not get {currency} balance due to malformed exchange response: {balances}')
        return balance['free']
コード例 #12
0
ファイル: exchange.py プロジェクト: uncaughtgregory/freqtrade
 def fetch_ticker(self, pair: str) -> dict:
     try:
         if pair not in self._api.markets or not self._api.markets[pair].get('active'):
             raise DependencyException(f"Pair {pair} not available")
         data = self._api.fetch_ticker(pair)
         return data
     except (ccxt.NetworkError, ccxt.ExchangeError) as e:
         raise TemporaryError(
             f'Could not load ticker due to {e.__class__.__name__}. Message: {e}') from e
     except ccxt.BaseError as e:
         raise OperationalException(e) from e
コード例 #13
0
ファイル: exchange.py プロジェクト: uncaughtgregory/freqtrade
 def get_tickers(self) -> Dict:
     try:
         return self._api.fetch_tickers()
     except ccxt.NotSupported as e:
         raise OperationalException(
             f'Exchange {self._api.name} does not support fetching tickers in batch. '
             f'Message: {e}') from e
     except (ccxt.NetworkError, ccxt.ExchangeError) as e:
         raise TemporaryError(
             f'Could not load tickers due to {e.__class__.__name__}. Message: {e}') from e
     except ccxt.BaseError as e:
         raise OperationalException(e) from e
コード例 #14
0
ファイル: exchange.py プロジェクト: uncaughtgregory/freqtrade
    def get_fee(self, symbol: str, type: str = '', side: str = '', amount: float = 1,
                price: float = 1, taker_or_maker: str = 'maker') -> float:
        try:
            # validate that markets are loaded before trying to get fee
            if self._api.markets is None or len(self._api.markets) == 0:
                self._api.load_markets()

            return self._api.calculate_fee(symbol=symbol, type=type, side=side, amount=amount,
                                           price=price, takerOrMaker=taker_or_maker)['rate']
        except (ccxt.NetworkError, ccxt.ExchangeError) as e:
            raise TemporaryError(
                f'Could not get fee info due to {e.__class__.__name__}. Message: {e}') from e
        except ccxt.BaseError as e:
            raise OperationalException(e) from e
コード例 #15
0
ファイル: exchange.py プロジェクト: uncaughtgregory/freqtrade
    def cancel_order(self, order_id: str, pair: str) -> None:
        if self._config['dry_run']:
            return

        try:
            return self._api.cancel_order(order_id, pair)
        except ccxt.InvalidOrder as e:
            raise InvalidOrderException(
                f'Could not cancel order. Message: {e}') from e
        except (ccxt.NetworkError, ccxt.ExchangeError) as e:
            raise TemporaryError(
                f'Could not cancel order due to {e.__class__.__name__}. Message: {e}') from e
        except ccxt.BaseError as e:
            raise OperationalException(e) from e
コード例 #16
0
 def cancel_stoploss_order(self, order_id: str, pair: str) -> Dict:
     if self._config['dry_run']:
         return {}
     try:
         return self._api.cancel_order(order_id, pair, params={'type': 'stop'})
     except ccxt.InvalidOrder as e:
         raise InvalidOrderException(
             f'Could not cancel order. Message: {e}') from e
     except ccxt.DDoSProtection as e:
         raise DDosProtection(e) from e
     except (ccxt.NetworkError, ccxt.ExchangeError) as e:
         raise TemporaryError(
             f'Could not cancel order due to {e.__class__.__name__}. Message: {e}') from e
     except ccxt.BaseError as e:
         raise OperationalException(e) from e
コード例 #17
0
    async def _async_get_candle_history(
            self,
            pair: str,
            timeframe: str,
            since_ms: Optional[int] = None) -> Tuple[str, str, List]:
        """
        Asynchronously gets candle histories using fetch_ohlcv
        returns tuple: (pair, timeframe, ohlcv_list)
        """
        try:
            # fetch ohlcv asynchronously
            s = '(' + arrow.get(
                since_ms //
                1000).isoformat() + ') ' if since_ms is not None else ''
            logger.debug("Fetching pair %s, interval %s, since %s %s...", pair,
                         timeframe, since_ms, s)

            data = await self._api_async.fetch_ohlcv(pair,
                                                     timeframe=timeframe,
                                                     since=since_ms)

            # Because some exchange sort Tickers ASC and other DESC.
            # Ex: Bittrex returns a list of tickers ASC (oldest first, newest last)
            # when GDAX returns a list of tickers DESC (newest first, oldest last)
            # Only sort if necessary to save computing time
            try:
                if data and data[0][0] > data[-1][0]:
                    data = sorted(data, key=lambda x: x[0])
            except IndexError:
                logger.exception("Error loading %s. Result was %s.", pair,
                                 data)
                return pair, timeframe, []
            logger.debug("Done fetching pair %s, interval %s ...", pair,
                         timeframe)
            return pair, timeframe, data

        except ccxt.NotSupported as e:
            raise OperationalException(
                f'Exchange {self._api.name} does not support fetching historical candlestick data.'
                f'Message: {e}') from e
        except (ccxt.NetworkError, ccxt.ExchangeError) as e:
            raise TemporaryError(
                f'Could not load ticker history for pair {pair} due to '
                f'{e.__class__.__name__}. Message: {e}') from e
        except ccxt.BaseError as e:
            raise OperationalException(
                f'Could not fetch ticker data for pair {pair}. '
                f'Msg: {e}') from e
コード例 #18
0
ファイル: kraken.py プロジェクト: derek-walter/GCT
    def stoploss(self, pair: str, amount: float, stop_price: float,
                 order_types: Dict) -> Dict:
        """
        Creates a stoploss market order.
        Stoploss market orders is the only stoploss type supported by kraken.
        """

        ordertype = "stop-loss"

        stop_price = self.price_to_precision(pair, stop_price)

        if self._config['dry_run']:
            dry_order = self.dry_run_order(pair, ordertype, "sell", amount,
                                           stop_price)
            return dry_order

        try:
            params = self._params.copy()

            amount = self.amount_to_precision(pair, amount)

            order = self._api.create_order(symbol=pair,
                                           type=ordertype,
                                           side='sell',
                                           amount=amount,
                                           price=stop_price,
                                           params=params)
            logger.info('stoploss order added for %s. '
                        'stop price: %s.', pair, stop_price)
            return order
        except ccxt.InsufficientFunds as e:
            raise DependencyException(
                f'Insufficient funds to create {ordertype} sell order on market {pair}.'
                f'Tried to create stoploss with amount {amount} at stoploss {stop_price}. '
                f'Message: {e}') from e
        except ccxt.InvalidOrder as e:
            raise InvalidOrderException(
                f'Could not create {ordertype} sell order on market {pair}. '
                f'Tried to create stoploss with amount {amount} at stoploss {stop_price}. '
                f'Message: {e}') from e
        except (ccxt.NetworkError, ccxt.ExchangeError) as e:
            raise TemporaryError(
                f'Could not place sell order due to {e.__class__.__name__}. Message: {e}'
            ) from e
        except ccxt.BaseError as e:
            raise OperationalException(e) from e
コード例 #19
0
ファイル: ftx.py プロジェクト: Uncodedtech/freqtrade
    def fetch_stoploss_order(self, order_id: str, pair: str) -> Dict:
        if self._config['dry_run']:
            return self.fetch_dry_run_order(order_id)

        try:
            orders = self._api.fetch_orders(pair,
                                            None,
                                            params={'type': 'stop'})

            order = [order for order in orders if order['id'] == order_id]
            self._log_exchange_response('fetch_stoploss_order', order)
            if len(order) == 1:
                if order[0].get('status') == 'closed':
                    # Trigger order was triggered ...
                    real_order_id = order[0].get('info', {}).get('orderId')
                    # OrderId may be None for stoploss-market orders
                    # But contains "average" in these cases.
                    if real_order_id:
                        order1 = self._api.fetch_order(real_order_id, pair)
                        self._log_exchange_response('fetch_stoploss_order1',
                                                    order1)
                        # Fake type to stop - as this was really a stop order.
                        order1['id_stop'] = order1['id']
                        order1['id'] = order_id
                        order1['type'] = 'stop'
                        order1['status_stop'] = 'triggered'
                        return order1

                return order[0]
            else:
                raise InvalidOrderException(
                    f"Could not get stoploss order for id {order_id}")

        except ccxt.InvalidOrder as e:
            raise InvalidOrderException(
                f'Tried to get an invalid order (id: {order_id}). Message: {e}'
            ) from e
        except ccxt.DDoSProtection as e:
            raise DDosProtection(e) from e
        except (ccxt.NetworkError, ccxt.ExchangeError) as e:
            raise TemporaryError(
                f'Could not get order due to {e.__class__.__name__}. Message: {e}'
            ) from e
        except ccxt.BaseError as e:
            raise OperationalException(e) from e
コード例 #20
0
ファイル: exchange.py プロジェクト: uncaughtgregory/freqtrade
    def get_balances(self) -> dict:
        if self._config['dry_run']:
            return {}

        try:
            balances = self._api.fetch_balance()
            # Remove additional info from ccxt results
            balances.pop("info", None)
            balances.pop("free", None)
            balances.pop("total", None)
            balances.pop("used", None)

            return balances
        except (ccxt.NetworkError, ccxt.ExchangeError) as e:
            raise TemporaryError(
                f'Could not get balance due to {e.__class__.__name__}. Message: {e}') from e
        except ccxt.BaseError as e:
            raise OperationalException(e) from e
コード例 #21
0
ファイル: exchange.py プロジェクト: uncaughtgregory/freqtrade
 def get_order(self, order_id: str, pair: str) -> Dict:
     if self._config['dry_run']:
         try:
             order = self._dry_run_open_orders[order_id]
             return order
         except KeyError as e:
             # Gracefully handle errors with dry-run orders.
             raise InvalidOrderException(
                 f'Tried to get an invalid dry-run-order (id: {order_id}). Message: {e}') from e
     try:
         return self._api.fetch_order(order_id, pair)
     except ccxt.InvalidOrder as e:
         raise InvalidOrderException(
             f'Tried to get an invalid order (id: {order_id}). Message: {e}') from e
     except (ccxt.NetworkError, ccxt.ExchangeError) as e:
         raise TemporaryError(
             f'Could not get order due to {e.__class__.__name__}. Message: {e}') from e
     except ccxt.BaseError as e:
         raise OperationalException(e) from e
コード例 #22
0
ファイル: exchange.py プロジェクト: uncaughtgregory/freqtrade
    def get_order_book(self, pair: str, limit: int = 100) -> dict:
        """
        get order book level 2 from exchange

        Notes:
        20180619: bittrex doesnt support limits -.-
        """
        try:

            return self._api.fetch_l2_order_book(pair, limit)
        except ccxt.NotSupported as e:
            raise OperationalException(
                f'Exchange {self._api.name} does not support fetching order book.'
                f'Message: {e}') from e
        except (ccxt.NetworkError, ccxt.ExchangeError) as e:
            raise TemporaryError(
                f'Could not get order book due to {e.__class__.__name__}. Message: {e}') from e
        except ccxt.BaseError as e:
            raise OperationalException(e) from e
コード例 #23
0
 def _lev_prep(self, pair: str, leverage: float, side: str):
     if self.trading_mode != TradingMode.SPOT and self.margin_mode is not None:
         try:
             # TODO-lev: Test me properly (check mgnMode passed)
             self._api.set_leverage(
                 leverage=leverage,
                 symbol=pair,
                 params={
                     "mgnMode": self.margin_mode.value,
                     # "posSide": "net"",
                 })
         except ccxt.DDoSProtection as e:
             raise DDosProtection(e) from e
         except (ccxt.NetworkError, ccxt.ExchangeError) as e:
             raise TemporaryError(
                 f'Could not set leverage due to {e.__class__.__name__}. Message: {e}'
             ) from e
         except ccxt.BaseError as e:
             raise OperationalException(e) from e
コード例 #24
0
ファイル: binance.py プロジェクト: Uncodedtech/freqtrade
 def load_leverage_tiers(self) -> Dict[str, List[Dict]]:
     if self.trading_mode == TradingMode.FUTURES:
         if self._config['dry_run']:
             leverage_tiers_path = (Path(__file__).parent /
                                    'binance_leverage_tiers.json')
             with open(leverage_tiers_path) as json_file:
                 return json.load(json_file)
         else:
             try:
                 return self._api.fetch_leverage_tiers()
             except ccxt.DDoSProtection as e:
                 raise DDosProtection(e) from e
             except (ccxt.NetworkError, ccxt.ExchangeError) as e:
                 raise TemporaryError(
                     f'Could not fetch leverage amounts due to'
                     f'{e.__class__.__name__}. Message: {e}') from e
             except ccxt.BaseError as e:
                 raise OperationalException(e) from e
     else:
         return {}
コード例 #25
0
ファイル: binance.py プロジェクト: Uncodedtech/freqtrade
    def _set_leverage(self,
                      leverage: float,
                      pair: Optional[str] = None,
                      trading_mode: Optional[TradingMode] = None):
        """
        Set's the leverage before making a trade, in order to not
        have the same leverage on every trade
        """
        trading_mode = trading_mode or self.trading_mode

        if self._config['dry_run'] or trading_mode != TradingMode.FUTURES:
            return

        try:
            self._api.set_leverage(symbol=pair, leverage=round(leverage))
        except ccxt.DDoSProtection as e:
            raise DDosProtection(e) from e
        except (ccxt.NetworkError, ccxt.ExchangeError) as e:
            raise TemporaryError(
                f'Could not set leverage due to {e.__class__.__name__}. Message: {e}'
            ) from e
        except ccxt.BaseError as e:
            raise OperationalException(e) from e
コード例 #26
0
 def fetch_ticker(self, pair: str, refresh: Optional[bool] = True) -> dict:
     if refresh or pair not in self._cached_ticker.keys():
         try:
             if pair not in self._api.markets or not self._api.markets[
                     pair].get('active'):
                 raise DependencyException(f"Pair {pair} not available")
             data = self._api.fetch_ticker(pair)
             try:
                 self._cached_ticker[pair] = {
                     'bid': float(data['bid']),
                     'ask': float(data['ask']),
                 }
             except KeyError:
                 logger.debug("Could not cache ticker data for %s", pair)
             return data
         except (ccxt.NetworkError, ccxt.ExchangeError) as e:
             raise TemporaryError(
                 f'Could not load ticker due to {e.__class__.__name__}. Message: {e}'
             ) from e
         except ccxt.BaseError as e:
             raise OperationalException(e) from e
     else:
         logger.info("returning cached ticker-data for %s", pair)
         return self._cached_ticker[pair]