diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 89b652e33..9ed8b5600 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -151,6 +151,7 @@ class Backtesting: self.trading_mode: TradingMode = config.get('trading_mode', TradingMode.SPOT) # strategies which define "can_short=True" will fail to load in Spot mode. self._can_short = self.trading_mode != TradingMode.SPOT + self._position_stacking: bool = self.config.get('position_stacking', False) self.init_backtest() @@ -1069,12 +1070,12 @@ class Backtesting: def backtest_loop( self, row: Tuple, pair: str, current_time: datetime, end_date: datetime, - max_open_trades: int, position_stacking: bool, enable_protections: bool, + max_open_trades: int, enable_protections: bool, open_trade_count_start: int) -> int: """ NOTE: This method is used by Hyperopt at each iteration. Please keep it optimized. - Backtesting processing for one candle. + Backtesting processing for one candle/pair. """ for t in list(LocalTrade.bt_trades_open_pp[pair]): # 1. Manage currently open orders of active trades @@ -1090,7 +1091,7 @@ class Backtesting: # don't open on the last row trade_dir = self.check_for_trade_entry(row) if ( - (position_stacking or len(LocalTrade.bt_trades_open_pp[pair]) == 0) + (self._position_stacking or len(LocalTrade.bt_trades_open_pp[pair]) == 0) and self.trade_slot_available(max_open_trades, open_trade_count_start) and current_time != end_date and trade_dir is not None @@ -1137,9 +1138,9 @@ class Backtesting: self.run_protections(enable_protections, pair, current_time, trade.trade_direction) return open_trade_count_start - def backtest(self, processed: Dict, # noqa: max-complexity: 13 + def backtest(self, processed: Dict, start_date: datetime, end_date: datetime, - max_open_trades: int = 0, position_stacking: bool = False, + max_open_trades: int = 0, enable_protections: bool = False) -> Dict[str, Any]: """ Implement backtesting functionality @@ -1153,7 +1154,6 @@ class Backtesting: :param start_date: backtesting timerange start datetime :param end_date: backtesting timerange end datetime :param max_open_trades: maximum number of concurrent trades, <= 0 means unlimited - :param position_stacking: do we allow position stacking? :param enable_protections: Should protections be enabled? :return: DataFrame with trades (results of backtesting) """ @@ -1187,7 +1187,7 @@ class Backtesting: open_trade_count_start = self.backtest_loop( row, pair, current_time, end_date, max_open_trades, - position_stacking, enable_protections, open_trade_count_start) + enable_protections, open_trade_count_start) # Move time one configured time_interval ahead. self.progress.increment() @@ -1249,7 +1249,6 @@ class Backtesting: start_date=min_date, end_date=max_date, max_open_trades=max_open_trades, - position_stacking=self.config.get('position_stacking', False), enable_protections=self.config.get('enable_protections', False), ) backtest_end_time = datetime.now(timezone.utc) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index d93bbbfc1..a25fb3b8f 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -122,7 +122,6 @@ class Hyperopt: else: logger.debug('Ignoring max_open_trades (--disable-max-market-positions was used) ...') self.max_open_trades = 0 - self.position_stacking = self.config.get('position_stacking', False) if HyperoptTools.has_space(self.config, 'sell'): # Make sure use_exit_signal is enabled @@ -339,7 +338,6 @@ class Hyperopt: start_date=self.min_date, end_date=self.max_date, max_open_trades=self.max_open_trades, - position_stacking=self.position_stacking, enable_protections=self.config.get('enable_protections', False), ) backtest_end_time = datetime.now(timezone.utc) diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py index fa59762db..6bec3b5d2 100644 --- a/tests/optimize/test_backtesting.py +++ b/tests/optimize/test_backtesting.py @@ -97,7 +97,6 @@ def _make_backtest_conf(mocker, datadir, conf=None, pair='UNITTEST/BTC'): 'start_date': min_date, 'end_date': max_date, 'max_open_trades': 10, - 'position_stacking': False, } @@ -735,7 +734,6 @@ def test_backtest_one(default_conf, fee, mocker, testdatadir) -> None: start_date=min_date, end_date=max_date, max_open_trades=10, - position_stacking=False, ) results = result['results'] assert not results.empty @@ -822,7 +820,6 @@ def test_backtest_timedout_entry_orders(default_conf, fee, mocker, testdatadir) start_date=min_date, end_date=max_date, max_open_trades=1, - position_stacking=False, ) assert result['timedout_entry_orders'] == 10 @@ -848,7 +845,6 @@ def test_backtest_1min_timeframe(default_conf, fee, mocker, testdatadir) -> None start_date=min_date, end_date=max_date, max_open_trades=1, - position_stacking=False, ) assert not results['results'].empty assert len(results['results']) == 1 @@ -880,7 +876,6 @@ def test_backtest_trim_no_data_left(default_conf, fee, mocker, testdatadir) -> N start_date=min_date, end_date=max_date, max_open_trades=10, - position_stacking=False, ) @@ -935,7 +930,6 @@ def test_backtest_dataprovider_analyzed_df(default_conf, fee, mocker, testdatadi start_date=min_date, end_date=max_date, max_open_trades=10, - position_stacking=False, ) assert count == 5 @@ -979,7 +973,6 @@ def test_backtest_pricecontours_protections(default_conf, fee, mocker, testdatad start_date=min_date, end_date=max_date, max_open_trades=1, - position_stacking=False, enable_protections=default_conf.get('enable_protections', False), ) assert len(results['results']) == numres @@ -1023,7 +1016,6 @@ def test_backtest_pricecontours(default_conf, fee, mocker, testdatadir, start_date=min_date, end_date=max_date, max_open_trades=1, - position_stacking=False, enable_protections=default_conf.get('enable_protections', False), ) assert len(results['results']) == expected @@ -1136,7 +1128,6 @@ def test_backtest_multi_pair(default_conf, fee, mocker, tres, pair, testdatadir) 'start_date': min_date, 'end_date': max_date, 'max_open_trades': 3, - 'position_stacking': False, } results = backtesting.backtest(**backtest_conf) @@ -1159,7 +1150,6 @@ def test_backtest_multi_pair(default_conf, fee, mocker, tres, pair, testdatadir) 'start_date': min_date, 'end_date': max_date, 'max_open_trades': 1, - 'position_stacking': False, } results = backtesting.backtest(**backtest_conf) assert len(evaluate_result_multi(results['results'], '5m', 1)) == 0 diff --git a/tests/optimize/test_backtesting_adjust_position.py b/tests/optimize/test_backtesting_adjust_position.py index 99c160a40..135ec6b15 100644 --- a/tests/optimize/test_backtesting_adjust_position.py +++ b/tests/optimize/test_backtesting_adjust_position.py @@ -42,7 +42,6 @@ def test_backtest_position_adjustment(default_conf, fee, mocker, testdatadir) -> start_date=min_date, end_date=max_date, max_open_trades=10, - position_stacking=False, ) results = result['results'] assert not results.empty diff --git a/tests/optimize/test_hyperopt.py b/tests/optimize/test_hyperopt.py index c52bc9799..5bce9f419 100644 --- a/tests/optimize/test_hyperopt.py +++ b/tests/optimize/test_hyperopt.py @@ -336,7 +336,7 @@ def test_start_calls_optimizer(mocker, hyperopt_conf, capsys) -> None: 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") + assert hasattr(hyperopt.backtesting, "_position_stacking") def test_hyperopt_format_results(hyperopt): @@ -704,7 +704,7 @@ def test_simplified_interface_roi_stoploss(mocker, hyperopt_conf, capsys) -> Non 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") + assert hasattr(hyperopt.backtesting, "_position_stacking") def test_simplified_interface_all_failed(mocker, hyperopt_conf, caplog) -> None: @@ -778,7 +778,7 @@ def test_simplified_interface_buy(mocker, hyperopt_conf, capsys) -> None: 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") + assert hasattr(hyperopt.backtesting, "_position_stacking") def test_simplified_interface_sell(mocker, hyperopt_conf, capsys) -> None: @@ -821,7 +821,7 @@ def test_simplified_interface_sell(mocker, hyperopt_conf, capsys) -> None: 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") + assert hasattr(hyperopt.backtesting, "_position_stacking") @pytest.mark.parametrize("space", [