From 0c7d14fe50694edd916c550b1c1213990146f648 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 30 Jun 2019 20:30:31 +0200 Subject: [PATCH 1/6] Check if timeframes is available and fail gracefully otherwise --- freqtrade/exchange/exchange.py | 7 +++++++ freqtrade/resolvers/exchange_resolver.py | 1 + 2 files changed, 8 insertions(+) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index b649a7b65..cefee999c 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -269,6 +269,13 @@ class Exchange(object): """ Checks if ticker interval from config is a supported timeframe on the exchange """ + logger.warning("validate_timerames") + if not hasattr(self._api, "timeframes"): + # If timeframes is missing, the exchange probably has no fetchOHLCV method. + # Therefore we also show that. + raise OperationalException( + f"This exchange ({self.name}) does not have a `timeframes` attribute and " + f"is therefore not supported. fetchOHLCV: {self.exchange_has('fetchOHLCV')}") timeframes = self._api.timeframes if timeframe not in timeframes: raise OperationalException( diff --git a/freqtrade/resolvers/exchange_resolver.py b/freqtrade/resolvers/exchange_resolver.py index 25a86dd0e..089f6306f 100644 --- a/freqtrade/resolvers/exchange_resolver.py +++ b/freqtrade/resolvers/exchange_resolver.py @@ -28,6 +28,7 @@ class ExchangeResolver(IResolver): except ImportError: logger.info( f"No {exchange_name} specific subclass found. Using the generic class instead.") + if not hasattr(self, "exchange"): self.exchange = Exchange(config) def _load_exchange( From 01904d3c1e47321140304faecb768a3709bc751c Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 30 Jun 2019 20:30:47 +0200 Subject: [PATCH 2/6] Test not having timeframe available on exchange object --- freqtrade/tests/exchange/test_exchange.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/freqtrade/tests/exchange/test_exchange.py b/freqtrade/tests/exchange/test_exchange.py index 48a8538a9..b74882ad4 100644 --- a/freqtrade/tests/exchange/test_exchange.py +++ b/freqtrade/tests/exchange/test_exchange.py @@ -396,6 +396,23 @@ def test_validate_timeframes_failed(default_conf, mocker): Exchange(default_conf) +def test_validate_timeframes_emulated_ohlcv(default_conf, mocker): + default_conf["ticker_interval"] = "3m" + api_mock = MagicMock() + id_mock = PropertyMock(return_value='test_exchange') + type(api_mock).id = id_mock + + # delete timeframes so magicmock does not autocreate it + del api_mock.timeframes + + mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock)) + mocker.patch('freqtrade.exchange.Exchange._load_markets', MagicMock(return_value={})) + mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock()) + with pytest.raises(OperationalException, + match=r'This exchange (.*) does not have a `timeframes` attribute and*'): + Exchange(default_conf) + + def test_validate_timeframes_not_in_config(default_conf, mocker): del default_conf["ticker_interval"] api_mock = MagicMock() From 0d601fd1113615d1155986ffe65ba9b49067b68c Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 1 Jul 2019 06:18:28 +0200 Subject: [PATCH 3/6] Remove logger message --- freqtrade/exchange/exchange.py | 1 - 1 file changed, 1 deletion(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index cefee999c..2350c752f 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -269,7 +269,6 @@ class Exchange(object): """ Checks if ticker interval from config is a supported timeframe on the exchange """ - logger.warning("validate_timerames") if not hasattr(self._api, "timeframes"): # If timeframes is missing, the exchange probably has no fetchOHLCV method. # Therefore we also show that. From 06ad04e5fa8f48adac1d1ae12caf5689464569f3 Mon Sep 17 00:00:00 2001 From: pyup-bot Date: Mon, 1 Jul 2019 18:28:30 +0000 Subject: [PATCH 4/6] Update ccxt from 1.18.805 to 1.18.860 --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index 6913217ff..409c979b5 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -1,6 +1,6 @@ # requirements without requirements installable via conda # mainly used for Raspberry pi installs -ccxt==1.18.805 +ccxt==1.18.860 SQLAlchemy==1.3.5 python-telegram-bot==11.1.0 arrow==0.14.2 From 1e4f459a2678e377e418480b5415d6c59c87b13b Mon Sep 17 00:00:00 2001 From: pyup-bot Date: Mon, 1 Jul 2019 18:28:31 +0000 Subject: [PATCH 5/6] Update pytest from 4.6.3 to 5.0.0 --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 1232d4dd4..99697340d 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -5,7 +5,7 @@ flake8==3.7.7 flake8-type-annotations==0.1.0 flake8-tidy-imports==2.0.0 -pytest==4.6.3 +pytest==5.0.0 pytest-mock==1.10.4 pytest-asyncio==0.10.0 pytest-cov==2.7.1 From c91add203d451b93d384af919f99d5d4edc408e8 Mon Sep 17 00:00:00 2001 From: pyup-bot Date: Mon, 1 Jul 2019 18:28:32 +0000 Subject: [PATCH 6/6] Update mypy from 0.710 to 0.711 --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 99697340d..c360bc85e 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -10,4 +10,4 @@ pytest-mock==1.10.4 pytest-asyncio==0.10.0 pytest-cov==2.7.1 coveralls==1.8.1 -mypy==0.710 +mypy==0.711