Implement validation for valid stake currency

This commit is contained in:
Matthias 2020-01-11 11:53:44 +01:00
parent 235a10ab86
commit 13274964a9
3 changed files with 25 additions and 3 deletions

View File

@ -61,7 +61,7 @@ CONF_SCHEMA = {
'properties': { 'properties': {
'max_open_trades': {'type': ['integer', 'number'], 'minimum': -1}, 'max_open_trades': {'type': ['integer', 'number'], 'minimum': -1},
'ticker_interval': {'type': 'string'}, 'ticker_interval': {'type': 'string'},
'stake_currency': {'type': 'string', 'enum': ['BTC', 'XBT', 'ETH', 'USDT', 'EUR', 'USD']}, 'stake_currency': {'type': 'string'},
'stake_amount': { 'stake_amount': {
'type': ['number', 'string'], 'type': ['number', 'string'],
'minimum': 0.0001, 'minimum': 0.0001,

View File

@ -116,6 +116,7 @@ class Exchange:
self._load_markets() self._load_markets()
# Check if all pairs are available # Check if all pairs are available
self.validate_stakecurrency(config['stake_currency'])
self.validate_pairs(config['exchange']['pair_whitelist']) self.validate_pairs(config['exchange']['pair_whitelist'])
self.validate_ordertypes(config.get('order_types', {})) self.validate_ordertypes(config.get('order_types', {}))
self.validate_order_time_in_force(config.get('order_time_in_force', {})) self.validate_order_time_in_force(config.get('order_time_in_force', {}))
@ -210,6 +211,14 @@ class Exchange:
markets = {k: v for k, v in markets.items() if market_is_active(v)} markets = {k: v for k, v in markets.items() if market_is_active(v)}
return markets return markets
def get_quote_currencies(self) -> List[str]:
"""
Return a list of supported quote currencies
"""
markets = self.markets
currencies = set([x['quote'] for _, x in markets.items()])
return list(currencies)
def klines(self, pair_interval: Tuple[str, str], copy=True) -> DataFrame: def klines(self, pair_interval: Tuple[str, str], copy=True) -> DataFrame:
if pair_interval in self._klines: if pair_interval in self._klines:
return self._klines[pair_interval].copy() if copy else self._klines[pair_interval] return self._klines[pair_interval].copy() if copy else self._klines[pair_interval]
@ -259,11 +268,23 @@ class Exchange:
except ccxt.BaseError: except ccxt.BaseError:
logger.exception("Could not reload markets.") logger.exception("Could not reload markets.")
def validate_stakecurrency(self, stake_currency) -> None:
"""
Checks stake-currency against available currencies on the exchange.
:param stake_currency: Stake-currency to validate
:raise: OperationalException if stake-currency is not available.
"""
quote_currencies = self.get_quote_currencies()
if stake_currency not in quote_currencies:
raise OperationalException(
f"{stake_currency} is not available as stake on {self.name}."
f"Available currencies are: {','.join(quote_currencies)}")
def validate_pairs(self, pairs: List[str]) -> None: def validate_pairs(self, pairs: List[str]) -> None:
""" """
Checks if all given pairs are tradable on the current exchange. Checks if all given pairs are tradable on the current exchange.
Raises OperationalException if one pair is not available.
:param pairs: list of pairs :param pairs: list of pairs
:raise: OperationalException if one pair is not available
:return: None :return: None
""" """
@ -319,7 +340,7 @@ class Exchange:
raise OperationalException( raise OperationalException(
f"Invalid ticker interval '{timeframe}'. This exchange supports: {self.timeframes}") f"Invalid ticker interval '{timeframe}'. This exchange supports: {self.timeframes}")
if timeframe_to_minutes(timeframe) < 1: if timeframe and timeframe_to_minutes(timeframe) < 1:
raise OperationalException( raise OperationalException(
f"Timeframes < 1m are currently not supported by Freqtrade.") f"Timeframes < 1m are currently not supported by Freqtrade.")

View File

@ -60,6 +60,7 @@ def patch_exchange(mocker, api_mock=None, id='bittrex', mock_markets=True) -> No
mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock()) mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock())
mocker.patch('freqtrade.exchange.Exchange.validate_timeframes', MagicMock()) mocker.patch('freqtrade.exchange.Exchange.validate_timeframes', MagicMock())
mocker.patch('freqtrade.exchange.Exchange.validate_ordertypes', MagicMock()) mocker.patch('freqtrade.exchange.Exchange.validate_ordertypes', MagicMock())
mocker.patch('freqtrade.exchange.Exchange.validate_stakecurrency', MagicMock())
mocker.patch('freqtrade.exchange.Exchange.id', PropertyMock(return_value=id)) mocker.patch('freqtrade.exchange.Exchange.id', PropertyMock(return_value=id))
mocker.patch('freqtrade.exchange.Exchange.name', PropertyMock(return_value=id.title())) mocker.patch('freqtrade.exchange.Exchange.name', PropertyMock(return_value=id.title()))
if mock_markets: if mock_markets: