Merge pull request #6307 from freqtrade/bt_shift
Remove shift in analyzed dataframe columns
This commit is contained in:
		| @@ -275,6 +275,13 @@ class Backtesting: | ||||
|             # Trim startup period from analyzed dataframe | ||||
|             df_analyzed = processed[pair] = pair_data = trim_dataframe( | ||||
|                 df_analyzed, self.timerange, startup_candles=self.required_startup) | ||||
|             # Update dataprovider cache | ||||
|             self.dataprovider._set_cached_df(pair, self.timeframe, df_analyzed) | ||||
|  | ||||
|             # Create a copy of the dataframe before shifting, that way the buy signal/tag | ||||
|             # remains on the correct candle for callbacks. | ||||
|             df_analyzed = df_analyzed.copy() | ||||
|  | ||||
|             # To avoid using data from future, we use buy/sell signals shifted | ||||
|             # from the previous candle | ||||
|             df_analyzed.loc[:, 'buy'] = df_analyzed.loc[:, 'buy'].shift(1) | ||||
| @@ -282,9 +289,6 @@ class Backtesting: | ||||
|             df_analyzed.loc[:, 'buy_tag'] = df_analyzed.loc[:, 'buy_tag'].shift(1) | ||||
|             df_analyzed.loc[:, 'exit_tag'] = df_analyzed.loc[:, 'exit_tag'].shift(1) | ||||
|  | ||||
|             # Update dataprovider cache | ||||
|             self.dataprovider._set_cached_df(pair, self.timeframe, df_analyzed) | ||||
|  | ||||
|             df_analyzed = df_analyzed.drop(df_analyzed.head(1).index) | ||||
|  | ||||
|             # Convert from Pandas to list for performance reasons | ||||
|   | ||||
| @@ -21,6 +21,7 @@ from freqtrade.data.dataprovider import DataProvider | ||||
| from freqtrade.data.history import get_timerange | ||||
| from freqtrade.enums import RunMode, SellType | ||||
| from freqtrade.exceptions import DependencyException, OperationalException | ||||
| from freqtrade.exchange.exchange import timeframe_to_next_date | ||||
| from freqtrade.misc import get_strategy_run_id | ||||
| from freqtrade.optimize.backtesting import Backtesting | ||||
| from freqtrade.persistence import LocalTrade | ||||
| @@ -650,6 +651,7 @@ def test_backtest_one(default_conf, fee, mocker, testdatadir) -> None: | ||||
|                              timerange=timerange) | ||||
|     processed = backtesting.strategy.advise_all_indicators(data) | ||||
|     min_date, max_date = get_timerange(processed) | ||||
|  | ||||
|     result = backtesting.backtest( | ||||
|         processed=deepcopy(processed), | ||||
|         start_date=min_date, | ||||
| @@ -741,6 +743,46 @@ def test_processed(default_conf, mocker, testdatadir) -> None: | ||||
|         assert col in cols | ||||
|  | ||||
|  | ||||
| def test_backtest_dataprovider_analyzed_df(default_conf, fee, mocker, testdatadir) -> None: | ||||
|     default_conf['use_sell_signal'] = False | ||||
|     mocker.patch('freqtrade.exchange.Exchange.get_fee', fee) | ||||
|     mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001) | ||||
|     patch_exchange(mocker) | ||||
|     backtesting = Backtesting(default_conf) | ||||
|     backtesting._set_strategy(backtesting.strategylist[0]) | ||||
|     timerange = TimeRange('date', None, 1517227800, 0) | ||||
|     data = history.load_data(datadir=testdatadir, timeframe='5m', pairs=['UNITTEST/BTC'], | ||||
|                              timerange=timerange) | ||||
|     processed = backtesting.strategy.advise_all_indicators(data) | ||||
|     min_date, max_date = get_timerange(processed) | ||||
|  | ||||
|     global count | ||||
|     count = 0 | ||||
|  | ||||
|     def tmp_confirm_entry(pair, current_time, **kwargs): | ||||
|         dp = backtesting.strategy.dp | ||||
|         df, _ = dp.get_analyzed_dataframe(pair, backtesting.strategy.timeframe) | ||||
|         current_candle = df.iloc[-1].squeeze() | ||||
|         assert current_candle['buy'] == 1 | ||||
|  | ||||
|         candle_date = timeframe_to_next_date(backtesting.strategy.timeframe, current_candle['date']) | ||||
|         assert candle_date == current_time | ||||
|         # These asserts don't properly raise as they are nested, | ||||
|         # therefore we increment count and assert for that. | ||||
|         global count | ||||
|         count = count + 1 | ||||
|  | ||||
|     backtesting.strategy.confirm_trade_entry = tmp_confirm_entry | ||||
|     backtesting.backtest( | ||||
|         processed=deepcopy(processed), | ||||
|         start_date=min_date, | ||||
|         end_date=max_date, | ||||
|         max_open_trades=10, | ||||
|         position_stacking=False, | ||||
|     ) | ||||
|     assert count == 5 | ||||
|  | ||||
|  | ||||
| def test_backtest_pricecontours_protections(default_conf, fee, mocker, testdatadir) -> None: | ||||
|     # While this test IS a copy of test_backtest_pricecontours, it's needed to ensure | ||||
|     # results do not carry-over to the next run, which is not given by using parametrize. | ||||
|   | ||||
		Reference in New Issue
	
	Block a user