From 3fcd531eacbda7ca89e64ff68e0185efc8bd621d Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 4 Nov 2019 20:19:43 +0100 Subject: [PATCH 1/4] Copy dataframe in interfac.py (reduces memory consumption) --- freqtrade/strategy/interface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index 89a38bf54..6307e664e 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -468,7 +468,7 @@ class IStrategy(ABC): Creates a dataframe and populates indicators for given candle (OHLCV) data Used by optimize operations only, not during dry / live runs. """ - return {pair: self.advise_indicators(pair_data, {'pair': pair}) + return {pair: self.advise_indicators(pair_data.copy(), {'pair': pair}) for pair, pair_data in data.items()} def advise_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: From de471862635f7344924c47ae91d2b00bd7a3c4e3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 25 Jan 2020 11:42:31 +0100 Subject: [PATCH 2/4] Use .loc for assignments --- freqtrade/optimize/backtesting.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 1725a7d13..f29f599a6 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -149,8 +149,8 @@ class Backtesting: # To avoid using data from future, we use buy/sell signals shifted # from the previous candle - df_analyzed.loc[:, 'buy'] = df_analyzed['buy'].shift(1) - df_analyzed.loc[:, 'sell'] = df_analyzed['sell'].shift(1) + df_analyzed.loc[:, 'buy'] = df_analyzed.loc[:, 'buy'].shift(1) + df_analyzed.loc[:, 'sell'] = df_analyzed.loc[:, 'sell'].shift(1) df_analyzed.drop(df_analyzed.head(1).index, inplace=True) From c465552df4b37be165157a1ad6c7e9e22e92f4b2 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Apr 2020 20:17:54 +0200 Subject: [PATCH 3/4] Update comment to mention .copy() usage --- freqtrade/strategy/interface.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index 6307e664e..c6f711b74 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -467,6 +467,9 @@ class IStrategy(ABC): """ Creates a dataframe and populates indicators for given candle (OHLCV) data Used by optimize operations only, not during dry / live runs. + Using .copy() to get a fresh copy of the dataframe for every strategy run. + Has positive effects on memory usage for whatever reason - also when + using only one strategy. """ return {pair: self.advise_indicators(pair_data.copy(), {'pair': pair}) for pair, pair_data in data.items()} From d4dde011405365fced9a93b2c916e31a66233344 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Apr 2020 20:23:20 +0200 Subject: [PATCH 4/4] Add test --- tests/strategy/test_interface.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/strategy/test_interface.py b/tests/strategy/test_interface.py index 8bc399f42..1c31aeb6a 100644 --- a/tests/strategy/test_interface.py +++ b/tests/strategy/test_interface.py @@ -168,6 +168,19 @@ def test_ohlcvdata_to_dataframe(default_conf, testdatadir) -> None: assert len(processed['UNITTEST/BTC']) == 102 # partial candle was removed +def test_ohlcvdata_to_dataframe_copy(mocker, default_conf, testdatadir) -> None: + default_conf.update({'strategy': 'DefaultStrategy'}) + strategy = StrategyResolver.load_strategy(default_conf) + aimock = mocker.patch('freqtrade.strategy.interface.IStrategy.advise_indicators') + timerange = TimeRange.parse_timerange('1510694220-1510700340') + data = load_data(testdatadir, '1m', ['UNITTEST/BTC'], timerange=timerange, + fill_up_missing=True) + strategy.ohlcvdata_to_dataframe(data) + assert aimock.call_count == 1 + # Ensure that a copy of the dataframe is passed to advice_indicators + assert aimock.call_args_list[0][0][0] is not data + + def test_min_roi_reached(default_conf, fee) -> None: # Use list to confirm sequence does not matter