Skip to content

Commit

Permalink
Merge pull request #2860 from Drakkar-Software/dev
Browse files Browse the repository at this point in the history
Dev merge
  • Loading branch information
GuillaumeDSM authored Jan 14, 2025
2 parents a4e5d56 + a9d7fe6 commit 29c43c1
Show file tree
Hide file tree
Showing 33 changed files with 603 additions and 92 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
# License along with OctoBot. If not, see <https://www.gnu.org/licenses/>.
import contextlib
import decimal
import ccxt
import pytest

import octobot_trading.enums as trading_enums
import octobot_trading.constants as trading_constants
import octobot_trading.errors as trading_errors
import trading_backend.enums
from additional_tests.exchanges_tests import abstract_authenticated_exchange_tester


Expand All @@ -33,7 +33,6 @@ class AbstractAuthenticatedFutureExchangeTester(
INVERSE_SYMBOL = None
MIN_PORTFOLIO_SIZE = 2 # ensure fetching currency for linear and inverse
SUPPORTS_GET_LEVERAGE = True
SUPPORTS_SET_LEVERAGE = True
SUPPORTS_EMPTY_POSITION_SET_MARGIN_TYPE = True

async def test_get_empty_linear_and_inverse_positions(self):
Expand Down Expand Up @@ -85,9 +84,12 @@ async def inner_test_get_and_set_leverage(self):
assert origin_leverage != trading_constants.ZERO
if self.SUPPORTS_GET_LEVERAGE:
assert origin_leverage == await self.get_leverage()
if not self.SUPPORTS_SET_LEVERAGE:
return
new_leverage = origin_leverage + 1
if not self.exchange_manager.exchange.UPDATE_LEVERAGE_FROM_API:
# can't set from api: make sure of that
with pytest.raises(trading_errors.NotSupported):
await self.exchange_manager.exchange.connector.set_symbol_leverage(self.SYMBOL, float(new_leverage))
return
await self.set_leverage(new_leverage)
await self._check_margin_type_and_leverage(origin_margin_type, new_leverage) # did not change margin type
# change leverage back to origin value
Expand Down Expand Up @@ -190,6 +192,10 @@ async def _inner_test_create_and_cancel_limit_orders_for_margin_type(
symbol=self.INVERSE_SYMBOL, settlement_currency=self.ORDER_CURRENCY, margin_type=margin_type
)

def _ensure_required_permissions(self, permissions):
super()._ensure_required_permissions(permissions)
assert trading_backend.enums.APIKeyRights.FUTURES_TRADING in permissions

async def inner_test_create_and_fill_market_orders(self):
portfolio = await self.get_portfolio()
position = await self.get_position()
Expand Down
6 changes: 6 additions & 0 deletions additional_tests/exchanges_tests/test_ascendex.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ async def test_get_portfolio_with_market_filter(self):
# pass if not implemented
pass

async def test_untradable_symbols(self):
await super().test_untradable_symbols()

async def test_get_account_id(self):
# pass if not implemented
pass
Expand All @@ -63,6 +66,9 @@ async def test_get_not_found_order(self):
async def test_is_valid_account(self):
await super().test_is_valid_account()

async def test_get_special_orders(self):
await super().test_get_special_orders()

async def test_create_and_cancel_limit_orders(self):
await super().test_create_and_cancel_limit_orders()

Expand Down
39 changes: 39 additions & 0 deletions additional_tests/exchanges_tests/test_binance.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
# 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
import octobot_trading.enums

from additional_tests.exchanges_tests import abstract_authenticated_exchange_tester

Expand Down Expand Up @@ -41,13 +42,48 @@ class TestBinanceAuthenticatedExchange(
IS_BROKER_ENABLED_ACCOUNT = False
IS_AUTHENTICATED_REQUEST_CHECK_AVAILABLE = True # set True when is_authenticated_request is implemented

SPECIAL_ORDER_TYPES_BY_EXCHANGE_ID: dict[
str, (
str, # symbol
str, # order type key in 'info' dict
str, # order type found in 'info' dict
str, # parsed trading_enums.TradeOrderType
str, # parsed trading_enums.TradeOrderSide
bool, # trigger above (on higher price than order price)
)
] = {
"6799804660": (
"BNB/USDT", "type", "TAKE_PROFIT",
octobot_trading.enums.TradeOrderType.LIMIT.value, octobot_trading.enums.TradeOrderSide.SELL.value, True
),
'6799810041': (
"BNB/USDT", "type", "STOP_LOSS",
octobot_trading.enums.TradeOrderType.STOP_LOSS.value, octobot_trading.enums.TradeOrderSide.SELL.value, False
),
'6799798838': (
"BNB/USDT", "type", "TAKE_PROFIT_LIMIT",
octobot_trading.enums.TradeOrderType.LIMIT.value, octobot_trading.enums.TradeOrderSide.SELL.value, True
),
'6799795001': (
"BNB/USDT", "type", "STOP_LOSS_LIMIT",
octobot_trading.enums.TradeOrderType.STOP_LOSS.value, octobot_trading.enums.TradeOrderSide.SELL.value, False
),
} # stop loss / take profit and other special order types to be successfully parsed
# details of an order that exists but can"t be cancelled
UNCANCELLABLE_ORDER_ID_SYMBOL_TYPE: tuple[str, str, octobot_trading.enums.TraderOrderType] = (
"6799798838", "BNB/USDT", octobot_trading.enums.TraderOrderType.BUY_LIMIT.value
)


async def test_get_portfolio(self):
await super().test_get_portfolio()

async def test_get_portfolio_with_market_filter(self):
await super().test_get_portfolio_with_market_filter()

async def test_untradable_symbols(self):
await super().test_untradable_symbols()

async def test_get_account_id(self):
await super().test_get_account_id()

Expand All @@ -69,6 +105,9 @@ async def test_get_not_found_order(self):
async def test_is_valid_account(self):
await super().test_is_valid_account()

async def test_get_special_orders(self):
await super().test_get_special_orders()

async def test_create_and_cancel_limit_orders(self):
await super().test_create_and_cancel_limit_orders()

Expand Down
39 changes: 39 additions & 0 deletions additional_tests/exchanges_tests/test_binance_futures.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
# License along with OctoBot. If not, see <https://www.gnu.org/licenses/>.
import pytest

import octobot_trading.enums
from additional_tests.exchanges_tests import abstract_authenticated_future_exchange_tester, \
abstract_authenticated_exchange_tester

Expand All @@ -38,6 +39,38 @@ class TestBinanceFuturesAuthenticatedExchange(
EXPECTED_QUOTE_MIN_ORDER_SIZE = 200 # min quote value of orders to create (used to check market status parsing)
IS_AUTHENTICATED_REQUEST_CHECK_AVAILABLE = True # set True when is_authenticated_request is implemented

SPECIAL_ORDER_TYPES_BY_EXCHANGE_ID: dict[
str, (
str, # symbol
str, # order type key in 'info' dict
str, # order type found in 'info' dict
str, # parsed trading_enums.TradeOrderType
str, # parsed trading_enums.TradeOrderSide
bool, # trigger above (on higher price than order price)
)
] = {
"4075521283": (
"BTC/USDT:USDT", "type", "TAKE_PROFIT_MARKET",
octobot_trading.enums.TradeOrderType.LIMIT.value, octobot_trading.enums.TradeOrderSide.SELL.value, True
),
'622529': (
"BTC/USDC:USDC", "type", "STOP_MARKET",
octobot_trading.enums.TradeOrderType.STOP_LOSS.value, octobot_trading.enums.TradeOrderSide.SELL.value, False
),
'4076521927': (
"BTC/USDT:USDT", "type", "TAKE_PROFIT",
octobot_trading.enums.TradeOrderType.LIMIT.value, octobot_trading.enums.TradeOrderSide.BUY.value, False
),
'4076521976': (
"BTC/USDT:USDT", "type", "STOP",
octobot_trading.enums.TradeOrderType.STOP_LOSS.value, octobot_trading.enums.TradeOrderSide.SELL.value, False
),
} # stop loss / take profit and other special order types to be successfully parsed
# details of an order that exists but can"t be cancelled
UNCANCELLABLE_ORDER_ID_SYMBOL_TYPE: tuple[str, str, octobot_trading.enums.TraderOrderType] = (
"4076521927", "BTC/USDT:USDT", octobot_trading.enums.TraderOrderType.BUY_LIMIT.value
)

async def _set_account_types(self, account_types):
# todo remove this and use both types when exchange-side multi portfolio is enabled
self.exchange_manager.exchange._futures_account_types = account_types
Expand All @@ -48,6 +81,9 @@ async def test_get_portfolio(self):
async def test_get_portfolio_with_market_filter(self):
await super().test_get_portfolio_with_market_filter() # can have small variations failing the test when positions are open

async def test_untradable_symbols(self):
await super().test_untradable_symbols()

async def test_get_account_id(self):
await super().test_get_account_id()

Expand Down Expand Up @@ -86,6 +122,9 @@ async def test_get_and_set_leverage(self):
async def test_is_valid_account(self):
await super().test_is_valid_account()

async def test_get_special_orders(self):
await super().test_get_special_orders()

async def test_create_and_cancel_limit_orders(self):
await super().test_create_and_cancel_limit_orders()

Expand Down
39 changes: 39 additions & 0 deletions additional_tests/exchanges_tests/test_bingx.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
# 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
import octobot_trading.enums

from additional_tests.exchanges_tests import abstract_authenticated_exchange_tester

Expand All @@ -38,12 +39,47 @@ class TestBingxAuthenticatedExchange(

VALID_ORDER_ID = "1812980957928929280"

SPECIAL_ORDER_TYPES_BY_EXCHANGE_ID: dict[
str, (
str, # symbol
str, # order type key in 'info' dict
str, # order type found in 'info' dict
str, # parsed trading_enums.TradeOrderType
str, # parsed trading_enums.TradeOrderSide
bool, # trigger above (on higher price than order price)
)
] = {
"1877004154170146816": (
"TAO/USDT", "type", "TAKE_STOP_MARKET",
octobot_trading.enums.TradeOrderType.STOP_LOSS.value, octobot_trading.enums.TradeOrderSide.SELL.value, False
),
'1877004191864356864': (
"TAO/USDT", "type", "TAKE_STOP_MARKET",
octobot_trading.enums.TradeOrderType.LIMIT.value, octobot_trading.enums.TradeOrderSide.SELL.value, True
),
'1877004220704391168': (
"TAO/USDT", "type", "TAKE_STOP_LIMIT",
octobot_trading.enums.TradeOrderType.UNSUPPORTED.value, octobot_trading.enums.TradeOrderSide.SELL.value, None
),
'1877004292053696512': (
"TAO/USDT", "type", "TAKE_STOP_LIMIT",
octobot_trading.enums.TradeOrderType.UNSUPPORTED.value, octobot_trading.enums.TradeOrderSide.SELL.value, None
),
} # stop loss / take profit and other special order types to be successfully parsed
# details of an order that exists but can"t be cancelled
UNCANCELLABLE_ORDER_ID_SYMBOL_TYPE: tuple[str, str, octobot_trading.enums.TraderOrderType] = (
"1877004292053696512", "TAO/USDT", octobot_trading.enums.TraderOrderType.SELL_LIMIT.value
)

async def test_get_portfolio(self):
await super().test_get_portfolio()

async def test_get_portfolio_with_market_filter(self):
await super().test_get_portfolio_with_market_filter()

async def test_untradable_symbols(self):
await super().test_untradable_symbols()

async def test_get_account_id(self):
await super().test_get_account_id()

Expand All @@ -65,6 +101,9 @@ async def test_get_not_found_order(self):
async def test_is_valid_account(self):
await super().test_is_valid_account()

async def test_get_special_orders(self):
await super().test_get_special_orders()

async def test_create_and_cancel_limit_orders(self):
await super().test_create_and_cancel_limit_orders()

Expand Down
6 changes: 6 additions & 0 deletions additional_tests/exchanges_tests/test_bitget.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ async def test_get_portfolio_with_market_filter(self):
# pass if not implemented
pass

async def test_untradable_symbols(self):
await super().test_untradable_symbols()

async def test_get_account_id(self):
# pass if not implemented
pass
Expand All @@ -65,6 +68,9 @@ async def test_get_not_found_order(self):
async def test_is_valid_account(self):
await super().test_is_valid_account()

async def test_get_special_orders(self):
await super().test_get_special_orders()

async def test_create_and_cancel_limit_orders(self):
await super().test_create_and_cancel_limit_orders()

Expand Down
6 changes: 6 additions & 0 deletions additional_tests/exchanges_tests/test_bitmart.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ async def test_get_portfolio(self):
async def test_get_portfolio_with_market_filter(self):
await super().test_get_portfolio_with_market_filter()

async def test_untradable_symbols(self):
await super().test_untradable_symbols()

async def test_get_account_id(self):
# pass if not implemented
pass
Expand All @@ -63,6 +66,9 @@ async def test_get_not_found_order(self):
async def test_is_valid_account(self):
await super().test_is_valid_account()

async def test_get_special_orders(self):
await super().test_get_special_orders()

async def test_create_and_cancel_limit_orders(self):
await super().test_create_and_cancel_limit_orders()

Expand Down
6 changes: 6 additions & 0 deletions additional_tests/exchanges_tests/test_bybit.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ async def test_get_portfolio_with_market_filter(self):
# pass if not implemented
pass

async def test_untradable_symbols(self):
await super().test_untradable_symbols()

async def test_get_account_id(self):
# pass if not implemented
pass
Expand All @@ -67,6 +70,9 @@ async def test_get_not_found_order(self):
async def test_is_valid_account(self):
await super().test_is_valid_account()

async def test_get_special_orders(self):
await super().test_get_special_orders()

async def test_create_and_cancel_limit_orders(self):
await super().test_create_and_cancel_limit_orders()

Expand Down
6 changes: 6 additions & 0 deletions additional_tests/exchanges_tests/test_bybit_futures.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ async def test_get_portfolio_with_market_filter(self):
# pass if not implemented
pass

async def test_untradable_symbols(self):
await super().test_untradable_symbols()

async def test_get_account_id(self):
# pass if not implemented
pass
Expand Down Expand Up @@ -79,6 +82,9 @@ async def test_get_and_set_leverage(self):
async def test_is_valid_account(self):
await super().test_is_valid_account()

async def test_get_special_orders(self):
await super().test_get_special_orders()

async def test_create_and_cancel_limit_orders(self):
await super().test_create_and_cancel_limit_orders()

Expand Down
Loading

0 comments on commit 29c43c1

Please sign in to comment.