Check if the exchange is supported

This commit is contained in:
Gerald Lonlas 2018-03-30 13:14:35 -07:00
parent 96b2210c0f
commit 052404ffbd
3 changed files with 58 additions and 7 deletions

View File

@ -5,10 +5,11 @@ This module contains the configuration class
import json import json
from argparse import Namespace from argparse import Namespace
from typing import Dict, Any from typing import Dict, Any
from jsonschema import Draft4Validator, validate from jsonschema import Draft4Validator, validate
from jsonschema.exceptions import ValidationError, best_match from jsonschema.exceptions import ValidationError, best_match
import ccxt
from freqtrade import OperationalException
from freqtrade.constants import Constants from freqtrade.constants import Constants
from freqtrade.logger import Logger from freqtrade.logger import Logger
@ -100,6 +101,9 @@ class Configuration(object):
else: else:
self.logger.info('Dry run is disabled. (--dry_run_db ignored)') self.logger.info('Dry run is disabled. (--dry_run_db ignored)')
# Check if the exchange set by the user is supported
self.check_exchange()
return config return config
def _load_backtesting_config(self, config: Dict[str, Any]) -> Dict[str, Any]: def _load_backtesting_config(self, config: Dict[str, Any]) -> Dict[str, Any]:
@ -198,3 +202,23 @@ class Configuration(object):
self.config = self.load_config() self.config = self.load_config()
return self.config return self.config
def check_exchange(self) -> bool:
"""
Check if the exchange name in the config file is supported by Freqtrade
:return: True or raised an exception if the exchange if not supported
"""
exchange = self.config.get('exchange', {}).get('name').lower()
if exchange not in ccxt.exchanges:
exception_msg = 'Exchange "{}" not supported.\n' \
'The following exchanges are supported: {}'\
.format(exchange, ', '.join(ccxt.exchanges))
self.logger.critical(exception_msg)
raise OperationalException(
exception_msg
)
self.logger.debug('Exchange "%s" supported', exchange)
return True

View File

@ -74,16 +74,14 @@ def init(config: dict) -> None:
# Find matching class for the given exchange name # Find matching class for the given exchange name
name = exchange_config['name'] name = exchange_config['name']
# TODO add check for a list of supported exchanges # Init the exchange if the exchange name passed is supported
try: try:
# exchange_class = Exchanges[name.upper()].value
_API = getattr(ccxt, name.lower())({ _API = getattr(ccxt, name.lower())({
'apiKey': exchange_config.get('key'), 'apiKey': exchange_config.get('key'),
'secret': exchange_config.get('secret'), 'secret': exchange_config.get('secret'),
}) })
logger.info('Using Exchange %s', name.capitalize()) logger.info('Using Exchange %s', name.capitalize())
except KeyError: except (KeyError, AttributeError):
raise OperationalException('Exchange {} is not supported'.format(name)) raise OperationalException('Exchange {} is not supported'.format(name))
# we need load api markets # we need load api markets

View File

@ -13,6 +13,7 @@ from jsonschema import ValidationError
from freqtrade.arguments import Arguments from freqtrade.arguments import Arguments
from freqtrade.configuration import Configuration from freqtrade.configuration import Configuration
from freqtrade.tests.conftest import log_has from freqtrade.tests.conftest import log_has
from freqtrade import OperationalException
def test_configuration_object() -> None: def test_configuration_object() -> None:
@ -28,7 +29,7 @@ def test_configuration_object() -> None:
assert hasattr(Configuration, 'get_config') assert hasattr(Configuration, 'get_config')
def test_load_config_invalid_pair(default_conf, mocker) -> None: def test_load_config_invalid_pair(default_conf) -> None:
""" """
Test the configuration validator with an invalid PAIR format Test the configuration validator with an invalid PAIR format
""" """
@ -40,7 +41,7 @@ def test_load_config_invalid_pair(default_conf, mocker) -> None:
configuration._validate_config(conf) configuration._validate_config(conf)
def test_load_config_missing_attributes(default_conf, mocker) -> None: def test_load_config_missing_attributes(default_conf) -> None:
""" """
Test the configuration validator with a missing attribute Test the configuration validator with a missing attribute
""" """
@ -314,3 +315,31 @@ def test_hyperopt_with_arguments(mocker, default_conf, caplog) -> None:
assert 'spaces' in config assert 'spaces' in config
assert config['spaces'] == ['all'] assert config['spaces'] == ['all']
assert log_has('Parameter -s/--spaces detected: [\'all\']', caplog.record_tuples) assert log_has('Parameter -s/--spaces detected: [\'all\']', caplog.record_tuples)
def test_check_exchange(default_conf) -> None:
"""
Test the configuration validator with a missing attribute
"""
conf = deepcopy(default_conf)
configuration = Configuration([])
# Test a valid exchange
conf.get('exchange').update({'name': 'BITTREX'})
configuration.config = conf
assert configuration.check_exchange()
# Test a valid exchange
conf.get('exchange').update({'name': 'binance'})
configuration.config = conf
assert configuration.check_exchange()
# Test a invalid exchange
conf.get('exchange').update({'name': 'unknown_exchange'})
configuration.config = conf
with pytest.raises(
OperationalException,
match=r'.*Exchange "unknown_exchange" not supported.*'
):
configuration.check_exchange()