Implement validation for valid stake currency
This commit is contained in:
parent
235a10ab86
commit
13274964a9
@ -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,
|
||||||
|
@ -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.")
|
||||||
|
|
||||||
|
@ -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:
|
||||||
|
Loading…
Reference in New Issue
Block a user