From 45a9c304b63ea2e253ea8ab3c15962598d811752 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 13 Jul 2023 07:05:14 +0200 Subject: [PATCH 1/3] Add test for new conditional behavior --- tests/test_freqtradebot.py | 56 +++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 3bfa5a127..742fdcace 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -5023,7 +5023,7 @@ def test_get_real_amount_in_point(default_conf_usdt, buy_order_fee, fee, mocker, (8.0, 0.1, 8.0, None), (8.0, 0.1, 7.9, 0.1), ]) -def test_apply_fee_conditional(default_conf_usdt, fee, mocker, +def test_apply_fee_conditional(default_conf_usdt, fee, mocker, caplog, amount, fee_abs, wallet, amount_exp): walletmock = mocker.patch('freqtrade.wallets.Wallets.update') mocker.patch('freqtrade.wallets.Wallets.get_free', return_value=wallet) @@ -5048,6 +5048,60 @@ def test_apply_fee_conditional(default_conf_usdt, fee, mocker, # Amount is kept as is assert freqtrade.apply_fee_conditional(trade, 'LTC', amount, fee_abs, order) == amount_exp assert walletmock.call_count == 1 + if fee_abs != 0 and amount_exp is None: + assert log_has_re(r"Fee amount.*Eating.*dust\.", caplog) + + +@pytest.mark.parametrize('amount,fee_abs,wallet,amount_exp', [ + (8.0, 0.0, 16, None), + (8.0, 0.0, 0, None), + (8.0, 0.1, 8, 0.1), + (8.0, 0.1, 20, None), + (8.0, 0.1, 16.0, None), + (8.0, 0.1, 7.9, 0.1), + (8.0, 0.1, 12, 0.1), + (8.0, 0.1, 15.9, 0.1), +]) +def test_apply_fee_conditional_multibuy(default_conf_usdt, fee, mocker, caplog, + amount, fee_abs, wallet, amount_exp): + walletmock = mocker.patch('freqtrade.wallets.Wallets.update') + mocker.patch('freqtrade.wallets.Wallets.get_free', return_value=wallet) + trade = Trade( + pair='LTC/ETH', + amount=amount, + exchange='binance', + open_rate=0.245441, + fee_open=fee.return_value, + fee_close=fee.return_value, + open_order_id="123456" + ) + # One closed order + order = Order( + ft_order_side='buy', + order_id='10', + ft_pair=trade.pair, + ft_is_open=False, + filled=amount, + status="closed" + ) + trade.orders.append(order) + # Add additional order - this should NOT eat into dust unless the wallet was bigger already. + order1 = Order( + ft_order_side='buy', + order_id='100', + ft_pair=trade.pair, + ft_is_open=True, + ) + trade.orders.append(order1) + + freqtrade = get_patched_freqtradebot(mocker, default_conf_usdt) + + walletmock.reset_mock() + # The new trade amount will be 2x amount - fee / wallet will have to be adapted to this. + assert freqtrade.apply_fee_conditional(trade, 'LTC', amount, fee_abs, order1) == amount_exp + assert walletmock.call_count == 1 + if fee_abs != 0 and amount_exp is None: + assert log_has_re(r"Fee amount.*Eating.*dust\.", caplog) @pytest.mark.parametrize("delta, is_high_delta", [ From 6134764d5e929d0f481688215a106a62731c9ad4 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 10 Jul 2023 21:05:09 +0200 Subject: [PATCH 2/3] Don't wrongly eat into dust on rebuys closes #8841 --- freqtrade/freqtradebot.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 562cdc2e0..7bee9f350 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -1939,6 +1939,7 @@ class FreqtradeBot(LoggingMixin): """ Applies the fee to amount (either from Order or from Trades). Can eat into dust if more than the required asset is available. + In case of trade adjustment orders, trade.amount will not have been adjusted yet. Can't happen in Futures mode - where Fees are always in settlement currency, never in base currency. """ @@ -1948,6 +1949,10 @@ class FreqtradeBot(LoggingMixin): # check against remaining amount! amount_ = trade.amount - amount + if trade.nr_of_successful_entries >= 1 and order_obj.ft_order_side == trade.entry_side: + # In case of rebuy's, trade.amount doesn't contain the amount of the last entry. + amount_ = trade.amount + amount + if fee_abs != 0 and self.wallets.get_free(trade_base_currency) >= amount_: # Eat into dust if we own more than base currency logger.info(f"Fee amount for {trade} was in base currency - " From 240606c5a4add5dc55d4bb836236afcb6084cc78 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 13 Jul 2023 07:14:20 +0200 Subject: [PATCH 3/3] Only run once for an order --- freqtrade/freqtradebot.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 7bee9f350..1fdf79b68 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -1982,7 +1982,11 @@ class FreqtradeBot(LoggingMixin): # Init variables order_amount = safe_value_fallback(order, 'filled', 'amount') # Only run for closed orders - if trade.fee_updated(order.get('side', '')) or order['status'] == 'open': + if ( + trade.fee_updated(order.get('side', '')) + or order['status'] == 'open' + or order_obj.ft_fee_base + ): return None trade_base_currency = self.exchange.get_pair_base_currency(trade.pair)