Repository: freqtrade/freqtrade

Issue:
Inconsistent backtest results (conditions unchanged)
## Step 1: Have you search for this issue before posting it?
Yes
If you have discovered a bug in the bot, please [search our issue tracker](https://github.com/freqtrade/freqtrade/issues?q=is%3Aissue). 
If it hasn't been reported, please create a new issue.

## Step 2: Describe your environment
  * Operating system: ____Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-91-generic x86_64)
  * Python Version: _____ Python 3.6.9
  * CCXT version: _____ ccxt==1.24.83
  * Branch: Master | Develop
  * Last Commit ID: _____ 39ea1266981d0e207159d978b4ac90a4142c7a56
  
## Step 3: Describe the problem:
config.json , strategy file and although the test date range does not change, the backtest results are very different
*Explain the problem you have encountered*

### Steps to reproduce:

`freqtrade backtesting --strategy-list   ADXMomentum AdxSmas ASDTSRockwellTrading AverageStrategy AwesomeMacd BbandRsi   BinHV27 BinHV45 CCIStrategy ClucMay72018 CMCWinner CofiBitStrategy   CombinedBinHAndCluc DoesNothingStrategy EMASkipPump   Freqtrade_backtest_validation_freqtrade1 InformativeSample Low_BB   MACDStrategy MACDStrategy_crossed Quickie ReinforcedQuickie   ReinforcedSmoothScalp Scalp Simple SmoothScalp TechnicalExampleStrategy   hokes1 strateji1 strateji3 strateji2 strateji ichimoku1 ichimoku2 hokes   --timerange=20200101- --ticker-interval 5m`

 
```
Result for strategy hokes
====   BACKTESTING REPORT   ====
  | Pair | Buys | Avg Profit % | Cum Profit % | Tot Profit % | Avg Duration | Wins | Draws | Losses |  

  | BTC/USDT | 33 | -0.24|  -7.81|-1.56 | 2 days,8:11:00 | 18 | 0 | 15 |  
  | ETH/USDT | 66 | 0.19 | 12.40 | 2.48 | 1 day, 3:25:00 | 39 | 0 | 27 |  
  | XRP/USDT | 50 | 0.17 | 8.57  | 1.71 | 1 day, 12:36:00| 29 | 0 | 21 |  
  | XLM/USDT | 57 | 0.31 | 17.79 | 3.56 | 1 day, 7:44:00 | 33 | 0 | 24 |  
  |WAVES/USDT| 72 |-0.10 |-7.24  |-1.45 | 1 day, 0:32:00 | 37 | 0 | 35 |  
  | TOTAL   | 278 | 0.09 | 23.71 | 4.74 | 1 day, 8:37:00 | 156 | 0 | 122 |  
======================================================   SELL REASON STATS =======================================================
  | Sell Reason | Sells | Wins | Draws | Avg Profit % | Cum Profit % | Tot Profit USDT | Tot Profit % |  
 -------------------------------------------------------------
  | roi        | 151 | 151 | 0 | 5.85  | 883.9    | 884.788 | 176.78 |  
  | stop_loss  | 122 | 0   | 0 | -7.19 | -876.67  | -877.546 | -175.33 |  
  | force_sell | 5   | 5   | 0 | 3.3   | 16.48    | 164.935 | 3.3 |   |  
====   LEFT OPEN TRADES REPORT   
===========================================
  | Pair | Buys | Avg Profit % | Cum Profit % | Tot Profit % | Avg Duration | Wins | Draws | Losses |  
  ------------------------------------------------------------------------------------
  | BTC/USDT | 1 | 3.66 | 3.66 | 0.73 | 4:45:00 | 1 | 0 | 0 |  
  | ETH/USDT | 1 | 5.01 | 5.01 | 1.00 | 4:50:00 | 1 | 0 | 0 |  
  | XRP/USDT | 1 | 2.67 | 2.67 | 0.53 | 4:50:00 | 1 | 0 | 0 |  
  | XLM/USDT | 1 | 2.18 | 2.18 | 0.44 | 3:15:00 | 1 | 0 | 0 |  
  |WAVES/USDT| 1 | 2.95 | 2.95 | 0.59 | 2:35:00 | 1 | 0 | 0 |  
  | TOTAL    | 5 | 3.30 | 16.48| 3.30 | 4:03:00 | 5 | 0 | 0 |  
===========================
```












`freqtrade backtesting   --strategy-list  MACDStrategy hokes   --timerange=20200101- --ticker-interval 5m`
or
`freqtrade backtesting   --strategy hokes   --timerange=20200101- --ticker-interval 5m`
```
Result for strategy hokes 
====   BACKTESTING REPORT   
====
  | Pair | Buys | Avg Profit % | Cum Profit % | Tot Profit % | Avg Duration | Wins | Draws | Losses |   |   |   |  
  | ------------+--------+----------------+----------------+-------------------+----------
  | BTC/USDT | 42 | 0.04 | 1.63 | 0.33 | 1 day, 19:53:00 | 24 | 0 | 18 |   |   |   |  
  | ETH/USDT | 58 | 0.43 | 24.67| 4.93 | 1 day, 7:19:00 | 35 | 0 | 23 |   |   |   |  
  | XRP/USDT | 48 | 0.17 | 8.12 | 1.62 | 1 day, 14:07:00 | 28 | 0 | 20 |   |   |   |  
  | XLM/USDT | 55 | 0.29 | 16.20| 3.24 | 1 day, 8:48:00 | 31 | 0 | 24 |   |   |   |  
  |WAVES/USDT| 73 | 0.74 | 53.98| 10.80| 1 day, 0:17:00 | 42 | 0 | 31 |   |   |   |  
  | TOTAL   | 276 | 0.38 |104.61| 20.92 | 1 day, 8:51:00 | 160 | 0 | 116 |   |   |   |  
======================================================   SELL REASON STATS ======================================================= |  
  | Sell Reason | Sells | Wins | Draws | Avg Profit % | Cum Profit % | Tot Profit USDT | Tot Profit % |   |   |   |  
  | ---------------+---------+--------+---------+----------+----------------+-------------- 
  | roi | 155 | 155 | 0 | 5.95 | 922.85 | 923.774 | 184.57 |   |   |   |  
  | stop_loss | 116 | 0 | 0 | -7.19 | -833.55 | -834.388 | -166.71 |   |   |   |  
  | force_sell | 5  | 5 | 0 | 3.06 | 15.31 | 153.261 | 3.06 |   |   |   |  
==========================================================   LEFT OPEN TRADES REPORT   ==========================================================
  | Pair | Buys | Avg Profit % | Cum Profit % | Tot Profit % | Avg Duration | Wins | Draws | Losses |   |   |   |  
  | ------------+--------+----------------+----------------+-------------------+-------------  
  | BTC/USDT | 1 | 1.18 | 1.18 | 0.24 | 4:15:00 | 1 | 0 | 0 |   |   |   |  
  | ETH/USDT | 1 | 5.01 | 5.01 | 1.00 | 4:50:00 | 1 | 0 | 0 |   |   |   |  
  | XRP/USDT | 1 | 2.67 | 2.67 | 0.53 | 4:50:00 | 1 | 0 | 0 |   |   |   |  
  | XLM/USDT | 1 | 1.44 | 1.44 | 0.29 | 3:10:00 | 1 | 0 | 0 |   |   |   |  
  |WAVES/USDT| 1 | 5.01 | 5.01 | 1.00 | 5:00:00 | 1 | 0 | 0 |   |   |   |  
  |  TOTAL  | 5 | 3.06 | 15.31 | 3.06 | 4:25:00 | 5 | 0 | 0 |   |   |   |  
========================================================
 ```
### Observed Results:

  Although no conditions have changed, I found 4.94% and 20.92% results for the same strategy
What is the reason for this discrepancy?




Discussion:

Resolving patch:
diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py
--- a/freqtrade/optimize/backtesting.py
+++ b/freqtrade/optimize/backtesting.py
@@ -149,8 +149,8 @@ def _get_ohlcv_as_lists(self, processed: Dict) -> Dict[str, DataFrame]:
 
             # 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)
 
diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py
--- a/freqtrade/strategy/interface.py
+++ b/freqtrade/strategy/interface.py
@@ -467,8 +467,11 @@ def ohlcvdata_to_dataframe(self, data: Dict[str, DataFrame]) -> Dict[str, DataFr
         """
         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, {'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:


Test patch:
diff --git a/tests/strategy/test_interface.py b/tests/strategy/test_interface.py
--- 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