diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index d60d19937..8c6bca653 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -2541,6 +2541,13 @@ def test_may_execute_sell_stoploss_on_exchange_multi(default_conf, ticker, fee, limit_buy_order, markets, mocker) -> None: + """ + Tests workflow of selling stoploss_on_exchange. + Sells + * first trade as stoploss + * 2nd trade is kept + * 3rd trade is sold via sell-signal + """ default_conf['max_open_trades'] = 3 default_conf['exchange']['name'] = 'binance' patch_RPCManager(mocker) @@ -2548,9 +2555,7 @@ def test_may_execute_sell_stoploss_on_exchange_multi(default_conf, stoploss_limit = { 'id': 123, - 'info': { - 'foo': 'bar' - } + 'info': {} } stoploss_order_open = { "id": "123", @@ -2575,8 +2580,12 @@ def test_may_execute_sell_stoploss_on_exchange_multi(default_conf, # Sell first trade based on stoploss, keep 2nd and 3rd trade open stoploss_order_mock = MagicMock( side_effect=[stoploss_order_closed, stoploss_order_open, stoploss_order_open]) - create_sl_mock = MagicMock(return_value=True) - + # Sell 3rd trade (not called for the first trade) + should_sell_mock = MagicMock(side_effect=[ + SellCheckTuple(sell_flag=False, sell_type=SellType.NONE), + SellCheckTuple(sell_flag=True, sell_type=SellType.SELL_SIGNAL)] + ) + cancel_order_mock = MagicMock() mocker.patch('freqtrade.exchange.Binance.stoploss_limit', stoploss_limit) mocker.patch.multiple( 'freqtrade.exchange.Exchange', @@ -2586,26 +2595,29 @@ def test_may_execute_sell_stoploss_on_exchange_multi(default_conf, symbol_amount_prec=lambda s, x, y: y, symbol_price_prec=lambda s, x, y: y, get_order=stoploss_order_mock, + cancel_order=cancel_order_mock, ) - # Sell 3rd trade (not called for the first trade) - handle_trade_mock = MagicMock(side_effect=[False, True]) + wallets_mock = MagicMock() mocker.patch.multiple( 'freqtrade.freqtradebot.FreqtradeBot', - handle_trade=handle_trade_mock, - create_stoploss_order=create_sl_mock, + create_stoploss_order=MagicMock(return_value=True), update_trade_state=MagicMock(), _notify_sell=MagicMock(), ) + mocker.patch("freqtrade.strategy.interface.IStrategy.should_sell", should_sell_mock) mocker.patch("freqtrade.wallets.Wallets.update", wallets_mock) freqtrade = FreqtradeBot(default_conf) freqtrade.strategy.order_types['stoploss_on_exchange'] = True + # Switch ordertype to market to close trade immediately + freqtrade.strategy.order_types['sell'] = 'market' patch_get_signal(freqtrade) # Create some test data freqtrade.create_trades() wallets_mock.reset_mock() + Trade.session = MagicMock() trades = Trade.query.all() # Make sure stoploss-order is open and trade is bought (since we mock update_trade_state) @@ -2614,16 +2626,25 @@ def test_may_execute_sell_stoploss_on_exchange_multi(default_conf, trade.open_order_id = None freqtrade.process_maybe_execute_sells(trades) - assert handle_trade_mock.call_count == 2 + assert should_sell_mock.call_count == 2 + + # Only order for 3rd trade needs to be cancelled + assert cancel_order_mock.call_count == 1 + # Wallets should only be called once per sell cycle assert wallets_mock.call_count == 1 trade = trades[0] assert trade.sell_reason == SellType.STOPLOSS_ON_EXCHANGE.value assert not trade.is_open + trade = trades[1] assert not trade.sell_reason assert trade.is_open + trade = trades[2] + assert trade.sell_reason == SellType.SELL_SIGNAL.value + assert not trade.is_open + def test_execute_sell_market_order(default_conf, ticker, fee, ticker_sell_up, markets, mocker) -> None: