From 30e45ec2bcbf584e5a395d5d0d2e6dc6075c9a7b Mon Sep 17 00:00:00 2001 From: Guillaume De Saint Martin Date: Sun, 12 Jan 2025 15:52:59 +0100 Subject: [PATCH] [MEXC] implement get_all_tradable_symbols --- Trading/Exchange/mexc/mexc_exchange.py | 42 ++++++++++++++------------ 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/Trading/Exchange/mexc/mexc_exchange.py b/Trading/Exchange/mexc/mexc_exchange.py index 85cb574df..390f12687 100644 --- a/Trading/Exchange/mexc/mexc_exchange.py +++ b/Trading/Exchange/mexc/mexc_exchange.py @@ -25,6 +25,7 @@ import octobot_trading.errors import octobot_commons.symbols as symbols_util import octobot_commons.constants as commons_constants +import octobot_commons import octobot_trading.constants as constants @@ -46,13 +47,6 @@ class MEXC(exchanges.RestExchange): ("api key info invalid",), ] - def __init__( - self, config, exchange_manager, exchange_config_by_exchange: typing.Optional[dict[str, dict]], - connector_class=None - ): - super().__init__(config, exchange_manager, exchange_config_by_exchange, connector_class=connector_class) - self.api_handled_symbols = APIHandledSymbols(self, commons_constants.DAYS_TO_SECONDS) - @classmethod def get_name(cls): return 'mexc' @@ -74,6 +68,15 @@ async def get_account_id(self, **kwargs: dict) -> str: # current impossible to get account UID (10/01/25) return constants.DEFAULT_SUBACCOUNT_ID + async def get_all_tradable_symbols(self, active_only=True) -> set[str]: + """ + Override if the exchange is not allowing trading for all available symbols (ex: MEXC) + :return: the list of all symbols supported by the exchange that can currently be traded through API + """ + if CACHED_MEXC_API_HANDLED_SYMBOLS.should_be_updated(): + await CACHED_MEXC_API_HANDLED_SYMBOLS.update(self) + return CACHED_MEXC_API_HANDLED_SYMBOLS.symbols + async def create_order(self, order_type: trading_enums.TraderOrderType, symbol: str, quantity: decimal.Decimal, price: decimal.Decimal = None, stop_price: decimal.Decimal = None, side: trading_enums.TradeOrderSide = None, current_price: decimal.Decimal = None, @@ -105,13 +108,13 @@ async def _mexc_handled_symbols_filter(self, symbol): try: yield except (ccxt.BadSymbol, ccxt.BadRequest) as err: - if self.api_handled_symbols.should_be_updated(): - await self.api_handled_symbols.update() - if symbol not in self.api_handled_symbols.symbols: - raise octobot_trading.errors.FailedRequest( + if CACHED_MEXC_API_HANDLED_SYMBOLS.should_be_updated(): + await CACHED_MEXC_API_HANDLED_SYMBOLS.update(self) + if symbol not in CACHED_MEXC_API_HANDLED_SYMBOLS.symbols: + raise octobot_trading.errors.UntradableSymbolError( f"{self.get_name()} error: {symbol} trading pair is not available to the API at the moment, " f"{symbol} is under maintenance ({err}). " - f"API available trading pairs are {self.api_handled_symbols.symbols}" + f"API available trading pairs are {CACHED_MEXC_API_HANDLED_SYMBOLS.symbols}" ) raise err @@ -157,28 +160,29 @@ class APIHandledSymbols: currently api tradable symbols from the defaultSymbols endpoint. """ - def __init__(self, exchange, update_interval): + def __init__(self, update_interval): self.symbols = set() self.last_update = 0 - self._exchange = exchange self._update_interval = update_interval def should_be_updated(self): return time.time() - self._update_interval >= self._update_interval - async def update(self): + async def update(self, exchange): try: - result = await self._exchange.connector.client.spot2PublicGetMarketApiDefaultSymbols() + result = await exchange.connector.client.spot2_public_get_market_api_default_symbols() self.symbols = set( # in some cases, "_" is not replaced as symbol is not found in markets - self._exchange.connector.client.safe_market(s)["symbol"].replace("_", "/") + exchange.connector.client.safe_market(s)["symbol"].replace("_", octobot_commons.MARKET_SEPARATOR) for s in result["data"]["symbol"] ) self.last_update = time.time() - self._exchange.logger.info(f"Updated handled symbols, list: {self.symbols}") + exchange.logger.info(f"Updated handled symbols, list: {self.symbols}") except Exception as err: - self._exchange.logger.exception(err, True, f"Error when fetching api-tradable symbols: {err}") + exchange.logger.exception(err, True, f"Error when fetching api-tradable symbols: {err}") +# make it available a singleton +CACHED_MEXC_API_HANDLED_SYMBOLS = APIHandledSymbols(commons_constants.DAYS_TO_SECONDS) class MEXCCCXTAdapter(exchanges.CCXTAdapter):