Update buy_timeout and sell_timeout methods

This commit is contained in:
Matthias
2022-03-25 19:46:56 +01:00
parent 973644de66
commit 6f1b14c013
11 changed files with 175 additions and 106 deletions

View File

@@ -29,3 +29,21 @@ class TestStrategyImplementCustomSell(TestStrategyNoImplementSell):
current_rate: float, current_profit: float,
**kwargs):
return False
class TestStrategyImplementBuyTimeout(TestStrategyNoImplementSell):
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
return super().populate_exit_trend(dataframe, metadata)
def check_buy_timeout(self, pair: str, trade, order: dict,
current_time: datetime, **kwargs) -> bool:
return False
class TestStrategyImplementSellTimeout(TestStrategyNoImplementSell):
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
return super().populate_exit_trend(dataframe, metadata)
def check_sell_timeout(self, pair: str, trade, order: dict,
current_time: datetime, **kwargs) -> bool:
return False

View File

@@ -418,11 +418,20 @@ def test_missing_implements(default_conf):
StrategyResolver.load_strategy(default_conf)
default_conf['strategy'] = 'TestStrategyImplementCustomSell'
with pytest.raises(OperationalException,
match=r"Please migrate your implementation of `custom_sell`.*"):
StrategyResolver.load_strategy(default_conf)
default_conf['strategy'] = 'TestStrategyImplementBuyTimeout'
with pytest.raises(OperationalException,
match=r"Please migrate your implementation of `check_buy_timeout`.*"):
StrategyResolver.load_strategy(default_conf)
default_conf['strategy'] = 'TestStrategyImplementSellTimeout'
with pytest.raises(OperationalException,
match=r"Please migrate your implementation of `check_sell_timeout`.*"):
StrategyResolver.load_strategy(default_conf)
@pytest.mark.filterwarnings("ignore:deprecated")
def test_call_deprecated_function(result, default_conf, caplog):

View File

@@ -2370,7 +2370,7 @@ def test_bot_loop_start_called_once(mocker, default_conf_usdt, caplog):
@pytest.mark.parametrize("is_short", [False, True])
def test_check_handle_timedout_buy_usercustom(
def test_check_handle_timedout_entry_usercustom(
default_conf_usdt, ticker_usdt, limit_buy_order_old, open_trade,
limit_sell_order_old, fee, mocker, is_short
) -> None:
@@ -2406,34 +2406,23 @@ def test_check_handle_timedout_buy_usercustom(
assert cancel_order_mock.call_count == 0
# Return false - trade remains open
if is_short:
freqtrade.strategy.check_sell_timeout = MagicMock(return_value=False)
else:
freqtrade.strategy.check_buy_timeout = MagicMock(return_value=False)
freqtrade.strategy.check_entry_timeout = MagicMock(return_value=False)
freqtrade.check_handle_timedout()
assert cancel_order_mock.call_count == 0
trades = Trade.query.filter(Trade.open_order_id.is_(open_trade.open_order_id)).all()
nb_trades = len(trades)
assert nb_trades == 1
if is_short:
assert freqtrade.strategy.check_sell_timeout.call_count == 1
# Raise Keyerror ... (no impact on trade)
freqtrade.strategy.check_sell_timeout = MagicMock(side_effect=KeyError)
else:
assert freqtrade.strategy.check_buy_timeout.call_count == 1
freqtrade.strategy.check_buy_timeout = MagicMock(side_effect=KeyError)
assert freqtrade.strategy.check_entry_timeout.call_count == 1
freqtrade.strategy.check_entry_timeout = MagicMock(side_effect=KeyError)
freqtrade.check_handle_timedout()
assert cancel_order_mock.call_count == 0
trades = Trade.query.filter(Trade.open_order_id.is_(open_trade.open_order_id)).all()
nb_trades = len(trades)
assert nb_trades == 1
if is_short:
assert freqtrade.strategy.check_sell_timeout.call_count == 1
freqtrade.strategy.check_sell_timeout = MagicMock(return_value=True)
else:
assert freqtrade.strategy.check_buy_timeout.call_count == 1
freqtrade.strategy.check_buy_timeout = MagicMock(return_value=True)
assert freqtrade.strategy.check_entry_timeout.call_count == 1
freqtrade.strategy.check_entry_timeout = MagicMock(return_value=True)
# Trade should be closed since the function returns true
freqtrade.check_handle_timedout()
assert cancel_order_wr_mock.call_count == 1
@@ -2441,10 +2430,7 @@ def test_check_handle_timedout_buy_usercustom(
trades = Trade.query.filter(Trade.open_order_id.is_(open_trade.open_order_id)).all()
nb_trades = len(trades)
assert nb_trades == 0
if is_short:
assert freqtrade.strategy.check_sell_timeout.call_count == 1
else:
assert freqtrade.strategy.check_buy_timeout.call_count == 1
assert freqtrade.strategy.check_entry_timeout.call_count == 1
@pytest.mark.parametrize("is_short", [False, True])
@@ -2472,9 +2458,9 @@ def test_check_handle_timedout_buy(
Trade.query.session.add(open_trade)
if is_short:
freqtrade.strategy.check_sell_timeout = MagicMock(return_value=False)
freqtrade.strategy.check_exit_timeout = MagicMock(return_value=False)
else:
freqtrade.strategy.check_buy_timeout = MagicMock(return_value=False)
freqtrade.strategy.check_entry_timeout = MagicMock(return_value=False)
# check it does cancel buy orders over the time limit
freqtrade.check_handle_timedout()
assert cancel_order_mock.call_count == 1
@@ -2484,9 +2470,9 @@ def test_check_handle_timedout_buy(
assert nb_trades == 0
# Custom user buy-timeout is never called
if is_short:
assert freqtrade.strategy.check_sell_timeout.call_count == 0
assert freqtrade.strategy.check_exit_timeout.call_count == 0
else:
assert freqtrade.strategy.check_buy_timeout.call_count == 0
assert freqtrade.strategy.check_entry_timeout.call_count == 0
@pytest.mark.parametrize("is_short", [False, True])
@@ -2553,7 +2539,7 @@ def test_check_handle_timedout_buy_exception(
@pytest.mark.parametrize("is_short", [False, True])
def test_check_handle_timedout_sell_usercustom(
def test_check_handle_timedout_exit_usercustom(
default_conf_usdt, ticker_usdt, limit_sell_order_old, mocker,
is_short, open_trade_usdt, caplog
) -> None:
@@ -2585,35 +2571,35 @@ def test_check_handle_timedout_sell_usercustom(
freqtrade.check_handle_timedout()
assert cancel_order_mock.call_count == 0
freqtrade.strategy.check_sell_timeout = MagicMock(return_value=False)
freqtrade.strategy.check_buy_timeout = MagicMock(return_value=False)
freqtrade.strategy.check_exit_timeout = MagicMock(return_value=False)
freqtrade.strategy.check_entry_timeout = MagicMock(return_value=False)
# Return false - No impact
freqtrade.check_handle_timedout()
assert cancel_order_mock.call_count == 0
assert rpc_mock.call_count == 0
assert open_trade_usdt.is_open is False
assert freqtrade.strategy.check_sell_timeout.call_count == (0 if is_short else 1)
assert freqtrade.strategy.check_buy_timeout.call_count == (1 if is_short else 0)
assert freqtrade.strategy.check_exit_timeout.call_count == 1
assert freqtrade.strategy.check_entry_timeout.call_count == 0
freqtrade.strategy.check_sell_timeout = MagicMock(side_effect=KeyError)
freqtrade.strategy.check_buy_timeout = MagicMock(side_effect=KeyError)
freqtrade.strategy.check_exit_timeout = MagicMock(side_effect=KeyError)
freqtrade.strategy.check_entry_timeout = MagicMock(side_effect=KeyError)
# Return Error - No impact
freqtrade.check_handle_timedout()
assert cancel_order_mock.call_count == 0
assert rpc_mock.call_count == 0
assert open_trade_usdt.is_open is False
assert freqtrade.strategy.check_sell_timeout.call_count == (0 if is_short else 1)
assert freqtrade.strategy.check_buy_timeout.call_count == (1 if is_short else 0)
assert freqtrade.strategy.check_exit_timeout.call_count == 1
assert freqtrade.strategy.check_entry_timeout.call_count == 0
# Return True - sells!
freqtrade.strategy.check_sell_timeout = MagicMock(return_value=True)
freqtrade.strategy.check_buy_timeout = MagicMock(return_value=True)
freqtrade.strategy.check_exit_timeout = MagicMock(return_value=True)
freqtrade.strategy.check_entry_timeout = MagicMock(return_value=True)
freqtrade.check_handle_timedout()
assert cancel_order_mock.call_count == 1
assert rpc_mock.call_count == 1
assert open_trade_usdt.is_open is True
assert freqtrade.strategy.check_sell_timeout.call_count == (0 if is_short else 1)
assert freqtrade.strategy.check_buy_timeout.call_count == (1 if is_short else 0)
assert freqtrade.strategy.check_exit_timeout.call_count == 1
assert freqtrade.strategy.check_entry_timeout.call_count == 0
# 2nd canceled trade - Fail execute sell
caplog.clear()
@@ -2665,16 +2651,16 @@ def test_check_handle_timedout_sell(
Trade.query.session.add(open_trade_usdt)
freqtrade.strategy.check_sell_timeout = MagicMock(return_value=False)
freqtrade.strategy.check_buy_timeout = MagicMock(return_value=False)
freqtrade.strategy.check_exit_timeout = MagicMock(return_value=False)
freqtrade.strategy.check_entry_timeout = MagicMock(return_value=False)
# check it does cancel sell orders over the time limit
freqtrade.check_handle_timedout()
assert cancel_order_mock.call_count == 1
assert rpc_mock.call_count == 1
assert open_trade_usdt.is_open is True
# Custom user sell-timeout is never called
assert freqtrade.strategy.check_sell_timeout.call_count == 0
assert freqtrade.strategy.check_buy_timeout.call_count == 0
assert freqtrade.strategy.check_exit_timeout.call_count == 0
assert freqtrade.strategy.check_entry_timeout.call_count == 0
@pytest.mark.parametrize("is_short", [False, True])