Fix BNB fee bug when selling

thanks @epigramx, for reporting and for the detailed data.
This commit is contained in:
Matthias 2022-09-01 06:35:24 +02:00
parent 3d4ad1de4c
commit ba2eb7cf0f
2 changed files with 18 additions and 6 deletions

View File

@ -1778,7 +1778,7 @@ class FreqtradeBot(LoggingMixin):
self.rpc.send_msg(msg) self.rpc.send_msg(msg)
def apply_fee_conditional(self, trade: Trade, trade_base_currency: str, def apply_fee_conditional(self, trade: Trade, trade_base_currency: str,
amount: float, fee_abs: float) -> Optional[float]: amount: float, fee_abs: float, order_obj: Order) -> Optional[float]:
""" """
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.
@ -1786,7 +1786,12 @@ class FreqtradeBot(LoggingMixin):
never in base currency. never in base currency.
""" """
self.wallets.update() self.wallets.update()
if fee_abs != 0 and self.wallets.get_free(trade_base_currency) >= amount: amount_ = amount
if order_obj.ft_order_side == trade.exit_side or order_obj.ft_order_side == 'stoploss':
# check against remaining amount!
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 # 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 - "
f"Eating Fee {fee_abs} into dust.") f"Eating Fee {fee_abs} into dust.")
@ -1833,7 +1838,8 @@ class FreqtradeBot(LoggingMixin):
if trade_base_currency == fee_currency: if trade_base_currency == fee_currency:
# Apply fee to amount # Apply fee to amount
return self.apply_fee_conditional(trade, trade_base_currency, return self.apply_fee_conditional(trade, trade_base_currency,
amount=order_amount, fee_abs=fee_cost) amount=order_amount, fee_abs=fee_cost,
order_obj=order_obj)
return None return None
return self.fee_detection_from_trades( return self.fee_detection_from_trades(
trade, order, order_obj, order_amount, order.get('trades', [])) trade, order, order_obj, order_amount, order.get('trades', []))
@ -1892,8 +1898,8 @@ class FreqtradeBot(LoggingMixin):
raise DependencyException("Half bought? Amounts don't match") raise DependencyException("Half bought? Amounts don't match")
if fee_abs != 0: if fee_abs != 0:
return self.apply_fee_conditional(trade, trade_base_currency, return self.apply_fee_conditional(
amount=amount, fee_abs=fee_abs) trade, trade_base_currency, amount=amount, fee_abs=fee_abs, order_obj=order_obj)
return None return None
def get_valid_price(self, custom_price: float, proposed_price: float) -> float: def get_valid_price(self, custom_price: float, proposed_price: float) -> float:

View File

@ -4650,11 +4650,17 @@ def test_apply_fee_conditional(default_conf_usdt, fee, mocker,
fee_close=fee.return_value, fee_close=fee.return_value,
open_order_id="123456" open_order_id="123456"
) )
order = Order(
ft_order_side='buy',
order_id='100',
ft_pair=trade.pair,
ft_is_open=True,
)
freqtrade = get_patched_freqtradebot(mocker, default_conf_usdt) freqtrade = get_patched_freqtradebot(mocker, default_conf_usdt)
walletmock.reset_mock() walletmock.reset_mock()
# Amount is kept as is # Amount is kept as is
assert freqtrade.apply_fee_conditional(trade, 'LTC', amount, fee_abs) == 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