Repository: freqtrade/freqtrade

Issue:
USDT is not available as stake on Binance. (NetworkError)
<!-- 
Have you searched for similar issues before posting it? yes
Did you have a VERY good look at the [documentation](https://www.freqtrade.io/en/latest/) and are sure that the question is not explained there yes

Please do not use the question template to report bugs or to request new features.
-->

## Describe your environment

  * Operating system: Ubuntu
  * Python Version: Python 3.8.10
  * CCXT version:1.55.55
  * Freqtrade Version: freqtrade 2021.8
  
## Your question

*Im getting this error: USDT is not available as stake on Binance. Available currencies are:

ccxt.base.errors.NetworkError: binance GET https://api.binance.com/api/v3/exchangeInfo
2021-08-28 20:57:54,794 - freqtrade.commands.trade_commands - ERROR - USDT is not available as stake on Binance. Available currencies are: 
2021-08-28 20:57:54,794 - freqtrade.commands.trade_commands - ERROR - Fatal exception!
Traceback (most recent call last):
  File "/freqtrade/freqtrade/commands/trade_commands.py", line 18, in start_trading
    worker = Worker(args)
  File "/freqtrade/freqtrade/worker.py", line 35, in __init__
    self._init(False)
  File "/freqtrade/freqtrade/worker.py", line 52, in _init
    self.freqtrade = FreqtradeBot(self._config)
  File "/freqtrade/freqtrade/freqtradebot.py", line 65, in __init__
    self.exchange = ExchangeResolver.load_exchange(self.config['exchange']['name'], self.config)
  File "/freqtrade/freqtrade/resolvers/exchange_resolver.py", line 32, in load_exchange
    exchange = ExchangeResolver._load_exchange(exchange_name,
  File "/freqtrade/freqtrade/resolvers/exchange_resolver.py", line 54, in _load_exchange
    exchange = ex_class(**kwargs)
  File "/freqtrade/freqtrade/exchange/exchange.py", line 148, in __init__
    self.validate_stakecurrency(config['stake_currency'])
  File "/freqtrade/freqtrade/exchange/exchange.py", line 360, in validate_stakecurrency
    raise OperationalException(
freqtrade.exceptions.OperationalException: USDT is not available as stake on Binance. Available currencies are: 


        "pair_whitelist": [
            "BCH/USDT",
            "ETH/USDT",
            "LINK/USDT",
            "XTZ/USDT"
        ],
        "pair_blacklist": [
            "BNB/BTC",
            "BNB/BUSD",
            "BNB/ETH",
            "BNB/EUR",
            "BNB/NGN",
            "BNB/PAX",
            "BNB/RUB",
            "BNB/TRY",
            "BNB/TUSD",
            "BNB/USDC",
            "BNB/USDS",
            "BNB/USDT"
        ]
    },



Discussion:
I am having a similar issue with freqtrade not connecting to Binance and telling me that stake currency AUD is not available. 
Please see below for complete logfile dump. The logfile just repeats this information over and over.

I am using: 
Ubuntu 20.04 
Python 3.9.5
CCXT 1.55.28
Freqtrade 2021.8

As a side note, Freqtrade 2021.7 was running with no problems whatsoever.

[freqtrade_error.txt](https://github.com/freqtrade/freqtrade/files/7071606/freqtrade_error.txt)

The hint is the network error.
Due to that, freqtrade will not know any markets, and therefore reject all stake currencies.

Its usually either a problem with local setup / network, but in this case (2 people with the same problem very close to each other), more likely a problem on binances side (maybe regionally).

Simply retrying later should help in this case.

Resolving patch:
diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py
--- a/freqtrade/exchange/exchange.py
+++ b/freqtrade/exchange/exchange.py
@@ -352,9 +352,16 @@ def reload_markets(self) -> None:
     def validate_stakecurrency(self, stake_currency: str) -> None:
         """
         Checks stake-currency against available currencies on the exchange.
+        Only runs on startup. If markets have not been loaded, there's been a problem with
+        the connection to the exchange.
         :param stake_currency: Stake-currency to validate
         :raise: OperationalException if stake-currency is not available.
         """
+        if not self._markets:
+            raise OperationalException(
+                'Could not load markets, therefore cannot start. '
+                'Please investigate the above error for more details.'
+                )
         quote_currencies = self.get_quote_currencies()
         if stake_currency not in quote_currencies:
             raise OperationalException(


Test patch:
diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py
--- a/tests/exchange/test_exchange.py
+++ b/tests/exchange/test_exchange.py
@@ -557,7 +557,7 @@ def test_reload_markets_exception(default_conf, mocker, caplog):
 
 
 @pytest.mark.parametrize("stake_currency", ['ETH', 'BTC', 'USDT'])
-def test_validate_stake_currency(default_conf, stake_currency, mocker, caplog):
+def test_validate_stakecurrency(default_conf, stake_currency, mocker, caplog):
     default_conf['stake_currency'] = stake_currency
     api_mock = MagicMock()
     type(api_mock).load_markets = MagicMock(return_value={
@@ -571,7 +571,7 @@ def test_validate_stake_currency(default_conf, stake_currency, mocker, caplog):
     Exchange(default_conf)
 
 
-def test_validate_stake_currency_error(default_conf, mocker, caplog):
+def test_validate_stakecurrency_error(default_conf, mocker, caplog):
     default_conf['stake_currency'] = 'XRP'
     api_mock = MagicMock()
     type(api_mock).load_markets = MagicMock(return_value={
@@ -587,6 +587,13 @@ def test_validate_stake_currency_error(default_conf, mocker, caplog):
                        'Available currencies are: BTC, ETH, USDT'):
         Exchange(default_conf)
 
+    type(api_mock).load_markets = MagicMock(side_effect=ccxt.NetworkError('No connection.'))
+    mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock))
+
+    with pytest.raises(OperationalException,
+                       match=r'Could not load markets, therefore cannot start\. Please.*'):
+        Exchange(default_conf)
+
 
 def test_get_quote_currencies(default_conf, mocker):
     ex = get_patched_exchange(mocker, default_conf)