From 5b84298e0305c84d1ff2dee56e150a05c030f320 Mon Sep 17 00:00:00 2001 From: Sam Germain Date: Sun, 12 Sep 2021 00:03:02 -0600 Subject: [PATCH 1/7] kraken._apply_leverage_to_stake_amount --- freqtrade/exchange/kraken.py | 9 +++++++++ tests/exchange/test_exchange.py | 6 +++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/freqtrade/exchange/kraken.py b/freqtrade/exchange/kraken.py index b72a92070..14ebedef0 100644 --- a/freqtrade/exchange/kraken.py +++ b/freqtrade/exchange/kraken.py @@ -163,6 +163,15 @@ class Kraken(Exchange): leverages[pair] = leverage_buy self._leverage_brackets = leverages + def _apply_leverage_to_stake_amount(self, stake_amount: float, leverage: float): + """ + Takes the minimum stake amount for a pair with no leverage and returns the minimum + stake amount when leverage is considered + :param stake_amount: The stake amount for a pair before leverage is considered + :param leverage: The amount of leverage being used on the current trade + """ + return stake_amount / leverage + def get_max_leverage(self, pair: Optional[str], nominal_value: Optional[float]) -> float: """ Returns the maximum leverage that a pair can be traded at diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 239704bdd..330793822 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -2974,9 +2974,9 @@ def test_calculate_backoff(retrycount, max_retries, expected): ('binance', 20.0, 5.0, 4.0), ('binance', 100.0, 100.0, 1.0), # Kraken - ('kraken', 9.0, 3.0, 9.0), - ('kraken', 20.0, 5.0, 20.0), - ('kraken', 100.0, 100.0, 100.0), + ('kraken', 9.0, 3.0, 3.0), + ('kraken', 20.0, 5.0, 4.0), + ('kraken', 100.0, 100.0, 1.0), # FTX ('ftx', 9.0, 3.0, 9.0), ('ftx', 20.0, 5.0, 20.0), From 1344c9f7fc3ae103baf207e1d67f5fe3ac11d57b Mon Sep 17 00:00:00 2001 From: Sam Germain Date: Sun, 12 Sep 2021 01:30:26 -0600 Subject: [PATCH 2/7] _apply_leverage_to_min_stake_amount --- freqtrade/exchange/binance.py | 3 --- freqtrade/exchange/exchange.py | 2 +- freqtrade/exchange/kraken.py | 9 --------- tests/exchange/test_exchange.py | 15 ++++----------- 4 files changed, 5 insertions(+), 24 deletions(-) diff --git a/freqtrade/exchange/binance.py b/freqtrade/exchange/binance.py index f5a222d2d..1fcdc0ab4 100644 --- a/freqtrade/exchange/binance.py +++ b/freqtrade/exchange/binance.py @@ -112,9 +112,6 @@ class Binance(Exchange): except ccxt.BaseError as e: raise OperationalException(e) from e - def _apply_leverage_to_stake_amount(self, stake_amount: float, leverage: float): - return stake_amount / leverage - @retrier def fill_leverage_brackets(self): """ diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 03ab281c9..dfee82d7b 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -630,7 +630,7 @@ class Exchange: :param stake_amount: The stake amount for a pair before leverage is considered :param leverage: The amount of leverage being used on the current trade """ - return stake_amount + return stake_amount / leverage # Dry-run methods diff --git a/freqtrade/exchange/kraken.py b/freqtrade/exchange/kraken.py index 14ebedef0..b72a92070 100644 --- a/freqtrade/exchange/kraken.py +++ b/freqtrade/exchange/kraken.py @@ -163,15 +163,6 @@ class Kraken(Exchange): leverages[pair] = leverage_buy self._leverage_brackets = leverages - def _apply_leverage_to_stake_amount(self, stake_amount: float, leverage: float): - """ - Takes the minimum stake amount for a pair with no leverage and returns the minimum - stake amount when leverage is considered - :param stake_amount: The stake amount for a pair before leverage is considered - :param leverage: The amount of leverage being used on the current trade - """ - return stake_amount / leverage - def get_max_leverage(self, pair: Optional[str], nominal_value: Optional[float]) -> float: """ Returns the maximum leverage that a pair can be traded at diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 330793822..5c0323915 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -2969,18 +2969,11 @@ def test_calculate_backoff(retrycount, max_retries, expected): assert calculate_backoff(retrycount, max_retries) == expected +@pytest.mark.parametrize('exchange', ['binance', 'kraken', 'ftx']) @pytest.mark.parametrize('exchange,stake_amount,leverage,min_stake_with_lev', [ - ('binance', 9.0, 3.0, 3.0), - ('binance', 20.0, 5.0, 4.0), - ('binance', 100.0, 100.0, 1.0), - # Kraken - ('kraken', 9.0, 3.0, 3.0), - ('kraken', 20.0, 5.0, 4.0), - ('kraken', 100.0, 100.0, 1.0), - # FTX - ('ftx', 9.0, 3.0, 9.0), - ('ftx', 20.0, 5.0, 20.0), - ('ftx', 100.0, 100.0, 100.0) + (9.0, 3.0, 3.0), + (20.0, 5.0, 4.0), + (100.0, 100.0, 1.0) ]) def test_apply_leverage_to_stake_amount( exchange, From 09418938fe920ae9f9dc335d54705f2347f102f9 Mon Sep 17 00:00:00 2001 From: Sam Germain Date: Sun, 12 Sep 2021 01:51:09 -0600 Subject: [PATCH 3/7] Updated kraken fill leverage brackets and set_leverage --- freqtrade/exchange/kraken.py | 15 ++++++++------- tests/exchange/test_kraken.py | 15 ++++++++++++--- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/freqtrade/exchange/kraken.py b/freqtrade/exchange/kraken.py index b72a92070..97125f7ec 100644 --- a/freqtrade/exchange/kraken.py +++ b/freqtrade/exchange/kraken.py @@ -146,6 +146,7 @@ class Kraken(Exchange): leverages = {} for pair, market in self.markets.items(): + leverages[pair] = [1] info = market['info'] leverage_buy = info.get('leverage_buy', []) leverage_sell = info.get('leverage_sell', []) @@ -155,12 +156,12 @@ class Kraken(Exchange): f"The buy({leverage_buy}) and sell({leverage_sell}) leverage are not equal" "for {pair}. Please notify freqtrade because this has never happened before" ) - if max(leverage_buy) < max(leverage_sell): - leverages[pair] = leverage_buy + if max(leverage_buy) <= max(leverage_sell): + leverages[pair] += [int(lev) for lev in leverage_buy] else: - leverages[pair] = leverage_sell + leverages[pair] += [int(lev) for lev in leverage_sell] else: - leverages[pair] = leverage_buy + leverages[pair] += [int(lev) for lev in leverage_buy] self._leverage_brackets = leverages def get_max_leverage(self, pair: Optional[str], nominal_value: Optional[float]) -> float: @@ -173,7 +174,7 @@ class Kraken(Exchange): def set_leverage(self, pair, leverage): """ - Kraken set's the leverage as an option in the order object, so it doesn't do - anything in this function + Kraken set's the leverage as an option in the order object, so we need to + add it to params """ - return + self._params['leverage'] = leverage diff --git a/tests/exchange/test_kraken.py b/tests/exchange/test_kraken.py index 66e7f4f0b..74a06c96c 100644 --- a/tests/exchange/test_kraken.py +++ b/tests/exchange/test_kraken.py @@ -292,7 +292,16 @@ def test_fill_leverage_brackets_kraken(default_conf, mocker): exchange.fill_leverage_brackets() assert exchange._leverage_brackets == { - 'BLK/BTC': ['2', '3'], - 'TKN/BTC': ['2', '3', '4', '5'], - 'ETH/BTC': ['2'] + 'BLK/BTC': [1, 2, 3], + 'TKN/BTC': [1, 2, 3, 4, 5], + 'ETH/BTC': [1, 2], + 'LTC/BTC': [1], + 'XRP/BTC': [1], + 'NEO/BTC': [1], + 'BTT/BTC': [1], + 'ETH/USDT': [1], + 'LTC/USDT': [1], + 'LTC/USD': [1], + 'XLTCUSDT': [1], + 'LTC/ETH': [1] } From 0c1e5afc91384c88e4a3bf6d7aba9894780ef6e3 Mon Sep 17 00:00:00 2001 From: Sam Germain Date: Sun, 12 Sep 2021 02:02:10 -0600 Subject: [PATCH 4/7] Added set leverage to create_order --- freqtrade/exchange/exchange.py | 5 +++-- freqtrade/exchange/kraken.py | 2 +- tests/exchange/test_exchange.py | 6 +++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index dfee82d7b..a5778432a 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -771,12 +771,13 @@ class Exchange: # Order handling def create_order(self, pair: str, ordertype: str, side: str, amount: float, - rate: float, time_in_force: str = 'gtc') -> Dict: + rate: float, time_in_force: str = 'gtc', leverage=1.0) -> Dict: if self._config['dry_run']: dry_order = self.create_dry_run_order(pair, ordertype, side, amount, rate) return dry_order + self._set_leverage(pair, leverage) params = self._params.copy() if time_in_force != 'gtc' and ordertype != 'market': param = self._ft_has.get('time_in_force_parameter', '') @@ -1600,7 +1601,7 @@ class Exchange: return 1.0 @retrier - def set_leverage(self, leverage: float, pair: Optional[str]): + def _set_leverage(self, leverage: float, pair: Optional[str]): """ Set's the leverage before making a trade, in order to not have the same leverage on every trade diff --git a/freqtrade/exchange/kraken.py b/freqtrade/exchange/kraken.py index 97125f7ec..6981204a4 100644 --- a/freqtrade/exchange/kraken.py +++ b/freqtrade/exchange/kraken.py @@ -172,7 +172,7 @@ class Kraken(Exchange): """ return float(max(self._leverage_brackets[pair])) - def set_leverage(self, pair, leverage): + def _set_leverage(self, pair, leverage): """ Kraken set's the leverage as an option in the order object, so we need to add it to params diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 5c0323915..939e45d63 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -2970,7 +2970,7 @@ def test_calculate_backoff(retrycount, max_retries, expected): @pytest.mark.parametrize('exchange', ['binance', 'kraken', 'ftx']) -@pytest.mark.parametrize('exchange,stake_amount,leverage,min_stake_with_lev', [ +@pytest.mark.parametrize('stake_amount,leverage,min_stake_with_lev', [ (9.0, 3.0, 3.0), (20.0, 5.0, 4.0), (100.0, 100.0, 1.0) @@ -2992,7 +2992,7 @@ def test_apply_leverage_to_stake_amount( (Collateral.ISOLATED) ]) @pytest.mark.parametrize("exchange_name", [("ftx"), ("binance")]) -def test_set_leverage(mocker, default_conf, exchange_name, collateral): +def test__set_leverage(mocker, default_conf, exchange_name, collateral): api_mock = MagicMock() api_mock.set_leverage = MagicMock() @@ -3003,7 +3003,7 @@ def test_set_leverage(mocker, default_conf, exchange_name, collateral): default_conf, api_mock, exchange_name, - "set_leverage", + "_set_leverage", "set_leverage", pair="XRP/USDT", leverage=5.0 From bc102d57c91ff225c9ca3cd1745d7b8460efcce0 Mon Sep 17 00:00:00 2001 From: Sam Germain Date: Sun, 12 Sep 2021 02:06:18 -0600 Subject: [PATCH 5/7] Updated set leverage to check trading mode --- freqtrade/exchange/binance.py | 21 +++++++++++++++++++++ freqtrade/exchange/exchange.py | 9 +++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/freqtrade/exchange/binance.py b/freqtrade/exchange/binance.py index 1fcdc0ab4..178fa49da 100644 --- a/freqtrade/exchange/binance.py +++ b/freqtrade/exchange/binance.py @@ -151,3 +151,24 @@ class Binance(Exchange): if nominal_value >= min_amount: max_lev = 1/margin_req return max_lev + + @retrier + def _set_leverage(self, leverage: float, pair: Optional[str]): + """ + Set's the leverage before making a trade, in order to not + have the same leverage on every trade + """ + if not self.exchange_has("setLeverage"): + # Some exchanges only support one collateral type + return + + try: + if self.trading_mode == TradingMode.FUTURES: + self._api.set_leverage(symbol=pair, leverage=leverage) + except ccxt.DDoSProtection as e: + raise DDosProtection(e) from e + except (ccxt.NetworkError, ccxt.ExchangeError) as e: + raise TemporaryError( + f'Could not set leverage due to {e.__class__.__name__}. Message: {e}') from e + except ccxt.BaseError as e: + raise OperationalException(e) from e diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index a5778432a..bef8f5e57 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -145,7 +145,7 @@ class Exchange: self._api_async = self._init_ccxt( exchange_config, ccxt_async, ccxt_kwargs=ccxt_async_config) - trading_mode: TradingMode = ( + self.trading_mode: TradingMode = ( TradingMode(config.get('trading_mode')) if config.get('trading_mode') else TradingMode.SPOT @@ -156,7 +156,7 @@ class Exchange: else None ) - if trading_mode != TradingMode.SPOT: + if self.trading_mode != TradingMode.SPOT: self.fill_leverage_brackets() logger.info('Using Exchange "%s"', self.name) @@ -176,7 +176,7 @@ class Exchange: self.validate_order_time_in_force(config.get('order_time_in_force', {})) self.validate_required_startup_candles(config.get('startup_candle_count', 0), config.get('timeframe', '')) - self.validate_trading_mode_and_collateral(trading_mode, collateral) + self.validate_trading_mode_and_collateral(self.trading_mode, collateral) # Converts the interval provided in minutes in config to seconds self.markets_refresh_interval: int = exchange_config.get( "markets_refresh_interval", 60) * 60 @@ -777,7 +777,8 @@ class Exchange: dry_order = self.create_dry_run_order(pair, ordertype, side, amount, rate) return dry_order - self._set_leverage(pair, leverage) + if self.trading_mode != TradingMode.SPOT: + self._set_leverage(pair, leverage) params = self._params.copy() if time_in_force != 'gtc' and ordertype != 'market': param = self._ft_has.get('time_in_force_parameter', '') From ad44048e29adc83518bdf2f5a8b9aaa2bc721897 Mon Sep 17 00:00:00 2001 From: Sam Germain Date: Sun, 12 Sep 2021 02:42:13 -0600 Subject: [PATCH 6/7] customized set_leverage for different exchanges --- freqtrade/exchange/binance.py | 13 ++++++++----- freqtrade/exchange/exchange.py | 9 +++++++-- freqtrade/exchange/kraken.py | 12 ++++++++++-- tests/exchange/test_exchange.py | 18 +++++++++--------- tests/exchange/test_kraken.py | 6 ++++++ 5 files changed, 40 insertions(+), 18 deletions(-) diff --git a/freqtrade/exchange/binance.py b/freqtrade/exchange/binance.py index 178fa49da..4315585b6 100644 --- a/freqtrade/exchange/binance.py +++ b/freqtrade/exchange/binance.py @@ -153,17 +153,20 @@ class Binance(Exchange): return max_lev @retrier - def _set_leverage(self, leverage: float, pair: Optional[str]): + def _set_leverage( + self, + leverage: float, + pair: Optional[str], + trading_mode: Optional[TradingMode] + ): """ Set's the leverage before making a trade, in order to not have the same leverage on every trade """ - if not self.exchange_has("setLeverage"): - # Some exchanges only support one collateral type - return + trading_mode = trading_mode or self.trading_mode try: - if self.trading_mode == TradingMode.FUTURES: + if trading_mode == TradingMode.FUTURES: self._api.set_leverage(symbol=pair, leverage=leverage) except ccxt.DDoSProtection as e: raise DDosProtection(e) from e diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index bef8f5e57..dd3304921 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -778,7 +778,7 @@ class Exchange: return dry_order if self.trading_mode != TradingMode.SPOT: - self._set_leverage(pair, leverage) + self._set_leverage(leverage, pair) params = self._params.copy() if time_in_force != 'gtc' and ordertype != 'market': param = self._ft_has.get('time_in_force_parameter', '') @@ -1602,7 +1602,12 @@ class Exchange: return 1.0 @retrier - def _set_leverage(self, leverage: float, pair: Optional[str]): + def _set_leverage( + self, + leverage: float, + pair: Optional[str], + trading_mode: Optional[TradingMode] + ): """ Set's the leverage before making a trade, in order to not have the same leverage on every trade diff --git a/freqtrade/exchange/kraken.py b/freqtrade/exchange/kraken.py index 6981204a4..46f1ab934 100644 --- a/freqtrade/exchange/kraken.py +++ b/freqtrade/exchange/kraken.py @@ -172,9 +172,17 @@ class Kraken(Exchange): """ return float(max(self._leverage_brackets[pair])) - def _set_leverage(self, pair, leverage): + def _set_leverage( + self, + leverage: float, + pair: Optional[str], + trading_mode: Optional[TradingMode] + ): """ Kraken set's the leverage as an option in the order object, so we need to add it to params """ - self._params['leverage'] = leverage + if leverage > 1.0: + self._params['leverage'] = leverage + else: + del self._params['leverage'] diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 939e45d63..3231d9811 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -2987,12 +2987,12 @@ def test_apply_leverage_to_stake_amount( assert exchange._apply_leverage_to_stake_amount(stake_amount, leverage) == min_stake_with_lev -@pytest.mark.parametrize("collateral", [ - (Collateral.CROSS), - (Collateral.ISOLATED) +@pytest.mark.parametrize("exchange_name,trading_mode", [ + ("binance", TradingMode.FUTURES), + ("ftx", TradingMode.MARGIN), + ("ftx", TradingMode.FUTURES) ]) -@pytest.mark.parametrize("exchange_name", [("ftx"), ("binance")]) -def test__set_leverage(mocker, default_conf, exchange_name, collateral): +def test__set_leverage(mocker, default_conf, exchange_name, trading_mode): api_mock = MagicMock() api_mock.set_leverage = MagicMock() @@ -3006,7 +3006,8 @@ def test__set_leverage(mocker, default_conf, exchange_name, collateral): "_set_leverage", "set_leverage", pair="XRP/USDT", - leverage=5.0 + leverage=5.0, + trading_mode=trading_mode ) @@ -3014,8 +3015,7 @@ def test__set_leverage(mocker, default_conf, exchange_name, collateral): (Collateral.CROSS), (Collateral.ISOLATED) ]) -@pytest.mark.parametrize("exchange_name", [("ftx"), ("binance")]) -def test_set_margin_mode(mocker, default_conf, exchange_name, collateral): +def test_set_margin_mode(mocker, default_conf, collateral): api_mock = MagicMock() api_mock.set_margin_mode = MagicMock() @@ -3025,7 +3025,7 @@ def test_set_margin_mode(mocker, default_conf, exchange_name, collateral): mocker, default_conf, api_mock, - exchange_name, + "binance", "set_margin_mode", "set_margin_mode", pair="XRP/USDT", diff --git a/tests/exchange/test_kraken.py b/tests/exchange/test_kraken.py index 74a06c96c..1a712fd3f 100644 --- a/tests/exchange/test_kraken.py +++ b/tests/exchange/test_kraken.py @@ -305,3 +305,9 @@ def test_fill_leverage_brackets_kraken(default_conf, mocker): 'XLTCUSDT': [1], 'LTC/ETH': [1] } + + +def test_kraken__set_leverage(default_conf, mocker): + exchange = get_patched_exchange(mocker, default_conf, id="kraken") + exchange._set_leverage(3) + assert exchange.params['leverage'] == 3 From e070bdd161a3b433c1afe0f0552f02632a03f47b Mon Sep 17 00:00:00 2001 From: Sam Germain Date: Sun, 12 Sep 2021 03:09:51 -0600 Subject: [PATCH 7/7] set leverage more thorough tests --- freqtrade/exchange/binance.py | 4 ++-- freqtrade/exchange/exchange.py | 4 ++-- freqtrade/exchange/kraken.py | 7 ++++--- tests/exchange/test_binance.py | 23 +++++++++++++++++++++++ tests/exchange/test_ftx.py | 26 +++++++++++++++++++++++++- tests/exchange/test_kraken.py | 10 ++++++++-- 6 files changed, 64 insertions(+), 10 deletions(-) diff --git a/freqtrade/exchange/binance.py b/freqtrade/exchange/binance.py index 4315585b6..fcd027d52 100644 --- a/freqtrade/exchange/binance.py +++ b/freqtrade/exchange/binance.py @@ -156,8 +156,8 @@ class Binance(Exchange): def _set_leverage( self, leverage: float, - pair: Optional[str], - trading_mode: Optional[TradingMode] + pair: Optional[str] = None, + trading_mode: Optional[TradingMode] = None ): """ Set's the leverage before making a trade, in order to not diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index dd3304921..2fb63d201 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -1605,8 +1605,8 @@ class Exchange: def _set_leverage( self, leverage: float, - pair: Optional[str], - trading_mode: Optional[TradingMode] + pair: Optional[str] = None, + trading_mode: Optional[TradingMode] = None ): """ Set's the leverage before making a trade, in order to not diff --git a/freqtrade/exchange/kraken.py b/freqtrade/exchange/kraken.py index 46f1ab934..661000d4d 100644 --- a/freqtrade/exchange/kraken.py +++ b/freqtrade/exchange/kraken.py @@ -175,8 +175,8 @@ class Kraken(Exchange): def _set_leverage( self, leverage: float, - pair: Optional[str], - trading_mode: Optional[TradingMode] + pair: Optional[str] = None, + trading_mode: Optional[TradingMode] = None ): """ Kraken set's the leverage as an option in the order object, so we need to @@ -185,4 +185,5 @@ class Kraken(Exchange): if leverage > 1.0: self._params['leverage'] = leverage else: - del self._params['leverage'] + if 'leverage' in self._params: + del self._params['leverage'] diff --git a/tests/exchange/test_binance.py b/tests/exchange/test_binance.py index 96287da44..dd012f4ab 100644 --- a/tests/exchange/test_binance.py +++ b/tests/exchange/test_binance.py @@ -4,6 +4,7 @@ from unittest.mock import MagicMock, PropertyMock import ccxt import pytest +from freqtrade.enums import TradingMode from freqtrade.exceptions import DependencyException, InvalidOrderException, OperationalException from tests.conftest import get_patched_exchange from tests.exchange.test_exchange import ccxt_exceptionhandlers @@ -232,3 +233,25 @@ def test_fill_leverage_brackets_binance(default_conf, mocker): "fill_leverage_brackets", "load_leverage_brackets" ) + + +def test__set_leverage_binance(mocker, default_conf): + + api_mock = MagicMock() + api_mock.set_leverage = MagicMock() + type(api_mock).has = PropertyMock(return_value={'setLeverage': True}) + + exchange = get_patched_exchange(mocker, default_conf, id="binance") + exchange._set_leverage(3.0, trading_mode=TradingMode.MARGIN) + + ccxt_exceptionhandlers( + mocker, + default_conf, + api_mock, + "binance", + "_set_leverage", + "set_leverage", + pair="XRP/USDT", + leverage=5.0, + trading_mode=TradingMode.FUTURES + ) diff --git a/tests/exchange/test_ftx.py b/tests/exchange/test_ftx.py index 33eb0e3c4..88c4c069b 100644 --- a/tests/exchange/test_ftx.py +++ b/tests/exchange/test_ftx.py @@ -1,9 +1,10 @@ from random import randint -from unittest.mock import MagicMock +from unittest.mock import MagicMock, PropertyMock import ccxt import pytest +from freqtrade.enums import TradingMode from freqtrade.exceptions import DependencyException, InvalidOrderException from freqtrade.exchange.common import API_FETCH_ORDER_RETRY_COUNT from tests.conftest import get_patched_exchange @@ -229,3 +230,26 @@ def test_fill_leverage_brackets_ftx(default_conf, mocker): exchange = get_patched_exchange(mocker, default_conf, id="ftx") exchange.fill_leverage_brackets() assert exchange._leverage_brackets == {} + + +@pytest.mark.parametrize("trading_mode", [ + (TradingMode.MARGIN), + (TradingMode.FUTURES) +]) +def test__set_leverage(mocker, default_conf, trading_mode): + + api_mock = MagicMock() + api_mock.set_leverage = MagicMock() + type(api_mock).has = PropertyMock(return_value={'setLeverage': True}) + + ccxt_exceptionhandlers( + mocker, + default_conf, + api_mock, + "ftx", + "_set_leverage", + "set_leverage", + pair="XRP/USDT", + leverage=5.0, + trading_mode=trading_mode + ) diff --git a/tests/exchange/test_kraken.py b/tests/exchange/test_kraken.py index 1a712fd3f..374b054a6 100644 --- a/tests/exchange/test_kraken.py +++ b/tests/exchange/test_kraken.py @@ -307,7 +307,13 @@ def test_fill_leverage_brackets_kraken(default_conf, mocker): } -def test_kraken__set_leverage(default_conf, mocker): +def test__set_leverage_kraken(default_conf, mocker): exchange = get_patched_exchange(mocker, default_conf, id="kraken") + exchange._set_leverage(1) + assert 'leverage' not in exchange._params exchange._set_leverage(3) - assert exchange.params['leverage'] == 3 + assert exchange._params['leverage'] == 3 + exchange._set_leverage(1.0) + assert 'leverage' not in exchange._params + exchange._set_leverage(3.0) + assert exchange._params['leverage'] == 3