Add exception handlers for orderbook logic
This commit is contained in:
		| @@ -18,7 +18,7 @@ from freqtrade.configuration import validate_config_consistency | ||||
| from freqtrade.data.converter import order_book_to_dataframe | ||||
| from freqtrade.data.dataprovider import DataProvider | ||||
| from freqtrade.edge import Edge | ||||
| from freqtrade.exceptions import DependencyException, InvalidOrderException | ||||
| from freqtrade.exceptions import DependencyException, InvalidOrderException, PricingException | ||||
| from freqtrade.exchange import timeframe_to_minutes, timeframe_to_next_date | ||||
| from freqtrade.misc import safe_value_fallback | ||||
| from freqtrade.pairlist.pairlistmanager import PairListManager | ||||
| @@ -263,9 +263,16 @@ class FreqtradeBot: | ||||
|             order_book = self.exchange.get_order_book(pair, order_book_top) | ||||
|             logger.debug('order_book %s', order_book) | ||||
|             # top 1 = index 0 | ||||
|             order_book_rate = order_book[f"{bid_strategy['price_side']}s"][order_book_top - 1][0] | ||||
|             logger.info(f'...top {order_book_top} order book buy rate {order_book_rate:.8f}') | ||||
|             used_rate = order_book_rate | ||||
|             try: | ||||
|                 rate_from_l2 = order_book[f"{bid_strategy['price_side']}s"][order_book_top - 1][0] | ||||
|             except (IndexError, KeyError) as e: | ||||
|                 logger.warning( | ||||
|                     "Buy Price from orderbook could not be determined." | ||||
|                     f"Orderbook: {order_book}" | ||||
|                  ) | ||||
|                 raise PricingException from e | ||||
|             logger.info(f'...top {order_book_top} order book buy rate {rate_from_l2:.8f}') | ||||
|             used_rate = rate_from_l2 | ||||
|         else: | ||||
|             logger.info(f"Using Last {bid_strategy['price_side'].capitalize()} / Last Price") | ||||
|             ticker = self.exchange.fetch_ticker(pair) | ||||
| @@ -662,8 +669,13 @@ class FreqtradeBot: | ||||
|             logger.info( | ||||
|                 f"Getting price from order book {ask_strategy['price_side'].capitalize()} side." | ||||
|             ) | ||||
|             try: | ||||
|                 rate = next(self._order_book_gen(pair, f"{ask_strategy['price_side']}s")) | ||||
|  | ||||
|             except (IndexError, KeyError) as e: | ||||
|                 logger.warning( | ||||
|                     f"Sell Price at location from orderbook could not be determined." | ||||
|                 ) | ||||
|                 raise PricingException from e | ||||
|         else: | ||||
|             rate = self.exchange.fetch_ticker(pair)[ask_strategy['price_side']] | ||||
|         self._sell_rate_cache[pair] = rate | ||||
| @@ -690,16 +702,23 @@ class FreqtradeBot: | ||||
|                 self.dataprovider.ohlcv(trade.pair, self.strategy.ticker_interval)) | ||||
|  | ||||
|         if config_ask_strategy.get('use_order_book', False): | ||||
|             logger.debug(f'Using order book for selling {trade.pair}...') | ||||
|             # logger.debug('Order book %s',orderBook) | ||||
|             order_book_min = config_ask_strategy.get('order_book_min', 1) | ||||
|             order_book_max = config_ask_strategy.get('order_book_max', 1) | ||||
|             logger.info(f'Using order book between {order_book_min} and {order_book_max} ' | ||||
|                         f'for selling {trade.pair}...') | ||||
|  | ||||
|             order_book = self._order_book_gen(trade.pair, f"{config_ask_strategy['price_side']}s", | ||||
|                                               order_book_min=order_book_min, | ||||
|                                               order_book_max=order_book_max) | ||||
|             for i in range(order_book_min, order_book_max + 1): | ||||
|                 try: | ||||
|                     sell_rate = next(order_book) | ||||
|                 except (IndexError, KeyError) as e: | ||||
|                     logger.warning( | ||||
|                         f"Sell Price at location {i} from orderbook could not be determined." | ||||
|                     ) | ||||
|                     raise PricingException from e | ||||
|                 logger.debug(f"  order book {config_ask_strategy['price_side']} top {i}: " | ||||
|                              f"{sell_rate:0.8f}") | ||||
|  | ||||
|   | ||||
| @@ -11,18 +11,21 @@ import arrow | ||||
| import pytest | ||||
| import requests | ||||
|  | ||||
| from freqtrade.constants import MATH_CLOSE_PREC, UNLIMITED_STAKE_AMOUNT, CANCEL_REASON | ||||
| from freqtrade.constants import (CANCEL_REASON, MATH_CLOSE_PREC, | ||||
|                                  UNLIMITED_STAKE_AMOUNT) | ||||
| from freqtrade.exceptions import (DependencyException, InvalidOrderException, | ||||
|                                   OperationalException, TemporaryError) | ||||
|                                   OperationalException, PricingException, | ||||
|                                   TemporaryError) | ||||
| from freqtrade.freqtradebot import FreqtradeBot | ||||
| from freqtrade.persistence import Trade | ||||
| from freqtrade.rpc import RPCMessageType | ||||
| from freqtrade.state import RunMode, State | ||||
| from freqtrade.strategy.interface import SellCheckTuple, SellType | ||||
| from freqtrade.worker import Worker | ||||
| from tests.conftest import (get_patched_freqtradebot, get_patched_worker, | ||||
|                             log_has, log_has_re, patch_edge, patch_exchange, | ||||
|                             patch_get_signal, patch_wallet, patch_whitelist, create_mock_trades) | ||||
| from tests.conftest import (create_mock_trades, get_patched_freqtradebot, | ||||
|                             get_patched_worker, log_has, log_has_re, | ||||
|                             patch_edge, patch_exchange, patch_get_signal, | ||||
|                             patch_wallet, patch_whitelist) | ||||
|  | ||||
|  | ||||
| def patch_RPCManager(mocker) -> MagicMock: | ||||
| @@ -3772,29 +3775,26 @@ def test_order_book_bid_strategy1(mocker, default_conf, order_book_l2) -> None: | ||||
|     assert ticker_mock.call_count == 0 | ||||
|  | ||||
|  | ||||
| def test_order_book_bid_strategy2(mocker, default_conf, order_book_l2) -> None: | ||||
|     """ | ||||
|     test if function get_buy_rate will return the ask rate (since its value is lower) | ||||
|     instead of the order book rate (even if enabled) | ||||
|     """ | ||||
| def test_order_book_bid_strategy_exception(mocker, default_conf, caplog) -> None: | ||||
|     patch_exchange(mocker) | ||||
|     ticker_mock = MagicMock(return_value={'ask': 0.042, 'last': 0.046}) | ||||
|     mocker.patch.multiple( | ||||
|         'freqtrade.exchange.Exchange', | ||||
|         get_order_book=order_book_l2, | ||||
|         get_order_book=MagicMock(return_value={'bids': [[]], 'asks': [[]]}), | ||||
|         fetch_ticker=ticker_mock, | ||||
|  | ||||
|     ) | ||||
|     default_conf['exchange']['name'] = 'binance' | ||||
|     default_conf['bid_strategy']['use_order_book'] = True | ||||
|     default_conf['bid_strategy']['order_book_top'] = 2 | ||||
|     default_conf['bid_strategy']['order_book_top'] = 1 | ||||
|     default_conf['bid_strategy']['ask_last_balance'] = 0 | ||||
|     default_conf['telegram']['enabled'] = False | ||||
|  | ||||
|     freqtrade = FreqtradeBot(default_conf) | ||||
|     # orderbook shall be used even if tickers would be lower. | ||||
|     assert freqtrade.get_buy_rate('ETH/BTC', True) != 0.042 | ||||
|     assert ticker_mock.call_count == 0 | ||||
|     with pytest.raises(PricingException): | ||||
|         freqtrade.get_buy_rate('ETH/BTC', refresh=True) | ||||
|     assert log_has_re(r'Buy Price from orderbook could not be determined.', caplog) | ||||
|  | ||||
|  | ||||
| def test_check_depth_of_market_buy(default_conf, mocker, order_book_l2) -> None: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user