diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index d92156ef7..a7451d632 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -745,7 +745,7 @@ class FreqtradeBot(LoggingMixin): trade.stoploss_order_id = None logger.error(f'Unable to place a stoploss order on exchange. {e}') logger.warning('Selling the trade forcefully') - self.execute_sell(trade, trade.stop_loss, sell_reason=SellCheckTuple( + self.execute_trade_exit(trade, trade.stop_loss, sell_reason=SellCheckTuple( sell_type=SellType.EMERGENCY_SELL)) except ExchangeError: @@ -863,7 +863,7 @@ class FreqtradeBot(LoggingMixin): if should_sell.sell_flag: logger.info(f'Executing Sell for {trade.pair}. Reason: {should_sell.sell_type}') - self.execute_sell(trade, sell_rate, should_sell) + self.execute_trade_exit(trade, sell_rate, should_sell) return True return False @@ -1064,9 +1064,9 @@ class FreqtradeBot(LoggingMixin): raise DependencyException( f"Not enough amount to sell. Trade-amount: {amount}, Wallet: {wallet_amount}") - def execute_sell(self, trade: Trade, limit: float, sell_reason: SellCheckTuple) -> bool: + def execute_trade_exit(self, trade: Trade, limit: float, sell_reason: SellCheckTuple) -> bool: """ - Executes a limit sell for the given trade and limit + Executes a trade exit for the given trade and limit :param trade: Trade instance :param limit: limit rate for the sell order :param sell_reason: Reason the sell was triggered diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index 51bf0ab3a..95a37452b 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -557,7 +557,7 @@ class RPC: current_rate = self._freqtrade.exchange.get_rate( trade.pair, refresh=False, side="sell") sell_reason = SellCheckTuple(sell_type=SellType.FORCE_SELL) - self._freqtrade.execute_sell(trade, current_rate, sell_reason) + self._freqtrade.execute_trade_exit(trade, current_rate, sell_reason) # ---- EOF def _exec_forcesell ---- if self._freqtrade.state != State.RUNNING: diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 9a5a537ef..75b67e59c 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -2007,7 +2007,7 @@ def test_handle_trade_roi(default_conf, ticker, limit_buy_order_open, trade = Trade.query.first() trade.is_open = True - # FIX: sniffing logs, suggest handle_trade should not execute_sell + # FIX: sniffing logs, suggest handle_trade should not execute_trade_exit # instead that responsibility should be moved out of handle_trade(), # we might just want to check if we are in a sell condition without # executing @@ -2633,7 +2633,7 @@ def test_handle_cancel_sell_cancel_exception(mocker, default_conf) -> None: assert freqtrade.handle_cancel_sell(trade, order, reason) == 'error cancelling order' -def test_execute_sell_up(default_conf, ticker, fee, ticker_sell_up, mocker) -> None: +def test_execute_trade_exit_up(default_conf, ticker, fee, ticker_sell_up, mocker) -> None: rpc_mock = patch_RPCManager(mocker) patch_exchange(mocker) mocker.patch.multiple( @@ -2661,16 +2661,16 @@ def test_execute_sell_up(default_conf, ticker, fee, ticker_sell_up, mocker) -> N fetch_ticker=ticker_sell_up ) # Prevented sell ... - freqtrade.execute_sell(trade=trade, limit=ticker_sell_up()['bid'], - sell_reason=SellCheckTuple(sell_type=SellType.ROI)) + freqtrade.execute_trade_exit(trade=trade, limit=ticker_sell_up()['bid'], + sell_reason=SellCheckTuple(sell_type=SellType.ROI)) assert rpc_mock.call_count == 0 assert freqtrade.strategy.confirm_trade_exit.call_count == 1 # Repatch with true freqtrade.strategy.confirm_trade_exit = MagicMock(return_value=True) - freqtrade.execute_sell(trade=trade, limit=ticker_sell_up()['bid'], - sell_reason=SellCheckTuple(sell_type=SellType.ROI)) + freqtrade.execute_trade_exit(trade=trade, limit=ticker_sell_up()['bid'], + sell_reason=SellCheckTuple(sell_type=SellType.ROI)) assert freqtrade.strategy.confirm_trade_exit.call_count == 1 assert rpc_mock.call_count == 1 @@ -2697,7 +2697,7 @@ def test_execute_sell_up(default_conf, ticker, fee, ticker_sell_up, mocker) -> N } == last_msg -def test_execute_sell_down(default_conf, ticker, fee, ticker_sell_down, mocker) -> None: +def test_execute_trade_exit_down(default_conf, ticker, fee, ticker_sell_down, mocker) -> None: rpc_mock = patch_RPCManager(mocker) patch_exchange(mocker) mocker.patch.multiple( @@ -2722,8 +2722,8 @@ def test_execute_sell_down(default_conf, ticker, fee, ticker_sell_down, mocker) fetch_ticker=ticker_sell_down ) - freqtrade.execute_sell(trade=trade, limit=ticker_sell_down()['bid'], - sell_reason=SellCheckTuple(sell_type=SellType.STOP_LOSS)) + freqtrade.execute_trade_exit(trade=trade, limit=ticker_sell_down()['bid'], + sell_reason=SellCheckTuple(sell_type=SellType.STOP_LOSS)) assert rpc_mock.call_count == 2 last_msg = rpc_mock.call_args_list[-1][0][0] @@ -2749,7 +2749,8 @@ def test_execute_sell_down(default_conf, ticker, fee, ticker_sell_down, mocker) } == last_msg -def test_execute_sell_custom_exit_price(default_conf, ticker, fee, ticker_sell_up, mocker) -> None: +def test_execute_trade_exit_custom_exit_price(default_conf, ticker, fee, ticker_sell_up, + mocker) -> None: rpc_mock = patch_RPCManager(mocker) patch_exchange(mocker) mocker.patch.multiple( @@ -2782,8 +2783,8 @@ def test_execute_sell_custom_exit_price(default_conf, ticker, fee, ticker_sell_u # Set a custom exit price freqtrade.strategy.custom_exit_price = lambda **kwargs: 1.170e-05 - freqtrade.execute_sell(trade=trade, limit=ticker_sell_up()['bid'], - sell_reason=SellCheckTuple(sell_type=SellType.SELL_SIGNAL)) + freqtrade.execute_trade_exit(trade=trade, limit=ticker_sell_up()['bid'], + sell_reason=SellCheckTuple(sell_type=SellType.SELL_SIGNAL)) # Sell price must be different to default bid price @@ -2813,8 +2814,8 @@ def test_execute_sell_custom_exit_price(default_conf, ticker, fee, ticker_sell_u } == last_msg -def test_execute_sell_down_stoploss_on_exchange_dry_run(default_conf, ticker, fee, - ticker_sell_down, mocker) -> None: +def test_execute_trade_exit_down_stoploss_on_exchange_dry_run(default_conf, ticker, fee, + ticker_sell_down, mocker) -> None: rpc_mock = patch_RPCManager(mocker) patch_exchange(mocker) mocker.patch.multiple( @@ -2844,8 +2845,8 @@ def test_execute_sell_down_stoploss_on_exchange_dry_run(default_conf, ticker, fe # Setting trade stoploss to 0.01 trade.stop_loss = 0.00001099 * 0.99 - freqtrade.execute_sell(trade=trade, limit=ticker_sell_down()['bid'], - sell_reason=SellCheckTuple(sell_type=SellType.STOP_LOSS)) + freqtrade.execute_trade_exit(trade=trade, limit=ticker_sell_down()['bid'], + sell_reason=SellCheckTuple(sell_type=SellType.STOP_LOSS)) assert rpc_mock.call_count == 2 last_msg = rpc_mock.call_args_list[-1][0][0] @@ -2872,7 +2873,8 @@ def test_execute_sell_down_stoploss_on_exchange_dry_run(default_conf, ticker, fe } == last_msg -def test_execute_sell_sloe_cancel_exception(mocker, default_conf, ticker, fee, caplog) -> None: +def test_execute_trade_exit_sloe_cancel_exception( + mocker, default_conf, ticker, fee, caplog) -> None: freqtrade = get_patched_freqtradebot(mocker, default_conf) mocker.patch('freqtrade.exchange.Exchange.cancel_stoploss_order', side_effect=InvalidOrderException()) @@ -2899,14 +2901,14 @@ def test_execute_sell_sloe_cancel_exception(mocker, default_conf, ticker, fee, c freqtrade.config['dry_run'] = False trade.stoploss_order_id = "abcd" - freqtrade.execute_sell(trade=trade, limit=1234, - sell_reason=SellCheckTuple(sell_type=SellType.STOP_LOSS)) + freqtrade.execute_trade_exit(trade=trade, limit=1234, + sell_reason=SellCheckTuple(sell_type=SellType.STOP_LOSS)) assert create_order_mock.call_count == 2 assert log_has('Could not cancel stoploss order abcd', caplog) -def test_execute_sell_with_stoploss_on_exchange(default_conf, ticker, fee, ticker_sell_up, - mocker) -> None: +def test_execute_trade_exit_with_stoploss_on_exchange(default_conf, ticker, fee, ticker_sell_up, + mocker) -> None: default_conf['exchange']['name'] = 'binance' rpc_mock = patch_RPCManager(mocker) @@ -2950,8 +2952,8 @@ def test_execute_sell_with_stoploss_on_exchange(default_conf, ticker, fee, ticke fetch_ticker=ticker_sell_up ) - freqtrade.execute_sell(trade=trade, limit=ticker_sell_up()['bid'], - sell_reason=SellCheckTuple(sell_type=SellType.STOP_LOSS)) + freqtrade.execute_trade_exit(trade=trade, limit=ticker_sell_up()['bid'], + sell_reason=SellCheckTuple(sell_type=SellType.STOP_LOSS)) trade = Trade.query.first() assert trade @@ -2959,8 +2961,8 @@ def test_execute_sell_with_stoploss_on_exchange(default_conf, ticker, fee, ticke assert rpc_mock.call_count == 3 -def test_may_execute_sell_after_stoploss_on_exchange_hit(default_conf, ticker, fee, - mocker) -> None: +def test_may_execute_trade_exit_after_stoploss_on_exchange_hit(default_conf, ticker, fee, + mocker) -> None: default_conf['exchange']['name'] = 'binance' rpc_mock = patch_RPCManager(mocker) patch_exchange(mocker) @@ -3031,8 +3033,8 @@ def test_may_execute_sell_after_stoploss_on_exchange_hit(default_conf, ticker, f assert rpc_mock.call_args_list[2][0][0]['type'] == RPCMessageType.SELL -def test_execute_sell_market_order(default_conf, ticker, fee, - ticker_sell_up, mocker) -> None: +def test_execute_trade_exit_market_order(default_conf, ticker, fee, + ticker_sell_up, mocker) -> None: rpc_mock = patch_RPCManager(mocker) patch_exchange(mocker) mocker.patch.multiple( @@ -3058,8 +3060,8 @@ def test_execute_sell_market_order(default_conf, ticker, fee, ) freqtrade.config['order_types']['sell'] = 'market' - freqtrade.execute_sell(trade=trade, limit=ticker_sell_up()['bid'], - sell_reason=SellCheckTuple(sell_type=SellType.ROI)) + freqtrade.execute_trade_exit(trade=trade, limit=ticker_sell_up()['bid'], + sell_reason=SellCheckTuple(sell_type=SellType.ROI)) assert not trade.is_open assert trade.close_profit == 0.0620716 @@ -3089,8 +3091,8 @@ def test_execute_sell_market_order(default_conf, ticker, fee, } == last_msg -def test_execute_sell_insufficient_funds_error(default_conf, ticker, fee, - ticker_sell_up, mocker) -> None: +def test_execute_trade_exit_insufficient_funds_error(default_conf, ticker, fee, + ticker_sell_up, mocker) -> None: freqtrade = get_patched_freqtradebot(mocker, default_conf) mock_insuf = mocker.patch('freqtrade.freqtradebot.FreqtradeBot.handle_insufficient_funds') mocker.patch.multiple( @@ -3117,8 +3119,8 @@ def test_execute_sell_insufficient_funds_error(default_conf, ticker, fee, ) sell_reason = SellCheckTuple(sell_type=SellType.ROI) - assert not freqtrade.execute_sell(trade=trade, limit=ticker_sell_up()['bid'], - sell_reason=sell_reason) + assert not freqtrade.execute_trade_exit(trade=trade, limit=ticker_sell_up()['bid'], + sell_reason=sell_reason) assert mock_insuf.call_count == 1 @@ -3374,8 +3376,8 @@ def test_locked_pairs(default_conf, ticker, fee, ticker_sell_down, mocker, caplo fetch_ticker=ticker_sell_down ) - freqtrade.execute_sell(trade=trade, limit=ticker_sell_down()['bid'], - sell_reason=SellCheckTuple(sell_type=SellType.STOP_LOSS)) + freqtrade.execute_trade_exit(trade=trade, limit=ticker_sell_down()['bid'], + sell_reason=SellCheckTuple(sell_type=SellType.STOP_LOSS)) trade.close(ticker_sell_down()['bid']) assert freqtrade.strategy.is_pair_locked(trade.pair) diff --git a/tests/test_integration.py b/tests/test_integration.py index b12959a03..215927098 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -9,7 +9,7 @@ from freqtrade.strategy.interface import SellCheckTuple from tests.conftest import get_patched_freqtradebot, patch_get_signal -def test_may_execute_sell_stoploss_on_exchange_multi(default_conf, ticker, fee, +def test_may_execute_exit_stoploss_on_exchange_multi(default_conf, ticker, fee, limit_buy_order, mocker) -> None: """ Tests workflow of selling stoploss_on_exchange.