def get_markets(self) -> List[Exchange.Market]: try: markets: dict = self._api.get_exchange_info() except (BinanceAPIException, BinanceRequestException) as e: if isinstance(e, BinanceAPIException): # TODO: Raise an exception when rate limited. Probably overkill # because it's unlikely over 1200 requests will be sent per # minute. if e.status_code == 429: self._log.error("Being rate limited.") elif e.status_code == 418: self._log.error("IP banned for violation of rate limits.") self._log.error("Markets could not be retrieved.") return [] markets = markets["symbols"] self._log.debug(f"Retrieved {len(markets)} markets.") # TODO: Filter out inactive markets (m["status"] != "TRADING") return list( map( lambda m: Exchange.Market( m["symbol"], Exchange.Currency(m["baseAsset"], None, m[ "baseAssetPrecision"]), Exchange.Currency(m["quoteAsset"], None, m[ "quotePrecision"]), self._get_step_size(m["filters"])), markets))
def get_markets(currency: Exchange.Currency) -> \ DefaultDict[str, List[Exchange.Market]]: g.log.debug(f"Getting markets for base currency {currency.symbol}.") quotes: Tuple[str] = tuple(g.config["order"]["quote_currencies"].keys()) cases: str = "\n".join(f"when '{ex}' then {i}" for i, ex in enumerate(quotes)) g.db.cursor.execute( f""" select e.name, em.name, m.base, (select precision from currencies where symbol = m.base limit 1) base_prec, m.quote, (select precision from currencies where symbol = m.base limit 1) quote_prec, m.step from markets m join exchange_markets em on m.id = em.market_id join exchanges e on em.exchange_id = e.id where base = upper(?) and lower(quote) in ({", ".join(["?"] * len(quotes))}) order by e.name, case lower(m.quote) {cases} end """, (currency.symbol, ) + quotes) results: List[Tuple[str, str, str, int, str, int, Union[str, None]]] = g.db.cursor.fetchall() markets: DefaultDict[str, List[Exchange.Market]] = defaultdict(list) g.log.debug(f"Retrieved {len(results)} markets.") for ex, market, base, base_prec, quote, quote_prec, step in results: markets[ex].append( Exchange.Market(market, Exchange.Currency(base, None, base_prec), Exchange.Currency(quote, None, quote_prec), Decimal(step) if step else None)) return markets
def parse_currency(text: str) -> Optional[Exchange.Currency]: """Finds a currency in a string. Searches for a currency in the string :any:`text` and returns the first match. Notes ----- Queries the database for all currencies and iterates them. Uses a regular expression to find a match in the text and constructs a :class:`~Exchange.Currency` from it. Parameters ---------- text: str The string in which to search for a currency. Returns ------- Exchange.Currency or None The first matching currency found in the string, or :any:`None` if no matches are found. """ log.debug("Searching for a currency in the text.") g.db.cursor.execute("select * from currencies") return next( (Exchange.Currency(symbol, name, precision) for symbol, name, precision in g.db.cursor.fetchall() if re.search((name if g.config["search_currency_name"] else "") + r"\s*?[(\[{]+?\s*?" + symbol + r"\s*?[)\]}]", text, re.IGNORECASE)), None)
def get_markets(self) -> List[Exchange.Market]: markets: dict = self._api.get_markets() if not markets["success"]: self._log.error("Markets could not be retrieved: " f"{markets['message']}") return [] markets = markets["result"] self._log.debug(f"Retrieved {len(markets)} markets.") # TODO: Filter out inactive markets (not m["IsActive"])? return list(map(lambda m: Exchange.Market( m["MarketName"], Exchange.Currency( m["MarketCurrency"], m["MarketCurrencyLong"], None), Exchange.Currency( m["BaseCurrency"], m["BaseCurrencyLong"], None), None), markets))
def get_currencies() -> List[Exchange.Currency]: g.log.debug("Getting currencies from CoinMarketCap.") return list( map(lambda c: Exchange.Currency(c["symbol"], c["name"], None), Market().ticker(limit=0)))