From 0e13d57e5792d10dea887d64b9552de5094c7e6c Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 22 Sep 2021 20:42:31 +0200 Subject: [PATCH] Update advise_* methods to entry/exit --- freqtrade/edge/edge_positioning.py | 4 ++-- freqtrade/optimize/backtesting.py | 4 ++-- freqtrade/strategy/interface.py | 10 ++++---- tests/optimize/test_backtest_detail.py | 4 ++-- tests/optimize/test_backtesting.py | 20 ++++++++-------- tests/optimize/test_hyperopt.py | 16 ++++++------- tests/strategy/test_interface.py | 32 ++++++++++++------------- tests/strategy/test_strategy_loading.py | 16 ++++++------- 8 files changed, 53 insertions(+), 53 deletions(-) diff --git a/freqtrade/edge/edge_positioning.py b/freqtrade/edge/edge_positioning.py index bee96c746..e08b3df2f 100644 --- a/freqtrade/edge/edge_positioning.py +++ b/freqtrade/edge/edge_positioning.py @@ -168,8 +168,8 @@ class Edge: pair_data = pair_data.sort_values(by=['date']) pair_data = pair_data.reset_index(drop=True) - df_analyzed = self.strategy.advise_sell( - dataframe=self.strategy.advise_buy( + df_analyzed = self.strategy.advise_exit( + dataframe=self.strategy.advise_entry( dataframe=pair_data, metadata={'pair': pair} ), diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 429ba7251..4094cf0aa 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -274,8 +274,8 @@ class Backtesting: pair_data.loc[:, 'long_tag'] = None pair_data.loc[:, 'short_tag'] = None - df_analyzed = self.strategy.advise_sell( - self.strategy.advise_buy(pair_data, {'pair': pair}), + df_analyzed = self.strategy.advise_exit( + self.strategy.advise_entry(pair_data, {'pair': pair}), {'pair': pair} ).copy() # Trim startup period from analyzed dataframe diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index d852c7269..0d651ccbb 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -489,8 +489,8 @@ class IStrategy(ABC, HyperStrategyMixin): """ logger.debug("TA Analysis Launched") dataframe = self.advise_indicators(dataframe, metadata) - dataframe = self.advise_buy(dataframe, metadata) - dataframe = self.advise_sell(dataframe, metadata) + dataframe = self.advise_entry(dataframe, metadata) + dataframe = self.advise_exit(dataframe, metadata) return dataframe def _analyze_ticker_internal(self, dataframe: DataFrame, metadata: dict) -> DataFrame: @@ -912,7 +912,7 @@ class IStrategy(ABC, HyperStrategyMixin): def advise_all_indicators(self, data: Dict[str, DataFrame]) -> Dict[str, DataFrame]: """ Populates indicators for given candle (OHLCV) data (for multiple pairs) - Does not run advise_buy or advise_sell! + Does not run advise_entry or advise_exit! Used by optimize operations only, not during dry / live runs. Using .copy() to get a fresh copy of the dataframe for every strategy run. Also copy on output to avoid PerformanceWarnings pandas 1.3.0 started to show. @@ -944,7 +944,7 @@ class IStrategy(ABC, HyperStrategyMixin): else: return self.populate_indicators(dataframe, metadata) - def advise_buy(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + def advise_entry(self, dataframe: DataFrame, metadata: dict) -> DataFrame: """ Based on TA indicators, populates the entry order signal for the given dataframe This method should not be overridden. @@ -967,7 +967,7 @@ class IStrategy(ABC, HyperStrategyMixin): return df - def advise_sell(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + def advise_exit(self, dataframe: DataFrame, metadata: dict) -> DataFrame: """ Based on TA indicators, populates the exit order signal for the given dataframe This method should not be overridden. diff --git a/tests/optimize/test_backtest_detail.py b/tests/optimize/test_backtest_detail.py index 9b99648b1..554122bd5 100644 --- a/tests/optimize/test_backtest_detail.py +++ b/tests/optimize/test_backtest_detail.py @@ -598,8 +598,8 @@ def test_backtest_results(default_conf, fee, mocker, caplog, data) -> None: backtesting = Backtesting(default_conf) backtesting._set_strategy(backtesting.strategylist[0]) backtesting.required_startup = 0 - backtesting.strategy.advise_buy = lambda a, m: frame - backtesting.strategy.advise_sell = lambda a, m: frame + backtesting.strategy.advise_entry = lambda a, m: frame + backtesting.strategy.advise_exit = lambda a, m: frame backtesting.strategy.use_custom_stoploss = data.use_custom_stoploss caplog.set_level(logging.DEBUG) diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py index 0d31846d5..662ca0193 100644 --- a/tests/optimize/test_backtesting.py +++ b/tests/optimize/test_backtesting.py @@ -295,8 +295,8 @@ def test_backtesting_init(mocker, default_conf, order_types) -> None: assert backtesting.config == default_conf assert backtesting.timeframe == '5m' assert callable(backtesting.strategy.advise_all_indicators) - assert callable(backtesting.strategy.advise_buy) - assert callable(backtesting.strategy.advise_sell) + assert callable(backtesting.strategy.advise_entry) + assert callable(backtesting.strategy.advise_exit) assert isinstance(backtesting.strategy.dp, DataProvider) get_fee.assert_called() assert backtesting.fee == 0.5 @@ -811,8 +811,8 @@ def test_backtest_clash_buy_sell(mocker, default_conf, testdatadir): backtest_conf = _make_backtest_conf(mocker, conf=default_conf, datadir=testdatadir) backtesting = Backtesting(default_conf) backtesting._set_strategy(backtesting.strategylist[0]) - backtesting.strategy.advise_buy = fun # Override - backtesting.strategy.advise_sell = fun # Override + backtesting.strategy.advise_entry = fun # Override + backtesting.strategy.advise_exit = fun # Override result = backtesting.backtest(**backtest_conf) assert result['results'].empty @@ -827,8 +827,8 @@ def test_backtest_only_sell(mocker, default_conf, testdatadir): backtest_conf = _make_backtest_conf(mocker, conf=default_conf, datadir=testdatadir) backtesting = Backtesting(default_conf) backtesting._set_strategy(backtesting.strategylist[0]) - backtesting.strategy.advise_buy = fun # Override - backtesting.strategy.advise_sell = fun # Override + backtesting.strategy.advise_entry = fun # Override + backtesting.strategy.advise_exit = fun # Override result = backtesting.backtest(**backtest_conf) assert result['results'].empty @@ -842,8 +842,8 @@ def test_backtest_alternate_buy_sell(default_conf, fee, mocker, testdatadir): backtesting = Backtesting(default_conf) backtesting.required_startup = 0 backtesting._set_strategy(backtesting.strategylist[0]) - backtesting.strategy.advise_buy = _trend_alternate # Override - backtesting.strategy.advise_sell = _trend_alternate # Override + backtesting.strategy.advise_entry = _trend_alternate # Override + backtesting.strategy.advise_exit = _trend_alternate # Override result = backtesting.backtest(**backtest_conf) # 200 candles in backtest data # won't buy on first (shifted by 1) @@ -896,8 +896,8 @@ def test_backtest_multi_pair(default_conf, fee, mocker, tres, pair, testdatadir) backtesting = Backtesting(default_conf) backtesting._set_strategy(backtesting.strategylist[0]) - backtesting.strategy.advise_buy = _trend_alternate_hold # Override - backtesting.strategy.advise_sell = _trend_alternate_hold # Override + backtesting.strategy.advise_entry = _trend_alternate_hold # Override + backtesting.strategy.advise_exit = _trend_alternate_hold # Override processed = backtesting.strategy.advise_all_indicators(data) min_date, max_date = get_timerange(processed) diff --git a/tests/optimize/test_hyperopt.py b/tests/optimize/test_hyperopt.py index a83277dc6..57d10d048 100644 --- a/tests/optimize/test_hyperopt.py +++ b/tests/optimize/test_hyperopt.py @@ -318,8 +318,8 @@ def test_start_calls_optimizer(mocker, hyperopt_conf, capsys) -> None: # Should be called for historical candle data assert dumper.call_count == 1 assert dumper2.call_count == 1 - assert hasattr(hyperopt.backtesting.strategy, "advise_sell") - assert hasattr(hyperopt.backtesting.strategy, "advise_buy") + assert hasattr(hyperopt.backtesting.strategy, "advise_exit") + assert hasattr(hyperopt.backtesting.strategy, "advise_entry") assert hasattr(hyperopt, "max_open_trades") assert hyperopt.max_open_trades == hyperopt_conf['max_open_trades'] assert hasattr(hyperopt, "position_stacking") @@ -698,8 +698,8 @@ def test_simplified_interface_roi_stoploss(mocker, hyperopt_conf, capsys) -> Non assert dumper.call_count == 1 assert dumper2.call_count == 1 - assert hasattr(hyperopt.backtesting.strategy, "advise_sell") - assert hasattr(hyperopt.backtesting.strategy, "advise_buy") + assert hasattr(hyperopt.backtesting.strategy, "advise_exit") + assert hasattr(hyperopt.backtesting.strategy, "advise_entry") assert hasattr(hyperopt, "max_open_trades") assert hyperopt.max_open_trades == hyperopt_conf['max_open_trades'] assert hasattr(hyperopt, "position_stacking") @@ -772,8 +772,8 @@ def test_simplified_interface_buy(mocker, hyperopt_conf, capsys) -> None: assert dumper.called assert dumper.call_count == 1 assert dumper2.call_count == 1 - assert hasattr(hyperopt.backtesting.strategy, "advise_sell") - assert hasattr(hyperopt.backtesting.strategy, "advise_buy") + assert hasattr(hyperopt.backtesting.strategy, "advise_exit") + assert hasattr(hyperopt.backtesting.strategy, "advise_entry") assert hasattr(hyperopt, "max_open_trades") assert hyperopt.max_open_trades == hyperopt_conf['max_open_trades'] assert hasattr(hyperopt, "position_stacking") @@ -821,8 +821,8 @@ def test_simplified_interface_sell(mocker, hyperopt_conf, capsys) -> None: assert dumper.called assert dumper.call_count == 1 assert dumper2.call_count == 1 - assert hasattr(hyperopt.backtesting.strategy, "advise_sell") - assert hasattr(hyperopt.backtesting.strategy, "advise_buy") + assert hasattr(hyperopt.backtesting.strategy, "advise_exit") + assert hasattr(hyperopt.backtesting.strategy, "advise_entry") assert hasattr(hyperopt, "max_open_trades") assert hyperopt.max_open_trades == hyperopt_conf['max_open_trades'] assert hasattr(hyperopt, "position_stacking") diff --git a/tests/strategy/test_interface.py b/tests/strategy/test_interface.py index ad393d6a4..4b39adaf7 100644 --- a/tests/strategy/test_interface.py +++ b/tests/strategy/test_interface.py @@ -535,20 +535,20 @@ def test_leverage_callback(default_conf, side) -> None: def test_analyze_ticker_default(ohlcv_history, mocker, caplog) -> None: caplog.set_level(logging.DEBUG) ind_mock = MagicMock(side_effect=lambda x, meta: x) - buy_mock = MagicMock(side_effect=lambda x, meta: x) - sell_mock = MagicMock(side_effect=lambda x, meta: x) + entry_mock = MagicMock(side_effect=lambda x, meta: x) + exit_mock = MagicMock(side_effect=lambda x, meta: x) mocker.patch.multiple( 'freqtrade.strategy.interface.IStrategy', advise_indicators=ind_mock, - advise_buy=buy_mock, - advise_sell=sell_mock, + advise_entry=entry_mock, + advise_exit=exit_mock, ) strategy = StrategyTestV3({}) strategy.analyze_ticker(ohlcv_history, {'pair': 'ETH/BTC'}) assert ind_mock.call_count == 1 - assert buy_mock.call_count == 1 - assert buy_mock.call_count == 1 + assert entry_mock.call_count == 1 + assert entry_mock.call_count == 1 assert log_has('TA Analysis Launched', caplog) assert not log_has('Skipping TA Analysis for already analyzed candle', caplog) @@ -557,8 +557,8 @@ def test_analyze_ticker_default(ohlcv_history, mocker, caplog) -> None: strategy.analyze_ticker(ohlcv_history, {'pair': 'ETH/BTC'}) # No analysis happens as process_only_new_candles is true assert ind_mock.call_count == 2 - assert buy_mock.call_count == 2 - assert buy_mock.call_count == 2 + assert entry_mock.call_count == 2 + assert entry_mock.call_count == 2 assert log_has('TA Analysis Launched', caplog) assert not log_has('Skipping TA Analysis for already analyzed candle', caplog) @@ -566,13 +566,13 @@ def test_analyze_ticker_default(ohlcv_history, mocker, caplog) -> None: def test__analyze_ticker_internal_skip_analyze(ohlcv_history, mocker, caplog) -> None: caplog.set_level(logging.DEBUG) ind_mock = MagicMock(side_effect=lambda x, meta: x) - buy_mock = MagicMock(side_effect=lambda x, meta: x) - sell_mock = MagicMock(side_effect=lambda x, meta: x) + entry_mock = MagicMock(side_effect=lambda x, meta: x) + exit_mock = MagicMock(side_effect=lambda x, meta: x) mocker.patch.multiple( 'freqtrade.strategy.interface.IStrategy', advise_indicators=ind_mock, - advise_buy=buy_mock, - advise_sell=sell_mock, + advise_entry=entry_mock, + advise_exit=exit_mock, ) strategy = StrategyTestV3({}) @@ -585,8 +585,8 @@ def test__analyze_ticker_internal_skip_analyze(ohlcv_history, mocker, caplog) -> assert 'close' in ret.columns assert isinstance(ret, DataFrame) assert ind_mock.call_count == 1 - assert buy_mock.call_count == 1 - assert buy_mock.call_count == 1 + assert entry_mock.call_count == 1 + assert entry_mock.call_count == 1 assert log_has('TA Analysis Launched', caplog) assert not log_has('Skipping TA Analysis for already analyzed candle', caplog) caplog.clear() @@ -594,8 +594,8 @@ def test__analyze_ticker_internal_skip_analyze(ohlcv_history, mocker, caplog) -> ret = strategy._analyze_ticker_internal(ohlcv_history, {'pair': 'ETH/BTC'}) # No analysis happens as process_only_new_candles is true assert ind_mock.call_count == 1 - assert buy_mock.call_count == 1 - assert buy_mock.call_count == 1 + assert entry_mock.call_count == 1 + assert entry_mock.call_count == 1 # only skipped analyze adds buy and sell columns, otherwise it's all mocked assert 'enter_long' in ret.columns assert 'exit_long' in ret.columns diff --git a/tests/strategy/test_strategy_loading.py b/tests/strategy/test_strategy_loading.py index b3e79cd27..4e29e1ebc 100644 --- a/tests/strategy/test_strategy_loading.py +++ b/tests/strategy/test_strategy_loading.py @@ -117,11 +117,11 @@ def test_strategy_v2(result, default_conf): df_indicators = strategy.advise_indicators(result, metadata=metadata) assert 'adx' in df_indicators - dataframe = strategy.advise_buy(df_indicators, metadata=metadata) + dataframe = strategy.advise_entry(df_indicators, metadata=metadata) assert 'buy' not in dataframe.columns assert 'enter_long' in dataframe.columns - dataframe = strategy.advise_sell(df_indicators, metadata=metadata) + dataframe = strategy.advise_exit(df_indicators, metadata=metadata) assert 'sell' not in dataframe.columns assert 'exit_long' in dataframe.columns @@ -347,7 +347,7 @@ def test_deprecate_populate_indicators(result, default_conf): with warnings.catch_warnings(record=True) as w: # Cause all warnings to always be triggered. warnings.simplefilter("always") - strategy.advise_buy(indicators, {'pair': 'ETH/BTC'}) + strategy.advise_entry(indicators, {'pair': 'ETH/BTC'}) assert len(w) == 1 assert issubclass(w[-1].category, DeprecationWarning) assert "deprecated - check out the Sample strategy to see the current function headers!" \ @@ -356,7 +356,7 @@ def test_deprecate_populate_indicators(result, default_conf): with warnings.catch_warnings(record=True) as w: # Cause all warnings to always be triggered. warnings.simplefilter("always") - strategy.advise_sell(indicators, {'pair': 'ETH_BTC'}) + strategy.advise_exit(indicators, {'pair': 'ETH_BTC'}) assert len(w) == 1 assert issubclass(w[-1].category, DeprecationWarning) assert "deprecated - check out the Sample strategy to see the current function headers!" \ @@ -384,11 +384,11 @@ def test_call_deprecated_function(result, monkeypatch, default_conf, caplog): assert isinstance(indicator_df, DataFrame) assert 'adx' in indicator_df.columns - enterdf = strategy.advise_buy(result, metadata=metadata) + enterdf = strategy.advise_entry(result, metadata=metadata) assert isinstance(enterdf, DataFrame) assert 'buy' in enterdf.columns - exitdf = strategy.advise_sell(result, metadata=metadata) + exitdf = strategy.advise_exit(result, metadata=metadata) assert isinstance(exitdf, DataFrame) assert 'sell' in exitdf @@ -411,13 +411,13 @@ def test_strategy_interface_versioning(result, default_conf): assert isinstance(indicator_df, DataFrame) assert 'adx' in indicator_df.columns - enterdf = strategy.advise_buy(result, metadata=metadata) + enterdf = strategy.advise_entry(result, metadata=metadata) assert isinstance(enterdf, DataFrame) assert 'buy' not in enterdf.columns assert 'enter_long' in enterdf.columns - exitdf = strategy.advise_sell(result, metadata=metadata) + exitdf = strategy.advise_exit(result, metadata=metadata) assert isinstance(exitdf, DataFrame) assert 'sell' not in exitdf assert 'exit_long' in exitdf