diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index acd0e3ea0..90b63b57b 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -2072,21 +2072,21 @@ class Exchange: mm_ex_1=mm_ex_1, upnl_ex_1=upnl_ex_1 ) - - try: - positions = self._api.fetch_positions([pair]) - if len(positions) > 0: - pos = positions[0] - isolated_liq = pos['liquidationPrice'] - else: - return None - except ccxt.DDoSProtection as e: - raise DDosProtection(e) from e - except (ccxt.NetworkError, ccxt.ExchangeError) as e: - raise TemporaryError( - f'Could not set margin mode due to {e.__class__.__name__}. Message: {e}') from e - except ccxt.BaseError as e: - raise OperationalException(e) from e + else: + try: + positions = self._api.fetch_positions([pair]) + if len(positions) > 0: + pos = positions[0] + isolated_liq = pos['liquidationPrice'] + else: + return None + except ccxt.DDoSProtection as e: + raise DDosProtection(e) from e + except (ccxt.NetworkError, ccxt.ExchangeError) as e: + raise TemporaryError( + f'Could not set margin mode due to {e.__class__.__name__}. Message: {e}') from e + except ccxt.BaseError as e: + raise OperationalException(e) from e if isolated_liq: buffer_amount = abs(open_rate - isolated_liq) * self.liquidation_buffer diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index f5d0d0fd2..220fd04e6 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -3664,6 +3664,7 @@ def test_get_liquidation_price(mocker, default_conf): default_conf['dry_run'] = False default_conf['trading_mode'] = 'futures' default_conf['margin_mode'] = 'isolated' + default_conf['liquidation_buffer'] = 0.0 exchange = get_patched_exchange(mocker, default_conf, api_mock) liq_price = exchange.get_liquidation_price( @@ -3675,6 +3676,17 @@ def test_get_liquidation_price(mocker, default_conf): ) assert liq_price == 17.47 + default_conf['liquidation_buffer'] = 0.05 + exchange = get_patched_exchange(mocker, default_conf, api_mock) + liq_price = exchange.get_liquidation_price( + pair='NEAR/USDT:USDT', + open_rate=0.0, + is_short=False, + position=0.0, + wallet_balance=0.0, + ) + assert liq_price == 18.8133 + ccxt_exceptionhandlers( mocker, default_conf, @@ -4073,6 +4085,7 @@ def test_liquidation_price( ): default_conf['trading_mode'] = trading_mode default_conf['margin_mode'] = margin_mode + default_conf['liquidation_buffer'] = 0.0 exchange = get_patched_exchange(mocker, default_conf, id=exchange_name) exchange.get_maintenance_ratio_and_amt = MagicMock(return_value=(mm_ratio, maintenance_amt)) assert isclose(round(exchange.get_liquidation_price( diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index da7e8692d..1442186ea 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -4813,6 +4813,7 @@ def test_get_valid_price(mocker, default_conf_usdt) -> None: assert valid_price_at_min_alwd < proposed_price +@pytest.mark.parametrize('liquidation_buffer', [0.0, 0.05]) @pytest.mark.parametrize( "is_short,trading_mode,exchange_name,margin_mode,leverage,open_rate,amount,expected_liq", [ (False, 'spot', 'binance', '', 5.0, 10.0, 1.0, None), @@ -4854,6 +4855,7 @@ def test_leverage_prep( open_rate, amount, expected_liq, + liquidation_buffer, ): """ position = 0.2 * 5 @@ -4907,6 +4909,7 @@ def test_leverage_prep( leverage = 5, open_rate = 8, amount = 1.0 (8 - (1.6 / 1.0)) / (1 + (0.01 + 0.0006)) = 6.332871561448645 """ + default_conf_usdt['liquidation_buffer'] = liquidation_buffer default_conf_usdt['trading_mode'] = trading_mode default_conf_usdt['exchange']['name'] = exchange_name default_conf_usdt['margin_mode'] = margin_mode @@ -4931,6 +4934,8 @@ def test_leverage_prep( if expected_liq is None: assert liq is None else: + buffer_amount = liquidation_buffer * abs(open_rate - expected_liq) + expected_liq = expected_liq - buffer_amount if is_short else expected_liq + buffer_amount isclose(expected_liq, liq)