We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
fiat-convert: coingecko symbols are not unique
## Describe your environment

  * Operating system: Debian testing
  * Python Version: 3.9.1 (`python -V`)
  * CCXT version: doesn't matter (`pip freeze | grep ccxt`)
  * Freqtrade Version: develop (`freqtrade -V` or `docker-compose run --rm freqtrade -V` for Freqtrade running in docker)
  
## Describe the problem:

While working on #5067 I've discovered that the coingecko coin list has duplicated symbols

```
In [7]: from pycoingecko import CoinGeckoAPI
   ...: cg = CoinGeckoAPI()

In [8]: a=cg.get_coins_list()

In [9]: b = [x['symbol'] for x in a]

In [10]: len(set([x for x in b if b.count(x) > 1]))
Out[10]: 747
```

https://github.com/freqtrade/freqtrade/blob/a0893b291a099b928ced567b9ef81f2d2795717a/freqtrade/rpc/fiat_convert.py#L54 also wrongfully assumes that the symbols are uniqe.

I've added a hand-hacked workaround for the symbols from binance in #5067 - but a more general solution might be needed.



--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `freqtrade/rpc/fiat_convert.py`
Content:
```
1 """
2 Module that define classes to convert Crypto-currency to FIAT
3 e.g BTC to USD
4 """
5 
6 import datetime
7 import logging
8 from typing import Dict
9 
10 from cachetools.ttl import TTLCache
11 from pycoingecko import CoinGeckoAPI
12 from requests.exceptions import RequestException
13 
14 from freqtrade.constants import SUPPORTED_FIAT
15 
16 
17 logger = logging.getLogger(__name__)
18 
19 
20 class CryptoToFiatConverter:
21     """
22     Main class to initiate Crypto to FIAT.
23     This object contains a list of pair Crypto, FIAT
24     This object is also a Singleton
25     """
26     __instance = None
27     _coingekko: CoinGeckoAPI = None
28 
29     _cryptomap: Dict = {}
30     _backoff: float = 0.0
31 
32     def __new__(cls):
33         """
34         This class is a singleton - cannot be instantiated twice.
35         """
36         if CryptoToFiatConverter.__instance is None:
37             CryptoToFiatConverter.__instance = object.__new__(cls)
38             try:
39                 CryptoToFiatConverter._coingekko = CoinGeckoAPI()
40             except BaseException:
41                 CryptoToFiatConverter._coingekko = None
42         return CryptoToFiatConverter.__instance
43 
44     def __init__(self) -> None:
45         # Timeout: 6h
46         self._pair_price: TTLCache = TTLCache(maxsize=500, ttl=6 * 60 * 60)
47 
48         self._load_cryptomap()
49 
50     def _load_cryptomap(self) -> None:
51         try:
52             coinlistings = self._coingekko.get_coins_list()
53             # Create mapping table from symbol to coingekko_id
54             self._cryptomap = {x['symbol']: x['id'] for x in coinlistings}
55         except RequestException as request_exception:
56             if "429" in str(request_exception):
57                 logger.warning(
58                     "Too many requests for Coingecko API, backing off and trying again later.")
59                 # Set backoff timestamp to 60 seconds in the future
60                 self._backoff = datetime.datetime.now().timestamp() + 60
61                 return
62             # If the request is not a 429 error we want to raise the normal error
63             logger.error(
64                 "Could not load FIAT Cryptocurrency map for the following problem: {}".format(
65                     request_exception
66                 )
67             )
68         except (Exception) as exception:
69             logger.error(
70                 f"Could not load FIAT Cryptocurrency map for the following problem: {exception}")
71 
72     def convert_amount(self, crypto_amount: float, crypto_symbol: str, fiat_symbol: str) -> float:
73         """
74         Convert an amount of crypto-currency to fiat
75         :param crypto_amount: amount of crypto-currency to convert
76         :param crypto_symbol: crypto-currency used
77         :param fiat_symbol: fiat to convert to
78         :return: float, value in fiat of the crypto-currency amount
79         """
80         if crypto_symbol == fiat_symbol:
81             return float(crypto_amount)
82         price = self.get_price(crypto_symbol=crypto_symbol, fiat_symbol=fiat_symbol)
83         return float(crypto_amount) * float(price)
84 
85     def get_price(self, crypto_symbol: str, fiat_symbol: str) -> float:
86         """
87         Return the price of the Crypto-currency in Fiat
88         :param crypto_symbol: Crypto-currency you want to convert (e.g BTC)
89         :param fiat_symbol: FIAT currency you want to convert to (e.g USD)
90         :return: Price in FIAT
91         """
92         crypto_symbol = crypto_symbol.lower()
93         fiat_symbol = fiat_symbol.lower()
94         inverse = False
95 
96         if crypto_symbol == 'usd':
97             # usd corresponds to "uniswap-state-dollar" for coingecko.
98             # We'll therefore need to "swap" the currencies
99             logger.info(f"reversing Rates {crypto_symbol}, {fiat_symbol}")
100             crypto_symbol = fiat_symbol
101             fiat_symbol = 'usd'
102             inverse = True
103 
104         symbol = f"{crypto_symbol}/{fiat_symbol}"
105         # Check if the fiat conversion you want is supported
106         if not self._is_supported_fiat(fiat=fiat_symbol):
107             raise ValueError(f'The fiat {fiat_symbol} is not supported.')
108 
109         price = self._pair_price.get(symbol, None)
110 
111         if not price:
112             price = self._find_price(
113                 crypto_symbol=crypto_symbol,
114                 fiat_symbol=fiat_symbol
115             )
116             if inverse and price != 0.0:
117                 price = 1 / price
118             self._pair_price[symbol] = price
119 
120         return price
121 
122     def _is_supported_fiat(self, fiat: str) -> bool:
123         """
124         Check if the FIAT your want to convert to is supported
125         :param fiat: FIAT to check (e.g USD)
126         :return: bool, True supported, False not supported
127         """
128 
129         return fiat.upper() in SUPPORTED_FIAT
130 
131     def _find_price(self, crypto_symbol: str, fiat_symbol: str) -> float:
132         """
133         Call CoinGekko API to retrieve the price in the FIAT
134         :param crypto_symbol: Crypto-currency you want to convert (e.g btc)
135         :param fiat_symbol: FIAT currency you want to convert to (e.g usd)
136         :return: float, price of the crypto-currency in Fiat
137         """
138         # Check if the fiat conversion you want is supported
139         if not self._is_supported_fiat(fiat=fiat_symbol):
140             raise ValueError(f'The fiat {fiat_symbol} is not supported.')
141 
142         # No need to convert if both crypto and fiat are the same
143         if crypto_symbol == fiat_symbol:
144             return 1.0
145 
146         if self._cryptomap == {}:
147             if self._backoff <= datetime.datetime.now().timestamp():
148                 self._load_cryptomap()
149                 # return 0.0 if we still don't have data to check, no reason to proceed
150                 if self._cryptomap == {}:
151                     return 0.0
152             else:
153                 return 0.0
154 
155         if crypto_symbol not in self._cryptomap:
156             # return 0 for unsupported stake currencies (fiat-convert should not break the bot)
157             logger.warning("unsupported crypto-symbol %s - returning 0.0", crypto_symbol)
158             return 0.0
159 
160         try:
161             _gekko_id = self._cryptomap[crypto_symbol]
162             return float(
163                 self._coingekko.get_price(
164                     ids=_gekko_id,
165                     vs_currencies=fiat_symbol
166                 )[_gekko_id][fiat_symbol]
167             )
168         except Exception as exception:
169             logger.error("Error in _find_price: %s", exception)
170             return 0.0
171
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/freqtrade/rpc/fiat_convert.py b/freqtrade/rpc/fiat_convert.py
--- a/freqtrade/rpc/fiat_convert.py
+++ b/freqtrade/rpc/fiat_convert.py
@@ -5,7 +5,7 @@
 
 import datetime
 import logging
-from typing import Dict
+from typing import Dict, List
 
 from cachetools.ttl import TTLCache
 from pycoingecko import CoinGeckoAPI
@@ -25,8 +25,7 @@
     """
     __instance = None
     _coingekko: CoinGeckoAPI = None
-
-    _cryptomap: Dict = {}
+    _coinlistings: List[Dict] = []
     _backoff: float = 0.0
 
     def __new__(cls):
@@ -49,9 +48,8 @@
 
     def _load_cryptomap(self) -> None:
         try:
-            coinlistings = self._coingekko.get_coins_list()
-            # Create mapping table from symbol to coingekko_id
-            self._cryptomap = {x['symbol']: x['id'] for x in coinlistings}
+            # Use list-comprehension to ensure we get a list.
+            self._coinlistings = [x for x in self._coingekko.get_coins_list()]
         except RequestException as request_exception:
             if "429" in str(request_exception):
                 logger.warning(
@@ -69,6 +67,24 @@
             logger.error(
                 f"Could not load FIAT Cryptocurrency map for the following problem: {exception}")
 
+    def _get_gekko_id(self, crypto_symbol):
+        if not self._coinlistings:
+            if self._backoff <= datetime.datetime.now().timestamp():
+                self._load_cryptomap()
+                # Still not loaded.
+                if not self._coinlistings:
+                    return None
+            else:
+                return None
+        found = [x for x in self._coinlistings if x['symbol'] == crypto_symbol]
+        if len(found) == 1:
+            return found[0]['id']
+
+        if len(found) > 0:
+            # Wrong!
+            logger.warning(f"Found multiple mappings in goingekko for {crypto_symbol}.")
+            return None
+
     def convert_amount(self, crypto_amount: float, crypto_symbol: str, fiat_symbol: str) -> float:
         """
         Convert an amount of crypto-currency to fiat
@@ -143,22 +159,14 @@
         if crypto_symbol == fiat_symbol:
             return 1.0
 
-        if self._cryptomap == {}:
-            if self._backoff <= datetime.datetime.now().timestamp():
-                self._load_cryptomap()
-                # return 0.0 if we still don't have data to check, no reason to proceed
-                if self._cryptomap == {}:
-                    return 0.0
-            else:
-                return 0.0
+        _gekko_id = self._get_gekko_id(crypto_symbol)
 
-        if crypto_symbol not in self._cryptomap:
+        if not _gekko_id:
             # return 0 for unsupported stake currencies (fiat-convert should not break the bot)
             logger.warning("unsupported crypto-symbol %s - returning 0.0", crypto_symbol)
             return 0.0
 
         try:
-            _gekko_id = self._cryptomap[crypto_symbol]
             return float(
                 self._coingekko.get_price(
                     ids=_gekko_id,

{"golden_diff": "diff --git a/freqtrade/rpc/fiat_convert.py b/freqtrade/rpc/fiat_convert.py\n--- a/freqtrade/rpc/fiat_convert.py\n+++ b/freqtrade/rpc/fiat_convert.py\n@@ -5,7 +5,7 @@\n \n import datetime\n import logging\n-from typing import Dict\n+from typing import Dict, List\n \n from cachetools.ttl import TTLCache\n from pycoingecko import CoinGeckoAPI\n@@ -25,8 +25,7 @@\n     \"\"\"\n     __instance = None\n     _coingekko: CoinGeckoAPI = None\n-\n-    _cryptomap: Dict = {}\n+    _coinlistings: List[Dict] = []\n     _backoff: float = 0.0\n \n     def __new__(cls):\n@@ -49,9 +48,8 @@\n \n     def _load_cryptomap(self) -> None:\n         try:\n-            coinlistings = self._coingekko.get_coins_list()\n-            # Create mapping table from symbol to coingekko_id\n-            self._cryptomap = {x['symbol']: x['id'] for x in coinlistings}\n+            # Use list-comprehension to ensure we get a list.\n+            self._coinlistings = [x for x in self._coingekko.get_coins_list()]\n         except RequestException as request_exception:\n             if \"429\" in str(request_exception):\n                 logger.warning(\n@@ -69,6 +67,24 @@\n             logger.error(\n                 f\"Could not load FIAT Cryptocurrency map for the following problem: {exception}\")\n \n+    def _get_gekko_id(self, crypto_symbol):\n+        if not self._coinlistings:\n+            if self._backoff <= datetime.datetime.now().timestamp():\n+                self._load_cryptomap()\n+                # Still not loaded.\n+                if not self._coinlistings:\n+                    return None\n+            else:\n+                return None\n+        found = [x for x in self._coinlistings if x['symbol'] == crypto_symbol]\n+        if len(found) == 1:\n+            return found[0]['id']\n+\n+        if len(found) > 0:\n+            # Wrong!\n+            logger.warning(f\"Found multiple mappings in goingekko for {crypto_symbol}.\")\n+            return None\n+\n     def convert_amount(self, crypto_amount: float, crypto_symbol: str, fiat_symbol: str) -> float:\n         \"\"\"\n         Convert an amount of crypto-currency to fiat\n@@ -143,22 +159,14 @@\n         if crypto_symbol == fiat_symbol:\n             return 1.0\n \n-        if self._cryptomap == {}:\n-            if self._backoff <= datetime.datetime.now().timestamp():\n-                self._load_cryptomap()\n-                # return 0.0 if we still don't have data to check, no reason to proceed\n-                if self._cryptomap == {}:\n-                    return 0.0\n-            else:\n-                return 0.0\n+        _gekko_id = self._get_gekko_id(crypto_symbol)\n \n-        if crypto_symbol not in self._cryptomap:\n+        if not _gekko_id:\n             # return 0 for unsupported stake currencies (fiat-convert should not break the bot)\n             logger.warning(\"unsupported crypto-symbol %s - returning 0.0\", crypto_symbol)\n             return 0.0\n \n         try:\n-            _gekko_id = self._cryptomap[crypto_symbol]\n             return float(\n                 self._coingekko.get_price(\n                     ids=_gekko_id,\n", "issue": "fiat-convert: coingecko symbols are not unique\n## Describe your environment\r\n\r\n  * Operating system: Debian testing\r\n  * Python Version: 3.9.1 (`python -V`)\r\n  * CCXT version: doesn't matter (`pip freeze | grep ccxt`)\r\n  * Freqtrade Version: develop (`freqtrade -V` or `docker-compose run --rm freqtrade -V` for Freqtrade running in docker)\r\n  \r\n## Describe the problem:\r\n\r\nWhile working on #5067 I've discovered that the coingecko coin list has duplicated symbols\r\n\r\n```\r\nIn [7]: from pycoingecko import CoinGeckoAPI\r\n   ...: cg = CoinGeckoAPI()\r\n\r\nIn [8]: a=cg.get_coins_list()\r\n\r\nIn [9]: b = [x['symbol'] for x in a]\r\n\r\nIn [10]: len(set([x for x in b if b.count(x) > 1]))\r\nOut[10]: 747\r\n```\r\n\r\nhttps://github.com/freqtrade/freqtrade/blob/a0893b291a099b928ced567b9ef81f2d2795717a/freqtrade/rpc/fiat_convert.py#L54 also wrongfully assumes that the symbols are uniqe.\r\n\r\nI've added a hand-hacked workaround for the symbols from binance in #5067 - but a more general solution might be needed.\r\n\r\n\n", "before_files": [{"content": "\"\"\"\nModule that define classes to convert Crypto-currency to FIAT\ne.g BTC to USD\n\"\"\"\n\nimport datetime\nimport logging\nfrom typing import Dict\n\nfrom cachetools.ttl import TTLCache\nfrom pycoingecko import CoinGeckoAPI\nfrom requests.exceptions import RequestException\n\nfrom freqtrade.constants import SUPPORTED_FIAT\n\n\nlogger = logging.getLogger(__name__)\n\n\nclass CryptoToFiatConverter:\n    \"\"\"\n    Main class to initiate Crypto to FIAT.\n    This object contains a list of pair Crypto, FIAT\n    This object is also a Singleton\n    \"\"\"\n    __instance = None\n    _coingekko: CoinGeckoAPI = None\n\n    _cryptomap: Dict = {}\n    _backoff: float = 0.0\n\n    def __new__(cls):\n        \"\"\"\n        This class is a singleton - cannot be instantiated twice.\n        \"\"\"\n        if CryptoToFiatConverter.__instance is None:\n            CryptoToFiatConverter.__instance = object.__new__(cls)\n            try:\n                CryptoToFiatConverter._coingekko = CoinGeckoAPI()\n            except BaseException:\n                CryptoToFiatConverter._coingekko = None\n        return CryptoToFiatConverter.__instance\n\n    def __init__(self) -> None:\n        # Timeout: 6h\n        self._pair_price: TTLCache = TTLCache(maxsize=500, ttl=6 * 60 * 60)\n\n        self._load_cryptomap()\n\n    def _load_cryptomap(self) -> None:\n        try:\n            coinlistings = self._coingekko.get_coins_list()\n            # Create mapping table from symbol to coingekko_id\n            self._cryptomap = {x['symbol']: x['id'] for x in coinlistings}\n        except RequestException as request_exception:\n            if \"429\" in str(request_exception):\n                logger.warning(\n                    \"Too many requests for Coingecko API, backing off and trying again later.\")\n                # Set backoff timestamp to 60 seconds in the future\n                self._backoff = datetime.datetime.now().timestamp() + 60\n                return\n            # If the request is not a 429 error we want to raise the normal error\n            logger.error(\n                \"Could not load FIAT Cryptocurrency map for the following problem: {}\".format(\n                    request_exception\n                )\n            )\n        except (Exception) as exception:\n            logger.error(\n                f\"Could not load FIAT Cryptocurrency map for the following problem: {exception}\")\n\n    def convert_amount(self, crypto_amount: float, crypto_symbol: str, fiat_symbol: str) -> float:\n        \"\"\"\n        Convert an amount of crypto-currency to fiat\n        :param crypto_amount: amount of crypto-currency to convert\n        :param crypto_symbol: crypto-currency used\n        :param fiat_symbol: fiat to convert to\n        :return: float, value in fiat of the crypto-currency amount\n        \"\"\"\n        if crypto_symbol == fiat_symbol:\n            return float(crypto_amount)\n        price = self.get_price(crypto_symbol=crypto_symbol, fiat_symbol=fiat_symbol)\n        return float(crypto_amount) * float(price)\n\n    def get_price(self, crypto_symbol: str, fiat_symbol: str) -> float:\n        \"\"\"\n        Return the price of the Crypto-currency in Fiat\n        :param crypto_symbol: Crypto-currency you want to convert (e.g BTC)\n        :param fiat_symbol: FIAT currency you want to convert to (e.g USD)\n        :return: Price in FIAT\n        \"\"\"\n        crypto_symbol = crypto_symbol.lower()\n        fiat_symbol = fiat_symbol.lower()\n        inverse = False\n\n        if crypto_symbol == 'usd':\n            # usd corresponds to \"uniswap-state-dollar\" for coingecko.\n            # We'll therefore need to \"swap\" the currencies\n            logger.info(f\"reversing Rates {crypto_symbol}, {fiat_symbol}\")\n            crypto_symbol = fiat_symbol\n            fiat_symbol = 'usd'\n            inverse = True\n\n        symbol = f\"{crypto_symbol}/{fiat_symbol}\"\n        # Check if the fiat conversion you want is supported\n        if not self._is_supported_fiat(fiat=fiat_symbol):\n            raise ValueError(f'The fiat {fiat_symbol} is not supported.')\n\n        price = self._pair_price.get(symbol, None)\n\n        if not price:\n            price = self._find_price(\n                crypto_symbol=crypto_symbol,\n                fiat_symbol=fiat_symbol\n            )\n            if inverse and price != 0.0:\n                price = 1 / price\n            self._pair_price[symbol] = price\n\n        return price\n\n    def _is_supported_fiat(self, fiat: str) -> bool:\n        \"\"\"\n        Check if the FIAT your want to convert to is supported\n        :param fiat: FIAT to check (e.g USD)\n        :return: bool, True supported, False not supported\n        \"\"\"\n\n        return fiat.upper() in SUPPORTED_FIAT\n\n    def _find_price(self, crypto_symbol: str, fiat_symbol: str) -> float:\n        \"\"\"\n        Call CoinGekko API to retrieve the price in the FIAT\n        :param crypto_symbol: Crypto-currency you want to convert (e.g btc)\n        :param fiat_symbol: FIAT currency you want to convert to (e.g usd)\n        :return: float, price of the crypto-currency in Fiat\n        \"\"\"\n        # Check if the fiat conversion you want is supported\n        if not self._is_supported_fiat(fiat=fiat_symbol):\n            raise ValueError(f'The fiat {fiat_symbol} is not supported.')\n\n        # No need to convert if both crypto and fiat are the same\n        if crypto_symbol == fiat_symbol:\n            return 1.0\n\n        if self._cryptomap == {}:\n            if self._backoff <= datetime.datetime.now().timestamp():\n                self._load_cryptomap()\n                # return 0.0 if we still don't have data to check, no reason to proceed\n                if self._cryptomap == {}:\n                    return 0.0\n            else:\n                return 0.0\n\n        if crypto_symbol not in self._cryptomap:\n            # return 0 for unsupported stake currencies (fiat-convert should not break the bot)\n            logger.warning(\"unsupported crypto-symbol %s - returning 0.0\", crypto_symbol)\n            return 0.0\n\n        try:\n            _gekko_id = self._cryptomap[crypto_symbol]\n            return float(\n                self._coingekko.get_price(\n                    ids=_gekko_id,\n                    vs_currencies=fiat_symbol\n                )[_gekko_id][fiat_symbol]\n            )\n        except Exception as exception:\n            logger.error(\"Error in _find_price: %s\", exception)\n            return 0.0\n", "path": "freqtrade/rpc/fiat_convert.py"}], "after_files": [{"content": "\"\"\"\nModule that define classes to convert Crypto-currency to FIAT\ne.g BTC to USD\n\"\"\"\n\nimport datetime\nimport logging\nfrom typing import Dict, List\n\nfrom cachetools.ttl import TTLCache\nfrom pycoingecko import CoinGeckoAPI\nfrom requests.exceptions import RequestException\n\nfrom freqtrade.constants import SUPPORTED_FIAT\n\n\nlogger = logging.getLogger(__name__)\n\n\nclass CryptoToFiatConverter:\n    \"\"\"\n    Main class to initiate Crypto to FIAT.\n    This object contains a list of pair Crypto, FIAT\n    This object is also a Singleton\n    \"\"\"\n    __instance = None\n    _coingekko: CoinGeckoAPI = None\n    _coinlistings: List[Dict] = []\n    _backoff: float = 0.0\n\n    def __new__(cls):\n        \"\"\"\n        This class is a singleton - cannot be instantiated twice.\n        \"\"\"\n        if CryptoToFiatConverter.__instance is None:\n            CryptoToFiatConverter.__instance = object.__new__(cls)\n            try:\n                CryptoToFiatConverter._coingekko = CoinGeckoAPI()\n            except BaseException:\n                CryptoToFiatConverter._coingekko = None\n        return CryptoToFiatConverter.__instance\n\n    def __init__(self) -> None:\n        # Timeout: 6h\n        self._pair_price: TTLCache = TTLCache(maxsize=500, ttl=6 * 60 * 60)\n\n        self._load_cryptomap()\n\n    def _load_cryptomap(self) -> None:\n        try:\n            # Use list-comprehension to ensure we get a list.\n            self._coinlistings = [x for x in self._coingekko.get_coins_list()]\n        except RequestException as request_exception:\n            if \"429\" in str(request_exception):\n                logger.warning(\n                    \"Too many requests for Coingecko API, backing off and trying again later.\")\n                # Set backoff timestamp to 60 seconds in the future\n                self._backoff = datetime.datetime.now().timestamp() + 60\n                return\n            # If the request is not a 429 error we want to raise the normal error\n            logger.error(\n                \"Could not load FIAT Cryptocurrency map for the following problem: {}\".format(\n                    request_exception\n                )\n            )\n        except (Exception) as exception:\n            logger.error(\n                f\"Could not load FIAT Cryptocurrency map for the following problem: {exception}\")\n\n    def _get_gekko_id(self, crypto_symbol):\n        if not self._coinlistings:\n            if self._backoff <= datetime.datetime.now().timestamp():\n                self._load_cryptomap()\n                # Still not loaded.\n                if not self._coinlistings:\n                    return None\n            else:\n                return None\n        found = [x for x in self._coinlistings if x['symbol'] == crypto_symbol]\n        if len(found) == 1:\n            return found[0]['id']\n\n        if len(found) > 0:\n            # Wrong!\n            logger.warning(f\"Found multiple mappings in goingekko for {crypto_symbol}.\")\n            return None\n\n    def convert_amount(self, crypto_amount: float, crypto_symbol: str, fiat_symbol: str) -> float:\n        \"\"\"\n        Convert an amount of crypto-currency to fiat\n        :param crypto_amount: amount of crypto-currency to convert\n        :param crypto_symbol: crypto-currency used\n        :param fiat_symbol: fiat to convert to\n        :return: float, value in fiat of the crypto-currency amount\n        \"\"\"\n        if crypto_symbol == fiat_symbol:\n            return float(crypto_amount)\n        price = self.get_price(crypto_symbol=crypto_symbol, fiat_symbol=fiat_symbol)\n        return float(crypto_amount) * float(price)\n\n    def get_price(self, crypto_symbol: str, fiat_symbol: str) -> float:\n        \"\"\"\n        Return the price of the Crypto-currency in Fiat\n        :param crypto_symbol: Crypto-currency you want to convert (e.g BTC)\n        :param fiat_symbol: FIAT currency you want to convert to (e.g USD)\n        :return: Price in FIAT\n        \"\"\"\n        crypto_symbol = crypto_symbol.lower()\n        fiat_symbol = fiat_symbol.lower()\n        inverse = False\n\n        if crypto_symbol == 'usd':\n            # usd corresponds to \"uniswap-state-dollar\" for coingecko.\n            # We'll therefore need to \"swap\" the currencies\n            logger.info(f\"reversing Rates {crypto_symbol}, {fiat_symbol}\")\n            crypto_symbol = fiat_symbol\n            fiat_symbol = 'usd'\n            inverse = True\n\n        symbol = f\"{crypto_symbol}/{fiat_symbol}\"\n        # Check if the fiat conversion you want is supported\n        if not self._is_supported_fiat(fiat=fiat_symbol):\n            raise ValueError(f'The fiat {fiat_symbol} is not supported.')\n\n        price = self._pair_price.get(symbol, None)\n\n        if not price:\n            price = self._find_price(\n                crypto_symbol=crypto_symbol,\n                fiat_symbol=fiat_symbol\n            )\n            if inverse and price != 0.0:\n                price = 1 / price\n            self._pair_price[symbol] = price\n\n        return price\n\n    def _is_supported_fiat(self, fiat: str) -> bool:\n        \"\"\"\n        Check if the FIAT your want to convert to is supported\n        :param fiat: FIAT to check (e.g USD)\n        :return: bool, True supported, False not supported\n        \"\"\"\n\n        return fiat.upper() in SUPPORTED_FIAT\n\n    def _find_price(self, crypto_symbol: str, fiat_symbol: str) -> float:\n        \"\"\"\n        Call CoinGekko API to retrieve the price in the FIAT\n        :param crypto_symbol: Crypto-currency you want to convert (e.g btc)\n        :param fiat_symbol: FIAT currency you want to convert to (e.g usd)\n        :return: float, price of the crypto-currency in Fiat\n        \"\"\"\n        # Check if the fiat conversion you want is supported\n        if not self._is_supported_fiat(fiat=fiat_symbol):\n            raise ValueError(f'The fiat {fiat_symbol} is not supported.')\n\n        # No need to convert if both crypto and fiat are the same\n        if crypto_symbol == fiat_symbol:\n            return 1.0\n\n        _gekko_id = self._get_gekko_id(crypto_symbol)\n\n        if not _gekko_id:\n            # return 0 for unsupported stake currencies (fiat-convert should not break the bot)\n            logger.warning(\"unsupported crypto-symbol %s - returning 0.0\", crypto_symbol)\n            return 0.0\n\n        try:\n            return float(\n                self._coingekko.get_price(\n                    ids=_gekko_id,\n                    vs_currencies=fiat_symbol\n                )[_gekko_id][fiat_symbol]\n            )\n        except Exception as exception:\n            logger.error(\"Error in _find_price: %s\", exception)\n            return 0.0\n", "path": "freqtrade/rpc/fiat_convert.py"}]}