Skip to content

Commit

Permalink
Merge pull request #2597 from Drakkar-Software/dev
Browse files Browse the repository at this point in the history
Dev merge
  • Loading branch information
GuillaumeDSM authored Apr 16, 2024
2 parents 9a322be + 64de001 commit ea2973f
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import decimal
import time

import mock
import pytest

import octobot_commons.constants as constants
Expand Down Expand Up @@ -73,6 +74,9 @@ class AbstractAuthenticatedExchangeTester:
MIN_TRADE_USD_VALUE = decimal.Decimal("0.1")
IS_ACCOUNT_ID_AVAILABLE = True # set False when get_account_id is not available and should be checked
EXPECTED_GENERATED_ACCOUNT_ID = False # set True when account_id can't be fetch and a generated account id is used
USE_ORDER_OPERATION_TO_CHECK_API_KEY_RIGHTS = False # set True when api key rights can't be checked using a
# dedicated api and have to be checked by sending an order operation
EXPECTED_INVALID_ORDERS_QUANTITY = [] # orders with known invalid quantity exchange order id (usually legacy)

# Implement all "test_[name]" methods, call super() to run the test, pass to ignore it.
# Override the "inner_test_[name]" method to override a test content.
Expand Down Expand Up @@ -135,11 +139,22 @@ async def test_get_api_key_permissions(self):
await self.inner_test_get_api_key_permissions()

async def inner_test_get_api_key_permissions(self):
permissions = await self.exchange_manager.exchange_backend._get_api_key_rights()
assert len(permissions) > 0
assert trading_backend.enums.APIKeyRights.READING in permissions
assert trading_backend.enums.APIKeyRights.SPOT_TRADING in permissions
assert trading_backend.enums.APIKeyRights.FUTURES_TRADING in permissions
origin_get_api_key_rights_using_order = self.exchange_manager.exchange_backend._get_api_key_rights_using_order
with mock.patch.object(
self.exchange_manager.exchange_backend,
"_get_api_key_rights_using_order", mock.AsyncMock(side_effect=origin_get_api_key_rights_using_order)
) as _get_api_key_rights_using_order_mock:
permissions = await self.exchange_manager.exchange_backend._get_api_key_rights()
assert len(permissions) > 0
assert trading_backend.enums.APIKeyRights.READING in permissions
assert trading_backend.enums.APIKeyRights.SPOT_TRADING in permissions
assert trading_backend.enums.APIKeyRights.FUTURES_TRADING in permissions
if self.USE_ORDER_OPERATION_TO_CHECK_API_KEY_RIGHTS:
# failed ? did not use _get_api_key_rights_using_order while expected
_get_api_key_rights_using_order_mock.assert_called_once()
else:
# failed ? used _get_api_key_rights_using_order when not expected
_get_api_key_rights_using_order_mock.assert_not_called()

async def test_get_not_found_order(self):
async with self.local_exchange_manager():
Expand Down Expand Up @@ -495,7 +510,7 @@ async def _get_bundled_orders_stop_take_profit(self, current_price):
)

async def get_portfolio(self):
return await exchanges_test_tools.get_portfolio(self.exchange_manager, as_float=False)
return await exchanges_test_tools.get_portfolio(self.exchange_manager, as_float=False, clear_empty=False)

async def get_my_recent_trades(self, exchange_data=None):
exchange_data = exchange_data or self.get_exchange_data()
Expand Down Expand Up @@ -571,9 +586,17 @@ def check_parsed_closed_order(
if self.OPEN_ORDERS_IN_CLOSED_ORDERS and order.status is trading_enums.OrderStatus.OPEN:
# when order is open, cost is not full
return
self.check_theoretical_cost(
symbols.parse_symbol(order.symbol), order.origin_quantity, order.origin_price, order.total_cost
)
if order.exchange_order_id in self.EXPECTED_INVALID_ORDERS_QUANTITY:
with pytest.raises(AssertionError):
self.check_theoretical_cost(
symbols.parse_symbol(order.symbol), order.origin_quantity,
order.origin_price, order.total_cost
)
else:
self.check_theoretical_cost(
symbols.parse_symbol(order.symbol), order.origin_quantity,
order.origin_price, order.total_cost
)
if "USD" in order.market:
assert self.MIN_TRADE_USD_VALUE < order.total_cost < self.MAX_TRADE_USD_VALUE

Expand Down
5 changes: 5 additions & 0 deletions additional_tests/exchanges_tests/test_binance.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ class TestBinanceAuthenticatedExchange(
ORDER_SIZE = 50 # % of portfolio to include in test orders
DUPLICATE_TRADES_RATIO = 0.1 # allow 10% duplicate in trades (due to trade id set to order id)
VALID_ORDER_ID = "26408108410"
EXPECTED_INVALID_ORDERS_QUANTITY = [
# for some reason these orders from 2021 are broken
'7457313043',
'7457370420',
]

async def test_get_portfolio(self):
await super().test_get_portfolio()
Expand Down
1 change: 1 addition & 0 deletions additional_tests/exchanges_tests/test_bingx.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class TestBingxAuthenticatedExchange(
ORDER_SIZE = 50 # % of portfolio to include in test orders
CONVERTS_ORDER_SIZE_BEFORE_PUSHING_TO_EXCHANGES = True
IGNORE_EXCHANGE_TRADE_ID = True
USE_ORDER_OPERATION_TO_CHECK_API_KEY_RIGHTS = True
VALID_ORDER_ID = "1777764898965454838"

async def test_get_portfolio(self):
Expand Down
29 changes: 29 additions & 0 deletions additional_tests/exchanges_tests/test_coinbase_legacy_api_key.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# This file is part of OctoBot (https://github.com/Drakkar-Software/OctoBot)
# Copyright (c) 2023 Drakkar-Software, All rights reserved.
#
# OctoBot is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either
# version 3.0 of the License, or (at your option) any later version.
#
# OctoBot is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with OctoBot. If not, see <https://www.gnu.org/licenses/>.
import pytest

from additional_tests.exchanges_tests import test_coinbase

# All test coroutines will be treated as marked.
pytestmark = pytest.mark.asyncio


class TestCoinbaseLegacyAPIKeyAuthenticatedExchange(
test_coinbase.TestCoinbaseAuthenticatedExchange
):
# same as regular coinbase exchange test except that it is using the legacy api key format
# (before organizations/ and -----BEGIN EC PRIVATE)
CREDENTIALS_EXCHANGE_NAME = "coinbase_legacy_api_key"
2 changes: 1 addition & 1 deletion additional_tests/exchanges_tests/test_cryptocom.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class TestCryptoComAuthenticatedExchange(
SETTLEMENT_CURRENCY = "USDT"
SYMBOL = f"{ORDER_CURRENCY}/{SETTLEMENT_CURRENCY}"
ORDER_SIZE = 20 # % of portfolio to include in test orders
VALID_ORDER_ID = "1777764898965454848" #todo
VALID_ORDER_ID = "1777764898965454848"

async def test_get_portfolio(self):
await super().test_get_portfolio()
Expand Down
3 changes: 2 additions & 1 deletion additional_tests/exchanges_tests/test_kucoin.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ class TestKucoinAuthenticatedExchange(
SETTLEMENT_CURRENCY = "USDT"
SYMBOL = f"{ORDER_CURRENCY}/{SETTLEMENT_CURRENCY}"
ORDER_SIZE = 50 # % of portfolio to include in test orders
EXPECTED_GENERATED_ACCOUNT_ID = True
EXPECTED_GENERATED_ACCOUNT_ID = False # True when subaccounts are created
USE_ORDER_OPERATION_TO_CHECK_API_KEY_RIGHTS = True
VALID_ORDER_ID = "6617e84c5c1e0000083c71f7"

async def test_get_portfolio(self):
Expand Down
5 changes: 3 additions & 2 deletions additional_tests/exchanges_tests/test_kucoin_futures.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,14 @@ class TestKucoinFuturesAuthenticatedExchange(
# enter exchange name as a class variable here
EXCHANGE_NAME = "kucoin"
CREDENTIALS_EXCHANGE_NAME = "KUCOIN_FUTURES"
ORDER_CURRENCY = "ETH" # ETH to allow for smaller orders
ORDER_CURRENCY = "DOT" # DOT to allow for smaller orders
SETTLEMENT_CURRENCY = "USDT"
SYMBOL = f"{ORDER_CURRENCY}/{SETTLEMENT_CURRENCY}:{SETTLEMENT_CURRENCY}"
INVERSE_SYMBOL = f"{ORDER_CURRENCY}/USD:{ORDER_CURRENCY}"
ORDER_SIZE = 90 # % of portfolio to include in test orders
ORDER_SIZE = 10 # % 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"

async def test_get_portfolio(self):
Expand Down
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Drakkar-Software requirements
OctoBot-Commons==1.9.43
OctoBot-Trading==2.4.77
OctoBot-Trading==2.4.78
OctoBot-Evaluators==1.9.5
OctoBot-Tentacles-Manager==2.9.10
OctoBot-Services==1.6.13
OctoBot-Backtesting==1.9.7
Async-Channel==2.2.1
trading-backend==1.2.16
trading-backend==1.2.18

## Others
colorlog==6.8.0
Expand Down

0 comments on commit ea2973f

Please sign in to comment.