diff --git a/additional_tests/exchanges_tests/abstract_authenticated_exchange_tester.py b/additional_tests/exchanges_tests/abstract_authenticated_exchange_tester.py index 6c737e20d..d318ad943 100644 --- a/additional_tests/exchanges_tests/abstract_authenticated_exchange_tester.py +++ b/additional_tests/exchanges_tests/abstract_authenticated_exchange_tester.py @@ -110,13 +110,14 @@ async def test_get_portfolio_with_market_filter(self): # check portfolio fetched with filtered markets (should be equal to the one with all markets) filtered_markets_portfolio = await self.get_portfolio() if self.EXPECT_BALANCE_FILTER_BY_MARKET_STATUS: - assert filtered_markets_portfolio == { + filtered = { key: val for key, val in all_markets_portfolio.items() if key in symbols.parse_symbol(self.SYMBOL).base_and_quote() } + assert filtered_markets_portfolio == filtered, f"{filtered_markets_portfolio=} != {filtered=}" else: - assert filtered_markets_portfolio == all_markets_portfolio + assert filtered_markets_portfolio == all_markets_portfolio, f"{filtered_markets_portfolio=} != {all_markets_portfolio=}" async def inner_test_get_portfolio(self): self.check_portfolio_content(await self.get_portfolio()) diff --git a/additional_tests/exchanges_tests/test_binance_futures.py b/additional_tests/exchanges_tests/test_binance_futures.py index d4e26b8fb..57cc09cde 100644 --- a/additional_tests/exchanges_tests/test_binance_futures.py +++ b/additional_tests/exchanges_tests/test_binance_futures.py @@ -28,7 +28,7 @@ class TestBinanceFuturesAuthenticatedExchange( # enter exchange name as a class variable here EXCHANGE_NAME = "binance" CREDENTIALS_EXCHANGE_NAME = "BINANCE_FUTURES" - ORDER_CURRENCY = "BTC" + ORDER_CURRENCY = "BTC" # always use a contract that has a size different from 1 unit of the currency SETTLEMENT_CURRENCY = "USDC" SYMBOL = f"{ORDER_CURRENCY}/{SETTLEMENT_CURRENCY}:{SETTLEMENT_CURRENCY}" INVERSE_SYMBOL = f"{ORDER_CURRENCY}/USD:{ORDER_CURRENCY}" @@ -46,8 +46,7 @@ async def test_get_portfolio(self): await super().test_get_portfolio() async def test_get_portfolio_with_market_filter(self): - # pass if not implemented - pass + await super().test_get_portfolio_with_market_filter() # can have small variations failing the test when positions are open async def test_get_account_id(self): await super().test_get_account_id() @@ -59,8 +58,7 @@ async def test_invalid_api_key_error(self): await super().test_invalid_api_key_error() async def test_get_api_key_permissions(self): - # pass if not implemented - pass + await super().test_get_api_key_permissions() async def test_missing_trading_api_key_permissions(self): pass diff --git a/additional_tests/exchanges_tests/test_kucoin_futures.py b/additional_tests/exchanges_tests/test_kucoin_futures.py index 781259d94..a26b66a5d 100644 --- a/additional_tests/exchanges_tests/test_kucoin_futures.py +++ b/additional_tests/exchanges_tests/test_kucoin_futures.py @@ -27,24 +27,25 @@ class TestKucoinFuturesAuthenticatedExchange( # enter exchange name as a class variable here EXCHANGE_NAME = "kucoin" CREDENTIALS_EXCHANGE_NAME = "KUCOIN_FUTURES" - ORDER_CURRENCY = "DOT" # DOT to allow for smaller orders + ORDER_CURRENCY = "SOL" # always use a contract that has a size different from 1 unit of the currency SETTLEMENT_CURRENCY = "USDT" SYMBOL = f"{ORDER_CURRENCY}/{SETTLEMENT_CURRENCY}:{SETTLEMENT_CURRENCY}" INVERSE_SYMBOL = f"{ORDER_CURRENCY}/USD:{ORDER_CURRENCY}" - ORDER_SIZE = 10 # % of portfolio to include in test orders + ORDER_SIZE = 5 # % of portfolio to include in test orders SUPPORTS_GET_LEVERAGE = False SUPPORTS_SET_LEVERAGE = False USE_ORDER_OPERATION_TO_CHECK_API_KEY_RIGHTS = True VALID_ORDER_ID = "6617e84c5c1e0000083c71f7" EXPECT_MISSING_FEE_IN_CANCELLED_ORDERS = False IS_AUTHENTICATED_REQUEST_CHECK_AVAILABLE = True # set True when is_authenticated_request is implemented + EXPECTED_QUOTE_MIN_ORDER_SIZE = 40 + EXPECT_BALANCE_FILTER_BY_MARKET_STATUS = True async def test_get_portfolio(self): await super().test_get_portfolio() async def test_get_portfolio_with_market_filter(self): - # pass if not implemented - pass + await super().test_get_portfolio_with_market_filter() # can have small variations failing the test when positions are open async def test_get_account_id(self): await super().test_get_account_id() diff --git a/octobot/community/__init__.py b/octobot/community/__init__.py index 4c0fd2df7..f2a9c50fd 100644 --- a/octobot/community/__init__.py +++ b/octobot/community/__init__.py @@ -33,6 +33,7 @@ StrategyData, get_exchange_type_from_availability, to_bot_exchange_internal_name, + get_exchange_type_from_internal_name, to_community_exchange_internal_name, ) from octobot.community.supabase_backend import ( @@ -110,6 +111,7 @@ "StrategyData", "get_exchange_type_from_availability", "to_bot_exchange_internal_name", + "get_exchange_type_from_internal_name", "to_community_exchange_internal_name", "SyncConfigurationStorage", "ASyncConfigurationStorage", diff --git a/octobot/community/models/__init__.py b/octobot/community/models/__init__.py index 7f0057c4e..7a8a1e5ab 100644 --- a/octobot/community/models/__init__.py +++ b/octobot/community/models/__init__.py @@ -48,6 +48,7 @@ format_portfolio_with_profitability, get_exchange_type_from_availability, to_bot_exchange_internal_name, + get_exchange_type_from_internal_name, to_community_exchange_internal_name, ) from octobot.community.models.community_public_data import ( @@ -71,6 +72,7 @@ "format_portfolio_with_profitability", "get_exchange_type_from_availability", "to_bot_exchange_internal_name", + "get_exchange_type_from_internal_name", "to_community_exchange_internal_name", "CommunityPublicData", "StrategyData", diff --git a/octobot/community/models/formatters.py b/octobot/community/models/formatters.py index a9f597e9c..e7bff3f88 100644 --- a/octobot/community/models/formatters.py +++ b/octobot/community/models/formatters.py @@ -121,6 +121,8 @@ def format_orders(orders: list, exchange_name: str) -> list: ), backend_enums.OrderKeys.QUANTITY.value: storage_order[trading_constants.STORAGE_ORIGIN_VALUE][ trading_enums.ExchangeConstantsOrderColumns.AMOUNT.value], + backend_enums.OrderKeys.SIDE.value: storage_order[trading_constants.STORAGE_ORIGIN_VALUE][ + trading_enums.ExchangeConstantsOrderColumns.SIDE.value], backend_enums.OrderKeys.EXCHANGE_ID.value: storage_order[trading_constants.STORAGE_ORIGIN_VALUE][ trading_enums.ExchangeConstantsOrderColumns.EXCHANGE_ID.value], backend_enums.OrderKeys.CHAINED.value: format_orders( @@ -155,6 +157,12 @@ def to_bot_exchange_internal_name(community_exchange_internal_name: str) -> str: return community_exchange_internal_name +def get_exchange_type_from_internal_name(community_exchange_internal_name: str) -> str: + if community_exchange_internal_name.endswith(FUTURES_INTERNAL_NAME_SUFFIX): + return commons_constants.CONFIG_EXCHANGE_FUTURE + return commons_constants.CONFIG_EXCHANGE_SPOT + + def get_exchange_type_from_availability(exchange_availability: dict) -> str: if not exchange_availability: # use spot by default diff --git a/octobot/community/supabase_backend/enums.py b/octobot/community/supabase_backend/enums.py index b6bc56230..2c7dcfa84 100644 --- a/octobot/community/supabase_backend/enums.py +++ b/octobot/community/supabase_backend/enums.py @@ -172,6 +172,7 @@ class OrderKeys(enum.Enum): SYMBOL = "symbol" TYPE = "type" CHAINED = "chained" + SIDE = "side" class PositionKeys(enum.Enum): diff --git a/requirements.txt b/requirements.txt index 3cc527046..b5d646de9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ # Drakkar-Software requirements OctoBot-Commons==1.9.70 -OctoBot-Trading==2.4.133 +OctoBot-Trading==2.4.140 OctoBot-Evaluators==1.9.7 OctoBot-Tentacles-Manager==2.9.16 OctoBot-Services==1.6.21