From 2124438202ffd757fa19ce389fc2ff1aec3d86f6 Mon Sep 17 00:00:00 2001 From: Sam Germain Date: Tue, 4 Jan 2022 23:03:58 -0600 Subject: [PATCH] SellCheckTuple -> ExitCheckTuple --- freqtrade/freqtradebot.py | 10 +++++----- freqtrade/optimize/backtesting.py | 4 ++-- freqtrade/rpc/rpc.py | 4 ++-- freqtrade/strategy/interface.py | 16 ++++++++-------- tests/strategy/test_interface.py | 4 ++-- tests/test_freqtradebot.py | 26 +++++++++++++------------- tests/test_integration.py | 16 ++++++++-------- 7 files changed, 40 insertions(+), 40 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index fe7ca21c0..5aa75674f 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -29,7 +29,7 @@ from freqtrade.plugins.pairlistmanager import PairListManager from freqtrade.plugins.protectionmanager import ProtectionManager from freqtrade.resolvers import ExchangeResolver, StrategyResolver from freqtrade.rpc import RPCManager -from freqtrade.strategy.interface import IStrategy, SellCheckTuple +from freqtrade.strategy.interface import IStrategy, ExitCheckTuple from freqtrade.strategy.strategy_wrapper import strategy_safe_wrapper from freqtrade.wallets import Wallets @@ -914,7 +914,7 @@ class FreqtradeBot(LoggingMixin): trade.stoploss_order_id = None logger.error(f'Unable to place a stoploss order on exchange. {e}') logger.warning('Exiting the trade forcefully') - self.execute_trade_exit(trade, trade.stop_loss, exit_reason=SellCheckTuple( + self.execute_trade_exit(trade, trade.stop_loss, exit_reason=ExitCheckTuple( exit_type=ExitType.EMERGENCY_SELL)) except ExchangeError: @@ -1030,7 +1030,7 @@ class FreqtradeBot(LoggingMixin): """ Check and execute trade exit """ - should_exit: SellCheckTuple = self.strategy.should_exit( + should_exit: ExitCheckTuple = self.strategy.should_exit( trade, exit_rate, datetime.now(timezone.utc), @@ -1102,7 +1102,7 @@ class FreqtradeBot(LoggingMixin): try: self.execute_trade_exit( trade, order.get('price'), - exit_reason=SellCheckTuple(exit_type=ExitType.EMERGENCY_SELL)) + exit_reason=ExitCheckTuple(exit_type=ExitType.EMERGENCY_SELL)) except DependencyException as exception: logger.warning( f'Unable to emergency sell trade {trade.pair}: {exception}') @@ -1266,7 +1266,7 @@ class FreqtradeBot(LoggingMixin): self, trade: Trade, limit: float, - exit_reason: SellCheckTuple, + exit_reason: ExitCheckTuple, *, exit_tag: Optional[str] = None, ordertype: Optional[str] = None, diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 9fe706357..060fbbd0b 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -28,7 +28,7 @@ from freqtrade.persistence import LocalTrade, PairLocks, Trade from freqtrade.plugins.pairlistmanager import PairListManager from freqtrade.plugins.protectionmanager import ProtectionManager from freqtrade.resolvers import ExchangeResolver, StrategyResolver -from freqtrade.strategy.interface import IStrategy, SellCheckTuple +from freqtrade.strategy.interface import IStrategy, ExitCheckTuple from freqtrade.strategy.strategy_wrapper import strategy_safe_wrapper from freqtrade.wallets import Wallets @@ -308,7 +308,7 @@ class Backtesting: processed[pair] = pair_data = None return data - def _get_close_rate(self, sell_row: Tuple, trade: LocalTrade, sell: SellCheckTuple, + def _get_close_rate(self, sell_row: Tuple, trade: LocalTrade, sell: ExitCheckTuple, trade_dur: int) -> float: """ Get close rate for backtesting result diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index 0800dde5c..33d225739 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -26,7 +26,7 @@ from freqtrade.persistence import PairLocks, Trade from freqtrade.persistence.models import PairLock from freqtrade.plugins.pairlist.pairlist_helpers import expand_pairlist from freqtrade.rpc.fiat_convert import CryptoToFiatConverter -from freqtrade.strategy.interface import SellCheckTuple +from freqtrade.strategy.interface import ExitCheckTuple logger = logging.getLogger(__name__) @@ -672,7 +672,7 @@ class RPC: closing_side = "buy" if trade.is_short else "sell" current_rate = self._freqtrade.exchange.get_rate( trade.pair, refresh=False, side=closing_side) - exit_reason = SellCheckTuple(exit_type=ExitType.FORCE_SELL) + exit_reason = ExitCheckTuple(exit_type=ExitType.FORCE_SELL) order_type = ordertype or self._freqtrade.strategy.order_types.get( "forcesell", self._freqtrade.strategy.order_types["sell"]) diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index a74c113b1..b79bffc9c 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -30,7 +30,7 @@ logger = logging.getLogger(__name__) CUSTOM_SELL_MAX_LENGTH = 64 -class SellCheckTuple: +class ExitCheckTuple: """ NamedTuple for Sell type + reason """ @@ -756,7 +756,7 @@ class IStrategy(ABC, HyperStrategyMixin): def should_exit(self, trade: Trade, rate: float, date: datetime, *, enter: bool, exit_: bool, low: float = None, high: float = None, - force_stoploss: float = 0) -> SellCheckTuple: + force_stoploss: float = 0) -> ExitCheckTuple: """ This function evaluates if one of the conditions required to trigger an exit order has been reached, which can either be a stop-loss, ROI or exit-signal. @@ -815,7 +815,7 @@ class IStrategy(ABC, HyperStrategyMixin): logger.debug(f"{trade.pair} - Sell signal received. " f"exit_type=ExitType.{exit_signal.name}" + (f", custom_reason={custom_reason}" if custom_reason else "")) - return SellCheckTuple(exit_type=exit_signal, exit_reason=custom_reason) + return ExitCheckTuple(exit_type=exit_signal, exit_reason=custom_reason) # Sequence: # Exit-signal @@ -823,7 +823,7 @@ class IStrategy(ABC, HyperStrategyMixin): # Stoploss if roi_reached and stoplossflag.exit_type != ExitType.STOP_LOSS: logger.debug(f"{trade.pair} - Required profit reached. exit_type=ExitType.ROI") - return SellCheckTuple(exit_type=ExitType.ROI) + return ExitCheckTuple(exit_type=ExitType.ROI) if stoplossflag.sell_flag: @@ -832,12 +832,12 @@ class IStrategy(ABC, HyperStrategyMixin): # This one is noisy, commented out... # logger.debug(f"{trade.pair} - No exit signal.") - return SellCheckTuple(exit_type=ExitType.NONE) + return ExitCheckTuple(exit_type=ExitType.NONE) def stop_loss_reached(self, current_rate: float, trade: Trade, current_time: datetime, current_profit: float, force_stoploss: float, low: float = None, - high: float = None) -> SellCheckTuple: + high: float = None) -> ExitCheckTuple: """ Based on current profit of the trade and configured (trailing) stoploss, decides to exit or not @@ -915,9 +915,9 @@ class IStrategy(ABC, HyperStrategyMixin): logger.debug(f"{trade.pair} - Trailing stop saved " f"{new_stoploss:.6f}") - return SellCheckTuple(exit_type=exit_type) + return ExitCheckTuple(exit_type=exit_type) - return SellCheckTuple(exit_type=ExitType.NONE) + return ExitCheckTuple(exit_type=ExitType.NONE) def min_roi_reached_entry(self, trade_dur: int) -> Tuple[Optional[int], Optional[float]]: """ diff --git a/tests/strategy/test_interface.py b/tests/strategy/test_interface.py index cba6d245e..e1ce5799b 100644 --- a/tests/strategy/test_interface.py +++ b/tests/strategy/test_interface.py @@ -18,7 +18,7 @@ from freqtrade.persistence import PairLocks, Trade from freqtrade.resolvers import StrategyResolver from freqtrade.strategy.hyper import (BaseParameter, BooleanParameter, CategoricalParameter, DecimalParameter, IntParameter, RealParameter) -from freqtrade.strategy.interface import SellCheckTuple +from freqtrade.strategy.interface import ExitCheckTuple from freqtrade.strategy.strategy_wrapper import strategy_safe_wrapper from tests.conftest import CURRENT_TEST_STRATEGY, TRADE_SIDES, log_has, log_has_re @@ -439,7 +439,7 @@ def test_stop_loss_reached(default_conf, fee, profit, adjusted, expected, traili sl_flag = strategy.stop_loss_reached(current_rate=trade.open_rate * (1 + profit), trade=trade, current_time=now, current_profit=profit, force_stoploss=0, high=None) - assert isinstance(sl_flag, SellCheckTuple) + assert isinstance(sl_flag, ExitCheckTuple) assert sl_flag.exit_type == expected if expected == ExitType.NONE: assert sl_flag.sell_flag is False diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index f601792d4..00bfcaa34 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -19,7 +19,7 @@ from freqtrade.exceptions import (DependencyException, ExchangeError, Insufficie from freqtrade.freqtradebot import FreqtradeBot from freqtrade.persistence import Order, PairLocks, Trade from freqtrade.persistence.models import PairLock -from freqtrade.strategy.interface import SellCheckTuple +from freqtrade.strategy.interface import ExitCheckTuple from freqtrade.worker import Worker from tests.conftest import (create_mock_trades, get_patched_freqtradebot, get_patched_worker, log_has, log_has_re, patch_edge, patch_exchange, patch_get_signal, @@ -2855,7 +2855,7 @@ def test_execute_trade_exit_up(default_conf_usdt, ticker_usdt, fee, ticker_usdt_ freqtrade.execute_trade_exit( trade=trade, limit=(ticker_usdt_sell_down()['ask'] if is_short else ticker_usdt_sell_up()['bid']), - exit_reason=SellCheckTuple(exit_type=ExitType.ROI) + exit_reason=ExitCheckTuple(exit_type=ExitType.ROI) ) assert rpc_mock.call_count == 0 assert freqtrade.strategy.confirm_trade_exit.call_count == 1 @@ -2867,7 +2867,7 @@ def test_execute_trade_exit_up(default_conf_usdt, ticker_usdt, fee, ticker_usdt_ freqtrade.execute_trade_exit( trade=trade, limit=(ticker_usdt_sell_down()['ask'] if is_short else ticker_usdt_sell_up()['bid']), - exit_reason=SellCheckTuple(exit_type=ExitType.ROI) + exit_reason=ExitCheckTuple(exit_type=ExitType.ROI) ) assert freqtrade.strategy.confirm_trade_exit.call_count == 1 @@ -2928,7 +2928,7 @@ def test_execute_trade_exit_down(default_conf_usdt, ticker_usdt, fee, ticker_usd ) freqtrade.execute_trade_exit( trade=trade, limit=(ticker_usdt_sell_up if is_short else ticker_usdt_sell_down)()['bid'], - exit_reason=SellCheckTuple(exit_type=ExitType.STOP_LOSS)) + exit_reason=ExitCheckTuple(exit_type=ExitType.STOP_LOSS)) assert rpc_mock.call_count == 2 last_msg = rpc_mock.call_args_list[-1][0][0] @@ -3003,7 +3003,7 @@ def test_execute_trade_exit_custom_exit_price( freqtrade.execute_trade_exit( trade=trade, limit=ticker_usdt_sell_up()['ask' if is_short else 'bid'], - exit_reason=SellCheckTuple(exit_type=ExitType.EXIT_SIGNAL) + exit_reason=ExitCheckTuple(exit_type=ExitType.EXIT_SIGNAL) ) # Sell price must be different to default bid price @@ -3074,7 +3074,7 @@ def test_execute_trade_exit_down_stoploss_on_exchange_dry_run( trade.stop_loss = 2.0 * 1.01 if is_short else 2.0 * 0.99 freqtrade.execute_trade_exit( trade=trade, limit=(ticker_usdt_sell_up if is_short else ticker_usdt_sell_down())['bid'], - exit_reason=SellCheckTuple(exit_type=ExitType.STOP_LOSS)) + exit_reason=ExitCheckTuple(exit_type=ExitType.STOP_LOSS)) assert rpc_mock.call_count == 2 last_msg = rpc_mock.call_args_list[-1][0][0] @@ -3134,7 +3134,7 @@ def test_execute_trade_exit_sloe_cancel_exception( trade.stoploss_order_id = "abcd" freqtrade.execute_trade_exit(trade=trade, limit=1234, - exit_reason=SellCheckTuple(exit_type=ExitType.STOP_LOSS)) + exit_reason=ExitCheckTuple(exit_type=ExitType.STOP_LOSS)) assert create_order_mock.call_count == 2 assert log_has('Could not cancel stoploss order abcd', caplog) @@ -3189,7 +3189,7 @@ def test_execute_trade_exit_with_stoploss_on_exchange( freqtrade.execute_trade_exit( trade=trade, limit=ticker_usdt_sell_up()['ask' if is_short else 'bid'], - exit_reason=SellCheckTuple(exit_type=ExitType.STOP_LOSS) + exit_reason=ExitCheckTuple(exit_type=ExitType.STOP_LOSS) ) trade = Trade.query.first() @@ -3328,7 +3328,7 @@ def test_execute_trade_exit_market_order( freqtrade.execute_trade_exit( trade=trade, limit=ticker_usdt_sell_up()['ask' if is_short else 'bid'], - exit_reason=SellCheckTuple(exit_type=ExitType.ROI) + exit_reason=ExitCheckTuple(exit_type=ExitType.ROI) ) assert not trade.is_open @@ -3392,7 +3392,7 @@ def test_execute_trade_exit_insufficient_funds_error(default_conf_usdt, ticker_u fetch_ticker=ticker_usdt_sell_up ) - exit_reason = SellCheckTuple(exit_type=ExitType.ROI) + exit_reason = ExitCheckTuple(exit_type=ExitType.ROI) assert not freqtrade.execute_trade_exit( trade=trade, limit=ticker_usdt_sell_up()['ask' if is_short else 'bid'], @@ -3444,7 +3444,7 @@ def test_sell_profit_only( if exit_type == ExitType.EXIT_SIGNAL.value: freqtrade.strategy.min_roi_reached = MagicMock(return_value=False) else: - freqtrade.strategy.stop_loss_reached = MagicMock(return_value=SellCheckTuple( + freqtrade.strategy.stop_loss_reached = MagicMock(return_value=ExitCheckTuple( exit_type=ExitType.NONE)) freqtrade.enter_positions() @@ -3561,7 +3561,7 @@ def test_locked_pairs(default_conf_usdt, ticker_usdt, fee, freqtrade.execute_trade_exit( trade=trade, limit=ticker_usdt_sell_down()['ask' if is_short else 'bid'], - exit_reason=SellCheckTuple(exit_type=ExitType.STOP_LOSS) + exit_reason=ExitCheckTuple(exit_type=ExitType.STOP_LOSS) ) trade.close(ticker_usdt_sell_down()['bid']) assert freqtrade.strategy.is_pair_locked(trade.pair) @@ -4920,7 +4920,7 @@ def test_update_funding_fees( trade=trade, # The values of the next 2 params are irrelevant for this test limit=ticker_usdt_sell_up()['bid'], - exit_reason=SellCheckTuple(exit_type=ExitType.ROI) + exit_reason=ExitCheckTuple(exit_type=ExitType.ROI) ) assert trade.funding_fees == pytest.approx(sum( trade.amount * diff --git a/tests/test_integration.py b/tests/test_integration.py index ba57a9cfb..375fb2c12 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -5,7 +5,7 @@ import pytest from freqtrade.enums import ExitType from freqtrade.persistence import Trade from freqtrade.rpc.rpc import RPC -from freqtrade.strategy.interface import SellCheckTuple +from freqtrade.strategy.interface import ExitCheckTuple from tests.conftest import get_patched_freqtradebot, patch_get_signal @@ -52,8 +52,8 @@ def test_may_execute_exit_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(exit_type=ExitType.NONE), - SellCheckTuple(exit_type=ExitType.EXIT_SIGNAL)] + ExitCheckTuple(exit_type=ExitType.NONE), + ExitCheckTuple(exit_type=ExitType.EXIT_SIGNAL)] ) cancel_order_mock = MagicMock() mocker.patch('freqtrade.exchange.Binance.stoploss', stoploss) @@ -157,11 +157,11 @@ def test_forcebuy_last_unlimited(default_conf, ticker, fee, limit_buy_order, moc _notify_exit=MagicMock(), ) should_sell_mock = MagicMock(side_effect=[ - SellCheckTuple(exit_type=ExitType.NONE), - SellCheckTuple(exit_type=ExitType.EXIT_SIGNAL), - SellCheckTuple(exit_type=ExitType.NONE), - SellCheckTuple(exit_type=ExitType.NONE), - SellCheckTuple(exit_type=ExitType.NONE)] + ExitCheckTuple(exit_type=ExitType.NONE), + ExitCheckTuple(exit_type=ExitType.EXIT_SIGNAL), + ExitCheckTuple(exit_type=ExitType.NONE), + ExitCheckTuple(exit_type=ExitType.NONE), + ExitCheckTuple(exit_type=ExitType.NONE)] ) mocker.patch("freqtrade.strategy.interface.IStrategy.should_exit", should_sell_mock)