diff --git a/additional_tests/exchanges_tests/test_binance_futures.py b/additional_tests/exchanges_tests/test_binance_futures.py index 9826efeb1..b61401dde 100644 --- a/additional_tests/exchanges_tests/test_binance_futures.py +++ b/additional_tests/exchanges_tests/test_binance_futures.py @@ -42,6 +42,8 @@ class TestBinanceFuturesAuthenticatedExchange( MAX_TRADE_USD_VALUE = decimal.Decimal(450000) # testnet portfolio ALLOW_0_MAKER_FEES = True SUPPORTS_GET_MAX_ORDERS_COUNT = True + # Set True when get_cancelled_order() can return outdated open orders + CAN_HAVE_DELAYED_CANCELLED_ORDERS = True SPECIAL_ORDER_TYPES_BY_EXCHANGE_ID: dict[ str, ( diff --git a/additional_tests/exchanges_tests/test_bitget.py b/additional_tests/exchanges_tests/test_bitget.py index 3dbdbac72..9a365ec1b 100644 --- a/additional_tests/exchanges_tests/test_bitget.py +++ b/additional_tests/exchanges_tests/test_bitget.py @@ -23,6 +23,7 @@ pytestmark = pytest.mark.asyncio +# need non FR account to test this exchange (20 march 2026) class TestBitgetAuthenticatedExchange( abstract_authenticated_exchange_tester.AbstractAuthenticatedExchangeTester ): diff --git a/packages/tentacles/Trading/Exchange/coinbase/coinbase_exchange.py b/packages/tentacles/Trading/Exchange/coinbase/coinbase_exchange.py index eb19df22c..d99e6c672 100644 --- a/packages/tentacles/Trading/Exchange/coinbase/coinbase_exchange.py +++ b/packages/tentacles/Trading/Exchange/coinbase/coinbase_exchange.py @@ -279,7 +279,6 @@ async def _ensure_auth(self): class Coinbase(exchanges.RestExchange): MAX_PAGINATION_LIMIT: int = 300 - ALWAYS_REQUIRES_AUTHENTICATION = True IS_SKIPPING_EMPTY_CANDLES_IN_OHLCV_FETCH = True DEFAULT_CONNECTOR_CLASS = CoinbaseConnector diff --git a/packages/tentacles/Trading/Exchange/hyperliquid/hyperliquid_exchange.py b/packages/tentacles/Trading/Exchange/hyperliquid/hyperliquid_exchange.py index e4253d937..7d181d55a 100644 --- a/packages/tentacles/Trading/Exchange/hyperliquid/hyperliquid_exchange.py +++ b/packages/tentacles/Trading/Exchange/hyperliquid/hyperliquid_exchange.py @@ -44,6 +44,8 @@ class Hyperliquid(exchanges.RestExchange): FIX_MARKET_STATUS = True REQUIRE_ORDER_FEES_FROM_TRADES = True # set True when get_order is not giving fees on closed orders and fees # should be fetched using recent trades. + EXPECT_POSSIBLE_ORDER_NOT_FOUND_DURING_ORDER_CREATION = True # set True when get_order() can return None + # (order not found) when orders are instantly filled on exchange and are not fully processed on the exchange side. @classmethod def get_name(cls): diff --git a/packages/trading/requirements.txt b/packages/trading/requirements.txt index 1de2cf886..5282d05a6 100644 --- a/packages/trading/requirements.txt +++ b/packages/trading/requirements.txt @@ -1,7 +1,7 @@ numpy==2.4.2 # Exchange connection requirements -ccxt==4.5.28 # always ensure real exchanges tests (in tests_additional and authenticated exchange tests) are passing before changing the ccxt version +ccxt==4.5.44 # always ensure real exchanges tests (in tests_additional and authenticated exchange tests) are passing before changing the ccxt version cryptography # Never specify a version (managed by https://github.com/Drakkar-Software/OctoBot-PyPi-Linux-Deployer) diff --git a/packages/trading/tests_additional/real_exchanges/real_exchange_tester.py b/packages/trading/tests_additional/real_exchanges/real_exchange_tester.py index 576ab3166..a618f8020 100644 --- a/packages/trading/tests_additional/real_exchanges/real_exchange_tester.py +++ b/packages/trading/tests_additional/real_exchanges/real_exchange_tester.py @@ -340,12 +340,8 @@ async def get_price_ticker(self): async with self.get_exchange_manager() as exchange_manager: return await exchange_manager.exchange.get_price_ticker(self.SYMBOL) - async def get_all_currencies_price_ticker(self, market_filter=None, **kwargs): - if market_filter is not None: - async with self.get_exchange_manager(market_filter=market_filter) as exchange_manager: - # create 2 exchange manager to force applying market_filter (avoid single test call side effect) - await exchange_manager.exchange.connector.load_symbol_markets() - async with self.get_exchange_manager(market_filter=market_filter) as exchange_manager: + async def get_all_currencies_price_ticker(self, **kwargs): + async with self.get_exchange_manager() as exchange_manager: return await exchange_manager.exchange.get_all_currencies_price_ticker(**kwargs) async def get_user_recent_trades(self): diff --git a/packages/trading/tests_additional/real_exchanges/test_ascendex.py b/packages/trading/tests_additional/real_exchanges/test_ascendex.py index 220e97d0c..ebc2e7439 100644 --- a/packages/trading/tests_additional/real_exchanges/test_ascendex.py +++ b/packages/trading/tests_additional/real_exchanges/test_ascendex.py @@ -34,7 +34,7 @@ class TestAscendExRealExchangeTester(RealExchangeTester): EXCHANGE_NAME = "ascendex" SYMBOL = "BTC/USDT" SYMBOL_2 = "ETH/BTC" - SYMBOL_3 = "KAI/USDT" + SYMBOL_3 = "BTT/USDT" # CANDLE_SINCE = round(time.time() - datetime.timedelta(days = 30.5*6).total_seconds()) # now - 6 months async def test_time_frames(self): diff --git a/packages/trading/tests_additional/real_exchanges/test_binance.py b/packages/trading/tests_additional/real_exchanges/test_binance.py index b84349e3a..10946ad91 100644 --- a/packages/trading/tests_additional/real_exchanges/test_binance.py +++ b/packages/trading/tests_additional/real_exchanges/test_binance.py @@ -154,20 +154,6 @@ async def test_get_all_currencies_price_ticker(self): for symbol, ticker in tickers.items(): self._check_ticker(ticker, symbol) - async def test_get_all_currencies_price_ticker_with_market_filter(self): - tickers = await self.get_all_currencies_price_ticker(market_filter=self.get_market_filter()) - assert len(tickers) > 2 # all tickers - assert self.SYMBOL in tickers - assert self.SYMBOL_2 in tickers - assert self.SYMBOL_3 not in tickers # symbol not correctly parsed as not in available markets - tickers = await self.get_all_currencies_price_ticker( - symbols=[self.SYMBOL, self.SYMBOL_2], - market_filter=self.get_market_filter() - ) - assert list(tickers) == [self.SYMBOL, self.SYMBOL_2] # ticker for self.SYMBOL, self.SYMBOL_2 - for symbol, ticker in tickers.items(): - self._check_ticker(ticker, symbol) - @staticmethod def _check_ticker(ticker, symbol, check_content=False): assert ticker[Ectc.SYMBOL.value] == symbol diff --git a/packages/trading/tests_additional/real_exchanges/test_bingx.py b/packages/trading/tests_additional/real_exchanges/test_bingx.py index 665662e9a..df62382bf 100644 --- a/packages/trading/tests_additional/real_exchanges/test_bingx.py +++ b/packages/trading/tests_additional/real_exchanges/test_bingx.py @@ -55,7 +55,7 @@ async def _test_time_frames(self): )) async def test_active_symbols(self): - await self.inner_test_active_symbols(1300, 1900) + await self.inner_test_active_symbols(1500, 2500) async def test_get_market_status(self): for market_status in await self.get_market_statuses(): diff --git a/packages/trading/tests_additional/real_exchanges/test_bitfinex.py b/packages/trading/tests_additional/real_exchanges/test_bitfinex.py index c0f8cf263..39a0ac1de 100644 --- a/packages/trading/tests_additional/real_exchanges/test_bitfinex.py +++ b/packages/trading/tests_additional/real_exchanges/test_bitfinex.py @@ -54,7 +54,7 @@ async def test_time_frames(self): )) async def test_active_symbols(self): - await self.inner_test_active_symbols(320, 320) + await self.inner_test_active_symbols(280, 280) async def test_get_market_status(self): for market_status in await self.get_market_statuses(): diff --git a/packages/trading/tests_additional/real_exchanges/test_bitmart.py b/packages/trading/tests_additional/real_exchanges/test_bitmart.py index c4c3494c4..0e0b5854e 100644 --- a/packages/trading/tests_additional/real_exchanges/test_bitmart.py +++ b/packages/trading/tests_additional/real_exchanges/test_bitmart.py @@ -142,20 +142,6 @@ async def test_get_all_currencies_price_ticker(self): for symbol, ticker in tickers.items(): self._check_ticker(ticker, symbol) - async def test_get_all_currencies_price_ticker_with_market_filter(self): - tickers = await self.get_all_currencies_price_ticker(market_filter=self.get_market_filter()) - assert len(tickers) > 2 # all tickers - assert self.SYMBOL in tickers - assert self.SYMBOL_2 in tickers - assert self.SYMBOL_3 not in tickers - tickers = await self.get_all_currencies_price_ticker( - symbols=[self.SYMBOL, self.SYMBOL_2], - market_filter=self.get_market_filter() - ) - assert sorted(list(tickers)) == sorted([self.SYMBOL, self.SYMBOL_2]) # ticker for self.SYMBOL, self.SYMBOL_2 - for symbol, ticker in tickers.items(): - self._check_ticker(ticker, symbol) - @staticmethod def _check_ticker(ticker, symbol, check_content=False): assert ticker[Ectc.SYMBOL.value] == symbol diff --git a/packages/trading/tests_additional/real_exchanges/test_coinbase.py b/packages/trading/tests_additional/real_exchanges/test_coinbase.py index 8cd1d2fc2..cffad048d 100644 --- a/packages/trading/tests_additional/real_exchanges/test_coinbase.py +++ b/packages/trading/tests_additional/real_exchanges/test_coinbase.py @@ -29,13 +29,10 @@ class TestCoinbaseRealExchangeTester(RealExchangeTester): - # ALL require authentication ? - # https://github.com/ccxt/ccxt/issues/16719 EXCHANGE_NAME = "coinbase" SYMBOL = "BTC/USDT" SYMBOL_2 = "ETH/BTC" SYMBOL_3 = "ADA/BTC" - REQUIRES_AUTH = True # set True when even normally public apis require authentication async def test_time_frames(self): time_frames = await self.time_frames() diff --git a/packages/trading/tests_additional/real_exchanges/test_hyperliquid.py b/packages/trading/tests_additional/real_exchanges/test_hyperliquid.py index b357f0e32..854a19366 100644 --- a/packages/trading/tests_additional/real_exchanges/test_hyperliquid.py +++ b/packages/trading/tests_additional/real_exchanges/test_hyperliquid.py @@ -171,20 +171,6 @@ async def test_get_all_currencies_price_ticker(self): for symbol, ticker in tickers.items(): self._check_ticker(ticker, symbol) - async def test_get_all_currencies_price_ticker_with_market_filter(self): - tickers = await self.get_all_currencies_price_ticker(market_filter=self.get_market_filter()) - assert len(tickers) > 2 # all tickers - assert self.SYMBOL in tickers - assert self.SYMBOL_2 in tickers - assert self.SYMBOL_3 in tickers - tickers = await self.get_all_currencies_price_ticker( - symbols=[self.SYMBOL, self.SYMBOL_2], - market_filter=self.get_market_filter() - ) - assert list(tickers) == [self.SYMBOL, self.SYMBOL_2] # ticker for self.SYMBOL, self.SYMBOL_2 - for symbol, ticker in tickers.items(): - self._check_ticker(ticker, symbol) - @staticmethod def _check_ticker(ticker, symbol, check_content=False): assert ticker[Ectc.SYMBOL.value] == symbol diff --git a/packages/trading/tests_additional/real_exchanges/test_kucoin.py b/packages/trading/tests_additional/real_exchanges/test_kucoin.py index 0f3ce0dc7..fbfcf5acb 100644 --- a/packages/trading/tests_additional/real_exchanges/test_kucoin.py +++ b/packages/trading/tests_additional/real_exchanges/test_kucoin.py @@ -53,7 +53,7 @@ async def test_time_frames(self): )) async def test_active_symbols(self): - await self.inner_test_active_symbols(1200, 1200) + await self.inner_test_active_symbols(1100, 1100) async def test_get_market_status(self): for market_status in await self.get_market_statuses(): @@ -149,20 +149,6 @@ async def test_get_all_currencies_price_ticker(self): for symbol, ticker in tickers.items(): self._check_ticker(ticker, symbol) - async def test_get_all_currencies_price_ticker_with_market_filter(self): - tickers = await self.get_all_currencies_price_ticker(market_filter=self.get_market_filter()) - assert len(tickers) > 2 # all tickers - assert self.SYMBOL in tickers - assert self.SYMBOL_2 in tickers - assert self.SYMBOL_3 in tickers # symbol not correctly parsed as not in available markets (but luckily kucoin also uses the same syntax) - tickers = await self.get_all_currencies_price_ticker( - symbols=[self.SYMBOL, self.SYMBOL_2], - market_filter=self.get_market_filter() - ) - assert list(tickers) == [self.SYMBOL, self.SYMBOL_2] # ticker for self.SYMBOL, self.SYMBOL_2 - for symbol, ticker in tickers.items(): - self._check_ticker(ticker, symbol) - @staticmethod def _check_ticker(ticker, symbol, check_content=False): assert ticker[Ectc.SYMBOL.value] == symbol diff --git a/packages/trading/tests_additional/real_exchanges/test_lbank.py b/packages/trading/tests_additional/real_exchanges/test_lbank.py index 3e8f2514c..250acbfda 100644 --- a/packages/trading/tests_additional/real_exchanges/test_lbank.py +++ b/packages/trading/tests_additional/real_exchanges/test_lbank.py @@ -144,20 +144,6 @@ async def test_get_all_currencies_price_ticker(self): for symbol, ticker in tickers.items(): self._check_ticker(ticker, symbol) - async def test_get_all_currencies_price_ticker_with_market_filter(self): - tickers = await self.get_all_currencies_price_ticker(market_filter=self.get_market_filter()) - assert len(tickers) > 2 # all tickers - assert self.SYMBOL in tickers - assert self.SYMBOL_2 in tickers - assert self.SYMBOL_3 not in tickers # symbol not correctly parsed as not in available markets - tickers = await self.get_all_currencies_price_ticker( - symbols=[self.SYMBOL, self.SYMBOL_2], - market_filter=self.get_market_filter() - ) - assert list(tickers) == [self.SYMBOL, self.SYMBOL_2] # ticker for self.SYMBOL, self.SYMBOL_2 - for symbol, ticker in tickers.items(): - self._check_ticker(ticker, symbol) - @staticmethod def _check_ticker(ticker, symbol, check_content=False): assert ticker[Ectc.SYMBOL.value] == symbol diff --git a/packages/trading/tests_additional/real_exchanges/test_mexc.py b/packages/trading/tests_additional/real_exchanges/test_mexc.py index 80c2be6c9..2ad9e58be 100644 --- a/packages/trading/tests_additional/real_exchanges/test_mexc.py +++ b/packages/trading/tests_additional/real_exchanges/test_mexc.py @@ -138,20 +138,6 @@ async def test_get_all_currencies_price_ticker(self): for symbol, ticker in tickers.items(): self._check_ticker(ticker, symbol) - async def test_get_all_currencies_price_ticker_with_market_filter(self): - tickers = await self.get_all_currencies_price_ticker(market_filter=self.get_market_filter()) - assert len(tickers) > 2 # all tickers - assert self.SYMBOL in tickers - assert self.SYMBOL_2 in tickers - assert self.SYMBOL_3 not in tickers # symbol not correctly parsed as not in available markets - tickers = await self.get_all_currencies_price_ticker( - symbols=[self.SYMBOL, self.SYMBOL_2], - market_filter=self.get_market_filter() - ) - assert sorted(list(tickers)) == sorted([self.SYMBOL, self.SYMBOL_2]) # ticker for self.SYMBOL, self.SYMBOL_2 - for symbol, ticker in tickers.items(): - self._check_ticker(ticker, symbol) - @staticmethod def _check_ticker(ticker, symbol, check_content=False): assert ticker[Ectc.SYMBOL.value] == symbol diff --git a/packages/trading/tests_additional/real_exchanges/test_myokx.py b/packages/trading/tests_additional/real_exchanges/test_myokx.py index 36babc005..76a997f6c 100644 --- a/packages/trading/tests_additional/real_exchanges/test_myokx.py +++ b/packages/trading/tests_additional/real_exchanges/test_myokx.py @@ -35,17 +35,3 @@ class TestMyOkxRealExchangeTester(test_okx.TestOkxRealExchangeTester): # myokx overrides async def test_active_symbols(self): await self.inner_test_active_symbols(2100, 2200) - - async def test_get_all_currencies_price_ticker_with_market_filter(self): - tickers = await self.get_all_currencies_price_ticker(market_filter=self.get_market_filter()) - assert len(tickers) > 2 # all tickers - assert self.SYMBOL in tickers - assert self.SYMBOL_2 in tickers - assert self.SYMBOL_3 not in tickers # symbol not correctly parsed as not in available markets - tickers = await self.get_all_currencies_price_ticker( - symbols=[self.SYMBOL, self.SYMBOL_2], - market_filter=self.get_market_filter() - ) - assert list(tickers) == [self.SYMBOL, self.SYMBOL_2] # ticker for self.SYMBOL, self.SYMBOL_2 - for symbol, ticker in tickers.items(): - self._check_ticker(ticker, symbol) diff --git a/packages/trading/tests_additional/real_exchanges/test_okx.py b/packages/trading/tests_additional/real_exchanges/test_okx.py index 88fa33dc6..e18278a1b 100644 --- a/packages/trading/tests_additional/real_exchanges/test_okx.py +++ b/packages/trading/tests_additional/real_exchanges/test_okx.py @@ -151,20 +151,6 @@ async def test_get_all_currencies_price_ticker(self): for symbol, ticker in tickers.items(): self._check_ticker(ticker, symbol) - async def test_get_all_currencies_price_ticker_with_market_filter(self): - tickers = await self.get_all_currencies_price_ticker(market_filter=self.get_market_filter()) - assert len(tickers) > 2 # all tickers - assert self.SYMBOL in tickers - assert self.SYMBOL_2 in tickers - assert self.SYMBOL_3 in tickers # symbol not correctly parsed as not in available markets (but luckily okx also uses the same syntax) - tickers = await self.get_all_currencies_price_ticker( - symbols=[self.SYMBOL, self.SYMBOL_2], - market_filter=self.get_market_filter() - ) - assert list(tickers) == [self.SYMBOL, self.SYMBOL_2] # ticker for self.SYMBOL, self.SYMBOL_2 - for symbol, ticker in tickers.items(): - self._check_ticker(ticker, symbol) - @staticmethod def _check_ticker(ticker, symbol, check_content=False): assert ticker[Ectc.SYMBOL.value] == symbol diff --git a/packages/trading/tests_additional/real_exchanges/test_okxus.py b/packages/trading/tests_additional/real_exchanges/test_okxus.py index ce691e386..08bee1e75 100644 --- a/packages/trading/tests_additional/real_exchanges/test_okxus.py +++ b/packages/trading/tests_additional/real_exchanges/test_okxus.py @@ -35,17 +35,3 @@ class TestOkxUsRealExchangeTester(test_okx.TestOkxRealExchangeTester): # okxus overrides async def test_active_symbols(self): await self.inner_test_active_symbols(2100, 2200) - - async def test_get_all_currencies_price_ticker_with_market_filter(self): - tickers = await self.get_all_currencies_price_ticker(market_filter=self.get_market_filter()) - assert len(tickers) > 2 # all tickers - assert self.SYMBOL in tickers - assert self.SYMBOL_2 in tickers - assert self.SYMBOL_3 not in tickers # symbol not correctly parsed as not in available markets - tickers = await self.get_all_currencies_price_ticker( - symbols=[self.SYMBOL, self.SYMBOL_2], - market_filter=self.get_market_filter() - ) - assert list(tickers) == [self.SYMBOL, self.SYMBOL_2] # ticker for self.SYMBOL, self.SYMBOL_2 - for symbol, ticker in tickers.items(): - self._check_ticker(ticker, symbol) diff --git a/packages/trading/tests_additional/real_exchanges/test_poloniex.py b/packages/trading/tests_additional/real_exchanges/test_poloniex.py index 5950e53d3..40ca59958 100644 --- a/packages/trading/tests_additional/real_exchanges/test_poloniex.py +++ b/packages/trading/tests_additional/real_exchanges/test_poloniex.py @@ -46,7 +46,7 @@ async def test_time_frames(self): )) async def test_active_symbols(self): - await self.inner_test_active_symbols(900, 900) + await self.inner_test_active_symbols(800, 800) async def test_get_market_status(self): for market_status in await self.get_market_statuses():