diff --git a/freqtrade/exchange/binance.py b/freqtrade/exchange/binance.py index b4e1f3d57..826087aac 100644 --- a/freqtrade/exchange/binance.py +++ b/freqtrade/exchange/binance.py @@ -173,22 +173,35 @@ class Binance(Exchange): except ccxt.BaseError as e: raise OperationalException(e) from e - def get_max_leverage(self, pair: str, nominal_value: float) -> float: + def get_max_leverage(self, pair: str, stake_amount: Optional[float]) -> float: """ Returns the maximum leverage that a pair can be traded at :param pair: The base/quote currency pair being traded - :nominal_value: The total value of the trade in quote currency (collateral + debt) + :stake_amount: The total value of the traders collateral in quote currency """ + if stake_amount is None: + raise OperationalException('binance.get_max_leverage requires argument stake_amount') if pair not in self._leverage_brackets: return 1.0 pair_brackets = self._leverage_brackets[pair] - for [notional_floor, mm_ratio, _] in reversed(pair_brackets): - if nominal_value >= notional_floor: - if mm_ratio != 0: - return 1/mm_ratio - else: - logger.warning(f"mm_ratio for {pair} with nominal_value {nominal_value} is 0") - return 1.0 + num_brackets = len(pair_brackets) + min_amount = 0.0 + for bracket_num in range(num_brackets): + [notional_floor, mm_ratio, _] = pair_brackets[bracket_num] + lev = 1.0 + if mm_ratio != 0: + lev = 1.0/mm_ratio + else: + logger.warning(f"mm_ratio for {pair} with notional floor {notional_floor} is 0") + if bracket_num+1 != num_brackets: # If not on last bracket + [min_amount, _, __] = pair_brackets[bracket_num+1] # Get min_amount of next bracket + else: + return lev + nominal_value = stake_amount * lev + # Bracket is good if the leveraged trade value doesnt exceed min_amount of next bracket + if nominal_value < min_amount: + return lev + return 1.0 # default leverage @retrier def _set_leverage( diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 837a390ed..4539ab352 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -1806,7 +1806,7 @@ class Exchange: """ return - def get_max_leverage(self, pair: str, nominal_value: float) -> float: + def get_max_leverage(self, pair: str, stake_amount: Optional[float]) -> float: """ Returns the maximum leverage that a pair can be traded at :param pair: The base/quote currency pair being traded diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index 55168fb45..676499642 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -810,7 +810,9 @@ def test_download_data_trades(mocker, caplog): "--days", "20", "--dl-trades" ] - start_download_data(get_args(args)) + pargs = get_args(args) + pargs['config'] = None + start_download_data(pargs) assert dl_mock.call_args[1]['timerange'].starttype == "date" assert dl_mock.call_count == 1 assert convert_mock.call_count == 1 diff --git a/tests/exchange/test_binance.py b/tests/exchange/test_binance.py index 6762fada7..00a2369bb 100644 --- a/tests/exchange/test_binance.py +++ b/tests/exchange/test_binance.py @@ -162,45 +162,49 @@ def test_stoploss_adjust_binance(mocker, default_conf, sl1, sl2, sl3, side): assert not exchange.stoploss_adjust(sl3, order, side=side) -@pytest.mark.parametrize('pair,nominal_value,max_lev', [ +@pytest.mark.parametrize('pair,stake_amount,max_lev', [ ("BNB/BUSD", 0.0, 40.0), - ("BNB/USDT", 100.0, 153.84615384615384), + ("BNB/USDT", 100.0, 100.0), ("BTC/USDT", 170.30, 250.0), - ("BNB/BUSD", 999999.9, 10.0), - ("BNB/USDT", 5000000.0, 6.666666666666667), - ("BTC/USDT", 300000000.1, 2.0), + ("BNB/BUSD", 99999.9, 10.0), + ("BNB/USDT", 750000, 6.666666666666667), + ("BTC/USDT", 150000000.1, 2.0), ]) -def test_get_max_leverage_binance(default_conf, mocker, pair, nominal_value, max_lev): +def test_get_max_leverage_binance(default_conf, mocker, pair, stake_amount, max_lev): exchange = get_patched_exchange(mocker, default_conf, id="binance") exchange._leverage_brackets = { - 'BNB/BUSD': [[0.0, 0.025, 0.0], - [100000.0, 0.05, 2500.0], - [500000.0, 0.1, 27500.0], - [1000000.0, 0.15, 77500.0], - [2000000.0, 0.25, 277500.0], - [5000000.0, 0.5, 1527500.0]], - 'BNB/USDT': [[0.0, 0.0065, 0.0], - [10000.0, 0.01, 35.0], - [50000.0, 0.02, 535.0], - [250000.0, 0.05, 8035.0], - [1000000.0, 0.1, 58035.0], - [2000000.0, 0.125, 108035.0], - [5000000.0, 0.15, 233035.0], - [10000000.0, 0.25, 1233035.0]], - 'BTC/USDT': [[0.0, 0.004, 0.0], - [50000.0, 0.005, 50.0], - [250000.0, 0.01, 1300.0], - [1000000.0, 0.025, 16300.0], - [5000000.0, 0.05, 141300.0], - [20000000.0, 0.1, 1141300.0], - [50000000.0, 0.125, 2391300.0], - [100000000.0, 0.15, 4891300.0], - [200000000.0, 0.25, 24891300.0], - [300000000.0, 0.5, 99891300.0] - ] - + 'BNB/BUSD': [ + [0.0, 0.025, 0.0], # lev = 40.0 + [100000.0, 0.05, 2500.0], # lev = 20.0 + [500000.0, 0.1, 27500.0], # lev = 10.0 + [1000000.0, 0.15, 77500.0], # lev = 6.666666666666667 + [2000000.0, 0.25, 277500.0], # lev = 4.0 + [5000000.0, 0.5, 1527500.0], # lev = 2.0 + ], + 'BNB/USDT': [ + [0.0, 0.0065, 0.0], # lev = 153.84615384615384 + [10000.0, 0.01, 35.0], # lev = 100.0 + [50000.0, 0.02, 535.0], # lev = 50.0 + [250000.0, 0.05, 8035.0], # lev = 20.0 + [1000000.0, 0.1, 58035.0], # lev = 10.0 + [2000000.0, 0.125, 108035.0], # lev = 8.0 + [5000000.0, 0.15, 233035.0], # lev = 6.666666666666667 + [10000000.0, 0.25, 1233035.0], # lev = 4.0 + ], + 'BTC/USDT': [ + [0.0, 0.004, 0.0], # lev = 250.0 + [50000.0, 0.005, 50.0], # lev = 200.0 + [250000.0, 0.01, 1300.0], # lev = 100.0 + [1000000.0, 0.025, 16300.0], # lev = 40.0 + [5000000.0, 0.05, 141300.0], # lev = 20.0 + [20000000.0, 0.1, 1141300.0], # lev = 10.0 + [50000000.0, 0.125, 2391300.0], # lev = 8.0 + [100000000.0, 0.15, 4891300.0], # lev = 6.666666666666667 + [200000000.0, 0.25, 24891300.0], # lev = 4.0 + [300000000.0, 0.5, 99891300.0], # lev = 2.0 + ] } - assert exchange.get_max_leverage(pair, nominal_value) == max_lev + assert exchange.get_max_leverage(pair, stake_amount) == max_lev def test_fill_leverage_brackets_binance(default_conf, mocker):