diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 07b7e2ecb..45b566bcf 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -649,7 +649,10 @@ class Exchange: if ('amount' in limits and 'min' in limits['amount'] and limits['amount']['min'] is not None): - self._contract_size_to_amount(pair, min_stake_amounts.append(limits['amount']['min'] * price)) + self._contract_size_to_amount( + pair, + min_stake_amounts.append(limits['amount']['min'] * price) + ) if not min_stake_amounts: return None @@ -837,15 +840,15 @@ class Exchange: def _amount_to_contract_size(self, pair: str, amount: float): - if ('contractSize' in self.markets[pair]): - return amount / self.markets[pair]['contractSize'] + if ('contractSize' in self._api.markets[pair]): + return amount / self._api.markets[pair]['contractSize'] else: return amount def _contract_size_to_amount(self, pair: str, amount: float): - if ('contractSize' in self.markets[pair]): - return amount * self.markets[pair]['contractSize'] + if ('contractSize' in self._api.markets[pair]): + return amount * self._api.markets[pair]['contractSize'] else: return amount diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index c91cc29c8..9f0f272e1 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -398,6 +398,9 @@ def test_get_min_pair_stake_amount(mocker, default_conf) -> None: result = exchange.get_min_pair_stake_amount('ETH/BTC', 1, stoploss) expected_result = 2 * (1+0.05) / (1-abs(stoploss)) assert isclose(result, expected_result) + # With Leverage + result = exchange.get_min_pair_stake_amount('ETH/BTC', 1, stoploss, 3.0) + assert isclose(result, expected_result/3) # min amount is set markets["ETH/BTC"]["limits"] = { @@ -411,6 +414,9 @@ def test_get_min_pair_stake_amount(mocker, default_conf) -> None: result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, stoploss) expected_result = 2 * 2 * (1+0.05) / (1-abs(stoploss)) assert isclose(result, expected_result) + # With Leverage + result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, stoploss, 5.0) + assert isclose(result, expected_result/5) # min amount and cost are set (cost is minimal) markets["ETH/BTC"]["limits"] = { @@ -424,6 +430,9 @@ def test_get_min_pair_stake_amount(mocker, default_conf) -> None: result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, stoploss) expected_result = max(2, 2 * 2) * (1+0.05) / (1-abs(stoploss)) assert isclose(result, expected_result) + # With Leverage + result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, stoploss, 10) + assert isclose(result, expected_result/10) # min amount and cost are set (amount is minial) markets["ETH/BTC"]["limits"] = { @@ -437,15 +446,24 @@ def test_get_min_pair_stake_amount(mocker, default_conf) -> None: result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, stoploss) expected_result = max(8, 2 * 2) * (1+0.05) / (1-abs(stoploss)) assert isclose(result, expected_result) + # With Leverage + result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, stoploss, 7.0) + assert isclose(result, expected_result/7.0) result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, -0.4) expected_result = max(8, 2 * 2) * 1.5 assert isclose(result, expected_result) + # With Leverage + result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, -0.4, 8.0) + assert isclose(result, expected_result/8.0) # Really big stoploss result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, -1) expected_result = max(8, 2 * 2) * 1.5 assert isclose(result, expected_result) + # With Leverage + result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, -1, 12.0) + assert isclose(result, expected_result/12) def test_get_min_pair_stake_amount_real_data(mocker, default_conf) -> None: @@ -465,6 +483,8 @@ def test_get_min_pair_stake_amount_real_data(mocker, default_conf) -> None: result = exchange.get_min_pair_stake_amount('ETH/BTC', 0.020405, stoploss) expected_result = max(0.0001, 0.001 * 0.020405) * (1+0.05) / (1-abs(stoploss)) assert round(result, 8) == round(expected_result, 8) + result = exchange.get_min_pair_stake_amount('ETH/BTC', 0.020405, stoploss, 3.0) + assert round(result, 8) == round(expected_result/3, 8) def test_set_sandbox(default_conf, mocker): @@ -3243,6 +3263,25 @@ def test__get_funding_fees_from_exchange(default_conf, mocker, exchange_name): ) +@pytest.mark.parametrize('exchange', ['binance', 'kraken', 'ftx']) +@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) +]) +def test_get_stake_amount_considering_leverage( + exchange, + stake_amount, + leverage, + min_stake_with_lev, + mocker, + default_conf +): + exchange = get_patched_exchange(mocker, default_conf, id=exchange) + assert exchange._get_stake_amount_considering_leverage( + stake_amount, leverage) == min_stake_with_lev + + @pytest.mark.parametrize("exchange_name,trading_mode", [ ("binance", TradingMode.FUTURES), ("ftx", TradingMode.MARGIN),