Add test for Generic behavior
This commit is contained in:
parent
7c464f3237
commit
2b5530217d
@ -552,13 +552,19 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
if stake_amount is not None and stake_amount < 0.0:
|
if stake_amount is not None and stake_amount < 0.0:
|
||||||
# We should decrease our position
|
# We should decrease our position
|
||||||
amount = abs(float(Decimal(stake_amount) / Decimal(current_exit_rate)))
|
amount = abs(float(Decimal(stake_amount) / Decimal(current_exit_rate)))
|
||||||
if (trade.amount - amount) * current_exit_rate < min_exit_stake:
|
|
||||||
logger.info('Remaining amount would be too small.')
|
|
||||||
return
|
|
||||||
if amount > trade.amount:
|
if amount > trade.amount:
|
||||||
|
# This is currently ineffective as remaining would become < min tradable
|
||||||
|
# Fixing this would require checking for 0.0 there -
|
||||||
|
# if we decide that this callback is allowed to "fully exit"
|
||||||
logger.info(
|
logger.info(
|
||||||
f"Adjusting amount to trade.amount as it is higher. {amount} > {trade.amount}")
|
f"Adjusting amount to trade.amount as it is higher. {amount} > {trade.amount}")
|
||||||
amount = trade.amount
|
amount = trade.amount
|
||||||
|
|
||||||
|
remaining = (trade.amount - amount) * current_exit_rate
|
||||||
|
if remaining < min_exit_stake:
|
||||||
|
logger.info(f'Remaining amount of {remaining} would be too small.')
|
||||||
|
return
|
||||||
|
|
||||||
self.execute_trade_exit(trade, current_exit_rate, exit_check=ExitCheckTuple(
|
self.execute_trade_exit(trade, current_exit_rate, exit_check=ExitCheckTuple(
|
||||||
exit_type=ExitType.PARTIAL_EXIT), sub_trade_amt=amount)
|
exit_type=ExitType.PARTIAL_EXIT), sub_trade_amt=amount)
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ from freqtrade.enums import ExitCheckTuple, ExitType
|
|||||||
from freqtrade.persistence import Trade
|
from freqtrade.persistence import Trade
|
||||||
from freqtrade.persistence.models import Order
|
from freqtrade.persistence.models import Order
|
||||||
from freqtrade.rpc.rpc import RPC
|
from freqtrade.rpc.rpc import RPC
|
||||||
from tests.conftest import get_patched_freqtradebot, patch_get_signal
|
from tests.conftest import get_patched_freqtradebot, log_has_re, patch_get_signal
|
||||||
|
|
||||||
|
|
||||||
def test_may_execute_exit_stoploss_on_exchange_multi(default_conf, ticker, fee,
|
def test_may_execute_exit_stoploss_on_exchange_multi(default_conf, ticker, fee,
|
||||||
@ -455,3 +455,60 @@ def test_dca_order_adjust(default_conf_usdt, ticker_usdt, fee, mocker) -> None:
|
|||||||
# Check the 2 filled orders equal the above amount
|
# Check the 2 filled orders equal the above amount
|
||||||
assert pytest.approx(trade.orders[1].amount) == 30.150753768
|
assert pytest.approx(trade.orders[1].amount) == 30.150753768
|
||||||
assert pytest.approx(trade.orders[-1].amount) == 61.538461232
|
assert pytest.approx(trade.orders[-1].amount) == 61.538461232
|
||||||
|
|
||||||
|
|
||||||
|
def test_dca_exiting(default_conf_usdt, ticker_usdt, fee, mocker, caplog) -> None:
|
||||||
|
default_conf_usdt['position_adjustment_enable'] = True
|
||||||
|
|
||||||
|
freqtrade = get_patched_freqtradebot(mocker, default_conf_usdt)
|
||||||
|
mocker.patch.multiple(
|
||||||
|
'freqtrade.exchange.Exchange',
|
||||||
|
fetch_ticker=ticker_usdt,
|
||||||
|
get_fee=fee,
|
||||||
|
amount_to_precision=lambda s, x, y: y,
|
||||||
|
price_to_precision=lambda s, x, y: y,
|
||||||
|
get_min_pair_stake_amount=MagicMock(return_value=10),
|
||||||
|
)
|
||||||
|
|
||||||
|
patch_get_signal(freqtrade)
|
||||||
|
freqtrade.enter_positions()
|
||||||
|
|
||||||
|
assert len(Trade.get_trades().all()) == 1
|
||||||
|
trade = Trade.get_trades().first()
|
||||||
|
assert len(trade.orders) == 1
|
||||||
|
assert pytest.approx(trade.stake_amount) == 60
|
||||||
|
assert pytest.approx(trade.amount) == 30.0
|
||||||
|
assert trade.open_rate == 2.0
|
||||||
|
|
||||||
|
# Too small size
|
||||||
|
freqtrade.strategy.adjust_trade_position = MagicMock(return_value=-59)
|
||||||
|
freqtrade.process()
|
||||||
|
trade = Trade.get_trades().first()
|
||||||
|
assert len(trade.orders) == 1
|
||||||
|
assert pytest.approx(trade.stake_amount) == 60
|
||||||
|
assert pytest.approx(trade.amount) == 30.0
|
||||||
|
assert log_has_re("Remaining amount of 1.6.* would be too small.", caplog)
|
||||||
|
|
||||||
|
freqtrade.strategy.adjust_trade_position = MagicMock(return_value=-20)
|
||||||
|
|
||||||
|
freqtrade.process()
|
||||||
|
trade = Trade.get_trades().first()
|
||||||
|
assert len(trade.orders) == 2
|
||||||
|
assert trade.orders[-1].ft_order_side == 'sell'
|
||||||
|
assert pytest.approx(trade.stake_amount) == 40.198
|
||||||
|
assert pytest.approx(trade.amount) == 20.099
|
||||||
|
assert trade.open_rate == 2.0
|
||||||
|
assert trade.is_open
|
||||||
|
caplog.clear()
|
||||||
|
|
||||||
|
# Sell more than what we got (we got ~20 coins left)
|
||||||
|
# First adjusts the amount to 20 - then rejects.
|
||||||
|
freqtrade.strategy.adjust_trade_position = MagicMock(return_value=-50)
|
||||||
|
freqtrade.process()
|
||||||
|
assert log_has_re("Adjusting amount to trade.amount as it is higher.*", caplog)
|
||||||
|
assert log_has_re("Remaining amount of 0.0 would be too small.", caplog)
|
||||||
|
trade = Trade.get_trades().first()
|
||||||
|
assert len(trade.orders) == 2
|
||||||
|
assert trade.orders[-1].ft_order_side == 'sell'
|
||||||
|
assert pytest.approx(trade.stake_amount) == 40.198
|
||||||
|
assert trade.is_open
|
||||||
|
Loading…
Reference in New Issue
Block a user