From 961b38636fa2ae7c8f4c9a97e5b90c83ff97c232 Mon Sep 17 00:00:00 2001 From: Rokas Kupstys Date: Thu, 22 Apr 2021 09:21:19 +0300 Subject: [PATCH] Remove explicit sell_flag parameter from SellCheckTuple. --- freqtrade/freqtradebot.py | 2 +- freqtrade/rpc/rpc.py | 2 +- freqtrade/strategy/interface.py | 26 ++++++++++++++------------ tests/test_freqtradebot.py | 24 ++++++++++++------------ tests/test_integration.py | 14 +++++++------- 5 files changed, 35 insertions(+), 33 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 7888e64bc..08c69bb53 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -851,7 +851,7 @@ class FreqtradeBot(LoggingMixin): 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( - sell_flag=True, sell_type=SellType.EMERGENCY_SELL)) + sell_type=SellType.EMERGENCY_SELL)) except ExchangeError: trade.stoploss_order_id = None diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index 957f31b63..fd97ad7d4 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -554,7 +554,7 @@ class RPC: if not fully_canceled: # Get current rate and execute sell current_rate = self._freqtrade.get_sell_rate(trade.pair, False) - sell_reason = SellCheckTuple(sell_flag=True, sell_type=SellType.FORCE_SELL) + sell_reason = SellCheckTuple(sell_type=SellType.FORCE_SELL) self._freqtrade.execute_sell(trade, current_rate, sell_reason) # ---- EOF def _exec_forcesell ---- diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index c73574729..bc8b3e59f 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -58,15 +58,17 @@ class SellCheckTuple(object): """ NamedTuple for Sell type + reason """ - sell_flag: bool # TODO: Remove? sell_type: SellType sell_reason: Optional[str] - def __init__(self, sell_flag: bool, sell_type: SellType, sell_reason: Optional[str] = None): - self.sell_flag = sell_flag + def __init__(self, sell_type: SellType, sell_reason: Optional[str] = None): self.sell_type = sell_type self.sell_reason = sell_reason or sell_type.value + @property + def sell_flag(self): + return self.sell_type != SellType.NONE + class IStrategy(ABC, HyperStrategyMixin): """ @@ -593,25 +595,25 @@ class IStrategy(ABC, HyperStrategyMixin): # Sell-signal # Stoploss if roi_reached and stoplossflag.sell_type != SellType.STOP_LOSS: - logger.debug(f"{trade.pair} - Required profit reached. sell_flag=True, " + logger.debug(f"{trade.pair} - Required profit reached. " f"sell_type=SellType.ROI") - return SellCheckTuple(sell_flag=True, sell_type=SellType.ROI) + return SellCheckTuple(sell_type=SellType.ROI) if sell_signal != SellType.NONE: - logger.debug(f"{trade.pair} - Sell signal received. sell_flag=True, " + logger.debug(f"{trade.pair} - Sell signal received. " f"sell_type=SellType.{sell_signal.name}" + (f", custom_reason={custom_reason}" if custom_reason else "")) - return SellCheckTuple(sell_flag=True, sell_type=sell_signal, sell_reason=custom_reason) + return SellCheckTuple(sell_type=sell_signal, sell_reason=custom_reason) if stoplossflag.sell_flag: - logger.debug(f"{trade.pair} - Stoploss hit. sell_flag=True, " + logger.debug(f"{trade.pair} - Stoploss hit. " f"sell_type={stoplossflag.sell_type}") return stoplossflag # This one is noisy, commented out... - # logger.debug(f"{trade.pair} - No sell signal. sell_flag=False") - return SellCheckTuple(sell_flag=False, sell_type=SellType.NONE) + # logger.debug(f"{trade.pair} - No sell signal.") + return SellCheckTuple(sell_type=SellType.NONE) def stop_loss_reached(self, current_rate: float, trade: Trade, current_time: datetime, current_profit: float, @@ -675,9 +677,9 @@ class IStrategy(ABC, HyperStrategyMixin): logger.debug(f"{trade.pair} - Trailing stop saved " f"{trade.stop_loss - trade.initial_stop_loss:.6f}") - return SellCheckTuple(sell_flag=True, sell_type=sell_type) + return SellCheckTuple(sell_type=sell_type) - return SellCheckTuple(sell_flag=False, sell_type=SellType.NONE) + return SellCheckTuple(sell_type=SellType.NONE) def min_roi_reached_entry(self, trade_dur: int) -> Tuple[Optional[int], Optional[float]]: """ diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index aecff95ee..7a2f6a1ed 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -1973,7 +1973,7 @@ def test_handle_trade_roi(default_conf, ticker, limit_buy_order_open, # if ROI is reached we must sell patch_get_signal(freqtrade, value=(False, True)) assert freqtrade.handle_trade(trade) - assert log_has("ETH/BTC - Required profit reached. sell_flag=True, sell_type=SellType.ROI", + assert log_has("ETH/BTC - Required profit reached. sell_type=SellType.ROI", caplog) @@ -2002,7 +2002,7 @@ def test_handle_trade_use_sell_signal( patch_get_signal(freqtrade, value=(False, True)) assert freqtrade.handle_trade(trade) - assert log_has("ETH/BTC - Sell signal received. sell_flag=True, sell_type=SellType.SELL_SIGNAL", + assert log_has("ETH/BTC - Sell signal received. sell_type=SellType.SELL_SIGNAL", caplog) @@ -2607,7 +2607,7 @@ def test_execute_sell_up(default_conf, ticker, fee, ticker_sell_up, mocker) -> N ) # Prevented sell ... freqtrade.execute_sell(trade=trade, limit=ticker_sell_up()['bid'], - sell_reason=SellCheckTuple(sell_flag=True, sell_type=SellType.ROI)) + sell_reason=SellCheckTuple(sell_type=SellType.ROI)) assert rpc_mock.call_count == 0 assert freqtrade.strategy.confirm_trade_exit.call_count == 1 @@ -2615,7 +2615,7 @@ def test_execute_sell_up(default_conf, ticker, fee, ticker_sell_up, mocker) -> N freqtrade.strategy.confirm_trade_exit = MagicMock(return_value=True) freqtrade.execute_sell(trade=trade, limit=ticker_sell_up()['bid'], - sell_reason=SellCheckTuple(sell_flag=True, sell_type=SellType.ROI)) + sell_reason=SellCheckTuple(sell_type=SellType.ROI)) assert freqtrade.strategy.confirm_trade_exit.call_count == 1 assert rpc_mock.call_count == 1 @@ -2667,7 +2667,7 @@ def test_execute_sell_down(default_conf, ticker, fee, ticker_sell_down, mocker) ) freqtrade.execute_sell(trade=trade, limit=ticker_sell_down()['bid'], - sell_reason=SellCheckTuple(sell_flag=True, sell_type=SellType.STOP_LOSS)) + sell_reason=SellCheckTuple(sell_type=SellType.STOP_LOSS)) assert rpc_mock.call_count == 2 last_msg = rpc_mock.call_args_list[-1][0][0] @@ -2724,7 +2724,7 @@ def test_execute_sell_down_stoploss_on_exchange_dry_run(default_conf, ticker, fe trade.stop_loss = 0.00001099 * 0.99 freqtrade.execute_sell(trade=trade, limit=ticker_sell_down()['bid'], - sell_reason=SellCheckTuple(sell_flag=True, sell_type=SellType.STOP_LOSS)) + sell_reason=SellCheckTuple(sell_type=SellType.STOP_LOSS)) assert rpc_mock.call_count == 2 last_msg = rpc_mock.call_args_list[-1][0][0] @@ -2776,7 +2776,7 @@ def test_execute_sell_sloe_cancel_exception(mocker, default_conf, ticker, fee, c trade.stoploss_order_id = "abcd" freqtrade.execute_sell(trade=trade, limit=1234, - sell_reason=SellCheckTuple(sell_flag=True, sell_type=SellType.STOP_LOSS)) + sell_reason=SellCheckTuple(sell_type=SellType.STOP_LOSS)) assert sellmock.call_count == 1 assert log_has('Could not cancel stoploss order abcd', caplog) @@ -2826,7 +2826,7 @@ def test_execute_sell_with_stoploss_on_exchange(default_conf, ticker, fee, ticke ) freqtrade.execute_sell(trade=trade, limit=ticker_sell_up()['bid'], - sell_reason=SellCheckTuple(sell_flag=True, sell_type=SellType.STOP_LOSS)) + sell_reason=SellCheckTuple(sell_type=SellType.STOP_LOSS)) trade = Trade.query.first() assert trade @@ -2932,7 +2932,7 @@ 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_flag=True, sell_type=SellType.ROI)) + sell_reason=SellCheckTuple(sell_type=SellType.ROI)) assert not trade.is_open assert trade.close_profit == 0.0620716 @@ -2986,7 +2986,7 @@ def test_execute_sell_insufficient_funds_error(default_conf, ticker, fee, fetch_ticker=ticker_sell_up ) - sell_reason = SellCheckTuple(sell_flag=True, sell_type=SellType.ROI) + sell_reason = SellCheckTuple(sell_type=SellType.ROI) assert not freqtrade.execute_sell(trade=trade, limit=ticker_sell_up()['bid'], sell_reason=sell_reason) assert mock_insuf.call_count == 1 @@ -3081,7 +3081,7 @@ def test_sell_profit_only_enable_loss(default_conf, limit_buy_order, limit_buy_o freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) freqtrade.strategy.stop_loss_reached = MagicMock(return_value=SellCheckTuple( - sell_flag=False, sell_type=SellType.NONE)) + sell_type=SellType.NONE)) freqtrade.enter_positions() trade = Trade.query.first() @@ -3230,7 +3230,7 @@ def test_locked_pairs(default_conf, ticker, fee, ticker_sell_down, mocker, caplo ) freqtrade.execute_sell(trade=trade, limit=ticker_sell_down()['bid'], - sell_reason=SellCheckTuple(sell_flag=True, sell_type=SellType.STOP_LOSS)) + 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 be0dd1137..217910961 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -51,8 +51,8 @@ def test_may_execute_sell_stoploss_on_exchange_multi(default_conf, ticker, fee, side_effect=[stoploss_order_closed, stoploss_order_open, stoploss_order_open]) # 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)] + SellCheckTuple(sell_type=SellType.NONE), + SellCheckTuple(sell_type=SellType.SELL_SIGNAL)] ) cancel_order_mock = MagicMock() mocker.patch('freqtrade.exchange.Binance.stoploss', stoploss) @@ -156,11 +156,11 @@ def test_forcebuy_last_unlimited(default_conf, ticker, fee, limit_buy_order, moc _notify_sell=MagicMock(), ) should_sell_mock = MagicMock(side_effect=[ - SellCheckTuple(sell_flag=False, sell_type=SellType.NONE), - SellCheckTuple(sell_flag=True, sell_type=SellType.SELL_SIGNAL), - SellCheckTuple(sell_flag=False, sell_type=SellType.NONE), - SellCheckTuple(sell_flag=False, sell_type=SellType.NONE), - SellCheckTuple(sell_flag=None, sell_type=SellType.NONE)] + SellCheckTuple(sell_type=SellType.NONE), + SellCheckTuple(sell_type=SellType.SELL_SIGNAL), + SellCheckTuple(sell_type=SellType.NONE), + SellCheckTuple(sell_type=SellType.NONE), + SellCheckTuple(sell_type=SellType.NONE)] ) mocker.patch("freqtrade.strategy.interface.IStrategy.should_sell", should_sell_mock)