Merge pull request #2055 from freqtrade/get_order_exception
Get order exception
This commit is contained in:
commit
fef8fe8525
@ -174,10 +174,10 @@ class Exchange(object):
|
|||||||
try:
|
try:
|
||||||
|
|
||||||
api = getattr(ccxt_module, name.lower())(ex_config)
|
api = getattr(ccxt_module, name.lower())(ex_config)
|
||||||
except (KeyError, AttributeError):
|
except (KeyError, AttributeError) as e:
|
||||||
raise OperationalException(f'Exchange {name} is not supported')
|
raise OperationalException(f'Exchange {name} is not supported') from e
|
||||||
except ccxt.BaseError as e:
|
except ccxt.BaseError as e:
|
||||||
raise OperationalException(f"Initialization of ccxt failed. Reason: {e}")
|
raise OperationalException(f"Initialization of ccxt failed. Reason: {e}") from e
|
||||||
|
|
||||||
self.set_sandbox(api, exchange_config, name)
|
self.set_sandbox(api, exchange_config, name)
|
||||||
|
|
||||||
@ -398,17 +398,17 @@ class Exchange(object):
|
|||||||
raise DependencyException(
|
raise DependencyException(
|
||||||
f'Insufficient funds to create {ordertype} {side} order on market {pair}.'
|
f'Insufficient funds to create {ordertype} {side} order on market {pair}.'
|
||||||
f'Tried to {side} amount {amount} at rate {rate} (total {rate * amount}).'
|
f'Tried to {side} amount {amount} at rate {rate} (total {rate * amount}).'
|
||||||
f'Message: {e}')
|
f'Message: {e}') from e
|
||||||
except ccxt.InvalidOrder as e:
|
except ccxt.InvalidOrder as e:
|
||||||
raise DependencyException(
|
raise DependencyException(
|
||||||
f'Could not create {ordertype} {side} order on market {pair}.'
|
f'Could not create {ordertype} {side} order on market {pair}.'
|
||||||
f'Tried to {side} amount {amount} at rate {rate} (total {rate * amount}).'
|
f'Tried to {side} amount {amount} at rate {rate} (total {rate * amount}).'
|
||||||
f'Message: {e}')
|
f'Message: {e}') from e
|
||||||
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
|
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
|
||||||
raise TemporaryError(
|
raise TemporaryError(
|
||||||
f'Could not place {side} order due to {e.__class__.__name__}. Message: {e}')
|
f'Could not place {side} order due to {e.__class__.__name__}. Message: {e}') from e
|
||||||
except ccxt.BaseError as e:
|
except ccxt.BaseError as e:
|
||||||
raise OperationalException(e)
|
raise OperationalException(e) from e
|
||||||
|
|
||||||
def buy(self, pair: str, ordertype: str, amount: float,
|
def buy(self, pair: str, ordertype: str, amount: float,
|
||||||
rate: float, time_in_force) -> Dict:
|
rate: float, time_in_force) -> Dict:
|
||||||
@ -493,9 +493,9 @@ class Exchange(object):
|
|||||||
return balances
|
return balances
|
||||||
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
|
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
|
||||||
raise TemporaryError(
|
raise TemporaryError(
|
||||||
f'Could not get balance due to {e.__class__.__name__}. Message: {e}')
|
f'Could not get balance due to {e.__class__.__name__}. Message: {e}') from e
|
||||||
except ccxt.BaseError as e:
|
except ccxt.BaseError as e:
|
||||||
raise OperationalException(e)
|
raise OperationalException(e) from e
|
||||||
|
|
||||||
@retrier
|
@retrier
|
||||||
def get_tickers(self) -> Dict:
|
def get_tickers(self) -> Dict:
|
||||||
@ -504,12 +504,12 @@ class Exchange(object):
|
|||||||
except ccxt.NotSupported as e:
|
except ccxt.NotSupported as e:
|
||||||
raise OperationalException(
|
raise OperationalException(
|
||||||
f'Exchange {self._api.name} does not support fetching tickers in batch.'
|
f'Exchange {self._api.name} does not support fetching tickers in batch.'
|
||||||
f'Message: {e}')
|
f'Message: {e}') from e
|
||||||
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
|
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
|
||||||
raise TemporaryError(
|
raise TemporaryError(
|
||||||
f'Could not load tickers due to {e.__class__.__name__}. Message: {e}')
|
f'Could not load tickers due to {e.__class__.__name__}. Message: {e}') from e
|
||||||
except ccxt.BaseError as e:
|
except ccxt.BaseError as e:
|
||||||
raise OperationalException(e)
|
raise OperationalException(e) from e
|
||||||
|
|
||||||
@retrier
|
@retrier
|
||||||
def get_ticker(self, pair: str, refresh: Optional[bool] = True) -> dict:
|
def get_ticker(self, pair: str, refresh: Optional[bool] = True) -> dict:
|
||||||
@ -528,9 +528,9 @@ class Exchange(object):
|
|||||||
return data
|
return data
|
||||||
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
|
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
|
||||||
raise TemporaryError(
|
raise TemporaryError(
|
||||||
f'Could not load ticker due to {e.__class__.__name__}. Message: {e}')
|
f'Could not load ticker due to {e.__class__.__name__}. Message: {e}') from e
|
||||||
except ccxt.BaseError as e:
|
except ccxt.BaseError as e:
|
||||||
raise OperationalException(e)
|
raise OperationalException(e) from e
|
||||||
else:
|
else:
|
||||||
logger.info("returning cached ticker-data for %s", pair)
|
logger.info("returning cached ticker-data for %s", pair)
|
||||||
return self._cached_ticker[pair]
|
return self._cached_ticker[pair]
|
||||||
@ -651,12 +651,12 @@ class Exchange(object):
|
|||||||
except ccxt.NotSupported as e:
|
except ccxt.NotSupported as e:
|
||||||
raise OperationalException(
|
raise OperationalException(
|
||||||
f'Exchange {self._api.name} does not support fetching historical candlestick data.'
|
f'Exchange {self._api.name} does not support fetching historical candlestick data.'
|
||||||
f'Message: {e}')
|
f'Message: {e}') from e
|
||||||
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
|
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
|
||||||
raise TemporaryError(
|
raise TemporaryError(f'Could not load ticker history due to {e.__class__.__name__}. '
|
||||||
f'Could not load ticker history due to {e.__class__.__name__}. Message: {e}')
|
f'Message: {e}') from e
|
||||||
except ccxt.BaseError as e:
|
except ccxt.BaseError as e:
|
||||||
raise OperationalException(f'Could not fetch ticker data. Msg: {e}')
|
raise OperationalException(f'Could not fetch ticker data. Msg: {e}') from e
|
||||||
|
|
||||||
@retrier
|
@retrier
|
||||||
def cancel_order(self, order_id: str, pair: str) -> None:
|
def cancel_order(self, order_id: str, pair: str) -> None:
|
||||||
@ -667,12 +667,12 @@ class Exchange(object):
|
|||||||
return self._api.cancel_order(order_id, pair)
|
return self._api.cancel_order(order_id, pair)
|
||||||
except ccxt.InvalidOrder as e:
|
except ccxt.InvalidOrder as e:
|
||||||
raise InvalidOrderException(
|
raise InvalidOrderException(
|
||||||
f'Could not cancel order. Message: {e}')
|
f'Could not cancel order. Message: {e}') from e
|
||||||
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
|
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
|
||||||
raise TemporaryError(
|
raise TemporaryError(
|
||||||
f'Could not cancel order due to {e.__class__.__name__}. Message: {e}')
|
f'Could not cancel order due to {e.__class__.__name__}. Message: {e}') from e
|
||||||
except ccxt.BaseError as e:
|
except ccxt.BaseError as e:
|
||||||
raise OperationalException(e)
|
raise OperationalException(e) from e
|
||||||
|
|
||||||
@retrier
|
@retrier
|
||||||
def get_order(self, order_id: str, pair: str) -> Dict:
|
def get_order(self, order_id: str, pair: str) -> Dict:
|
||||||
@ -683,12 +683,12 @@ class Exchange(object):
|
|||||||
return self._api.fetch_order(order_id, pair)
|
return self._api.fetch_order(order_id, pair)
|
||||||
except ccxt.InvalidOrder as e:
|
except ccxt.InvalidOrder as e:
|
||||||
raise InvalidOrderException(
|
raise InvalidOrderException(
|
||||||
f'Tried to get an invalid order (id: {order_id}). Message: {e}')
|
f'Tried to get an invalid order (id: {order_id}). Message: {e}') from e
|
||||||
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
|
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
|
||||||
raise TemporaryError(
|
raise TemporaryError(
|
||||||
f'Could not get order due to {e.__class__.__name__}. Message: {e}')
|
f'Could not get order due to {e.__class__.__name__}. Message: {e}') from e
|
||||||
except ccxt.BaseError as e:
|
except ccxt.BaseError as e:
|
||||||
raise OperationalException(e)
|
raise OperationalException(e) from e
|
||||||
|
|
||||||
@retrier
|
@retrier
|
||||||
def get_order_book(self, pair: str, limit: int = 100) -> dict:
|
def get_order_book(self, pair: str, limit: int = 100) -> dict:
|
||||||
@ -704,12 +704,12 @@ class Exchange(object):
|
|||||||
except ccxt.NotSupported as e:
|
except ccxt.NotSupported as e:
|
||||||
raise OperationalException(
|
raise OperationalException(
|
||||||
f'Exchange {self._api.name} does not support fetching order book.'
|
f'Exchange {self._api.name} does not support fetching order book.'
|
||||||
f'Message: {e}')
|
f'Message: {e}') from e
|
||||||
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
|
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
|
||||||
raise TemporaryError(
|
raise TemporaryError(
|
||||||
f'Could not get order book due to {e.__class__.__name__}. Message: {e}')
|
f'Could not get order book due to {e.__class__.__name__}. Message: {e}') from e
|
||||||
except ccxt.BaseError as e:
|
except ccxt.BaseError as e:
|
||||||
raise OperationalException(e)
|
raise OperationalException(e) from e
|
||||||
|
|
||||||
@retrier
|
@retrier
|
||||||
def get_trades_for_order(self, order_id: str, pair: str, since: datetime) -> List:
|
def get_trades_for_order(self, order_id: str, pair: str, since: datetime) -> List:
|
||||||
@ -726,9 +726,9 @@ class Exchange(object):
|
|||||||
|
|
||||||
except ccxt.NetworkError as e:
|
except ccxt.NetworkError as e:
|
||||||
raise TemporaryError(
|
raise TemporaryError(
|
||||||
f'Could not get trades due to networking error. Message: {e}')
|
f'Could not get trades due to networking error. Message: {e}') from e
|
||||||
except ccxt.BaseError as e:
|
except ccxt.BaseError as e:
|
||||||
raise OperationalException(e)
|
raise OperationalException(e) from e
|
||||||
|
|
||||||
@retrier
|
@retrier
|
||||||
def get_fee(self, symbol='ETH/BTC', type='', side='', amount=1,
|
def get_fee(self, symbol='ETH/BTC', type='', side='', amount=1,
|
||||||
@ -742,9 +742,9 @@ class Exchange(object):
|
|||||||
price=price, takerOrMaker=taker_or_maker)['rate']
|
price=price, takerOrMaker=taker_or_maker)['rate']
|
||||||
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
|
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
|
||||||
raise TemporaryError(
|
raise TemporaryError(
|
||||||
f'Could not get fee info due to {e.__class__.__name__}. Message: {e}')
|
f'Could not get fee info due to {e.__class__.__name__}. Message: {e}') from e
|
||||||
except ccxt.BaseError as e:
|
except ccxt.BaseError as e:
|
||||||
raise OperationalException(e)
|
raise OperationalException(e) from e
|
||||||
|
|
||||||
|
|
||||||
def is_exchange_bad(exchange: str) -> bool:
|
def is_exchange_bad(exchange: str) -> bool:
|
||||||
|
@ -524,7 +524,11 @@ class FreqtradeBot(object):
|
|||||||
if trade.open_order_id:
|
if trade.open_order_id:
|
||||||
# Update trade with order values
|
# Update trade with order values
|
||||||
logger.info('Found open order for %s', trade)
|
logger.info('Found open order for %s', trade)
|
||||||
|
try:
|
||||||
order = action_order or self.exchange.get_order(trade.open_order_id, trade.pair)
|
order = action_order or self.exchange.get_order(trade.open_order_id, trade.pair)
|
||||||
|
except InvalidOrderException as exception:
|
||||||
|
logger.warning('Unable to fetch order %s: %s', trade.open_order_id, exception)
|
||||||
|
return
|
||||||
# Try update amount (binance-fix)
|
# Try update amount (binance-fix)
|
||||||
try:
|
try:
|
||||||
new_amount = self.get_real_amount(trade, order)
|
new_amount = self.get_real_amount(trade, order)
|
||||||
@ -749,7 +753,7 @@ class FreqtradeBot(object):
|
|||||||
if not trade.open_order_id:
|
if not trade.open_order_id:
|
||||||
continue
|
continue
|
||||||
order = self.exchange.get_order(trade.open_order_id, trade.pair)
|
order = self.exchange.get_order(trade.open_order_id, trade.pair)
|
||||||
except (RequestException, DependencyException):
|
except (RequestException, DependencyException, InvalidOrderException):
|
||||||
logger.info(
|
logger.info(
|
||||||
'Cannot query order for %s due to %s',
|
'Cannot query order for %s due to %s',
|
||||||
trade,
|
trade,
|
||||||
|
@ -1460,6 +1460,22 @@ def test_update_trade_state_exception(mocker, default_conf,
|
|||||||
assert log_has('Could not update trade amount: ', caplog.record_tuples)
|
assert log_has('Could not update trade amount: ', caplog.record_tuples)
|
||||||
|
|
||||||
|
|
||||||
|
def test_update_trade_state_orderexception(mocker, default_conf, caplog) -> None:
|
||||||
|
freqtrade = get_patched_freqtradebot(mocker, default_conf)
|
||||||
|
mocker.patch('freqtrade.exchange.Exchange.get_order',
|
||||||
|
MagicMock(side_effect=InvalidOrderException))
|
||||||
|
|
||||||
|
trade = MagicMock()
|
||||||
|
trade.open_order_id = '123'
|
||||||
|
trade.open_fee = 0.001
|
||||||
|
|
||||||
|
# Test raise of OperationalException exception
|
||||||
|
grm_mock = mocker.patch("freqtrade.freqtradebot.FreqtradeBot.get_real_amount", MagicMock())
|
||||||
|
freqtrade.update_trade_state(trade)
|
||||||
|
assert grm_mock.call_count == 0
|
||||||
|
assert log_has(f'Unable to fetch order {trade.open_order_id}: ', caplog.record_tuples)
|
||||||
|
|
||||||
|
|
||||||
def test_update_trade_state_sell(default_conf, trades_for_order, limit_sell_order, mocker):
|
def test_update_trade_state_sell(default_conf, trades_for_order, limit_sell_order, mocker):
|
||||||
mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=trades_for_order)
|
mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=trades_for_order)
|
||||||
# get_order should not be called!!
|
# get_order should not be called!!
|
||||||
|
Loading…
Reference in New Issue
Block a user