mirror of
https://github.com/freqtrade/freqtrade.git
synced 2024-09-21 01:51:12 +00:00
Merge pull request #8901 from freqtrade/fix/8841
Avoid false-triggering "dust-eating" logic for rebuys
This commit is contained in:
commit
061e930eb1
|
@ -1939,6 +1939,7 @@ class FreqtradeBot(LoggingMixin):
|
||||||
"""
|
"""
|
||||||
Applies the fee to amount (either from Order or from Trades).
|
Applies the fee to amount (either from Order or from Trades).
|
||||||
Can eat into dust if more than the required asset is available.
|
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,
|
Can't happen in Futures mode - where Fees are always in settlement currency,
|
||||||
never in base currency.
|
never in base currency.
|
||||||
"""
|
"""
|
||||||
|
@ -1948,6 +1949,10 @@ class FreqtradeBot(LoggingMixin):
|
||||||
# check against remaining amount!
|
# check against remaining amount!
|
||||||
amount_ = trade.amount - 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_:
|
if fee_abs != 0 and self.wallets.get_free(trade_base_currency) >= amount_:
|
||||||
# Eat into dust if we own more than base currency
|
# Eat into dust if we own more than base currency
|
||||||
logger.info(f"Fee amount for {trade} was in base currency - "
|
logger.info(f"Fee amount for {trade} was in base currency - "
|
||||||
|
@ -1977,7 +1982,11 @@ class FreqtradeBot(LoggingMixin):
|
||||||
# Init variables
|
# Init variables
|
||||||
order_amount = safe_value_fallback(order, 'filled', 'amount')
|
order_amount = safe_value_fallback(order, 'filled', 'amount')
|
||||||
# Only run for closed orders
|
# 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
|
return None
|
||||||
|
|
||||||
trade_base_currency = self.exchange.get_pair_base_currency(trade.pair)
|
trade_base_currency = self.exchange.get_pair_base_currency(trade.pair)
|
||||||
|
|
|
@ -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, 8.0, None),
|
||||||
(8.0, 0.1, 7.9, 0.1),
|
(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):
|
amount, fee_abs, wallet, amount_exp):
|
||||||
walletmock = mocker.patch('freqtrade.wallets.Wallets.update')
|
walletmock = mocker.patch('freqtrade.wallets.Wallets.update')
|
||||||
mocker.patch('freqtrade.wallets.Wallets.get_free', return_value=wallet)
|
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
|
# Amount is kept as is
|
||||||
assert freqtrade.apply_fee_conditional(trade, 'LTC', amount, fee_abs, order) == amount_exp
|
assert freqtrade.apply_fee_conditional(trade, 'LTC', amount, fee_abs, order) == amount_exp
|
||||||
assert walletmock.call_count == 1
|
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", [
|
@pytest.mark.parametrize("delta, is_high_delta", [
|
||||||
|
|
Loading…
Reference in New Issue
Block a user