We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Strategy analysis -> how many max_open_trades i will use for this strategy ?
As an algo trade
I want to perform statistics like maximum drawdown, profit and find an optimum between stake_amount and max_open_trade so i run and export the backtest with --disable-max-market-positions flag and make simulations in jupyter.
So that i can find a comprise between risk and profit.

To archive that i need to find trades that happens at the same time and flag them (open_trade_number) and then filter then.

I don't know if it can be useful to have this straight in a column of the dataframe of load_backtest_data() ?

Maybe it is a too specific need.

Have a nice day.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `freqtrade/data/btanalysis.py`
Content:
```
1 """
2 Helpers when analyzing backtest data
3 """
4 import logging
5 from pathlib import Path
6 from typing import Dict
7 
8 import numpy as np
9 import pandas as pd
10 import pytz
11 
12 from freqtrade import persistence
13 from freqtrade.misc import json_load
14 from freqtrade.persistence import Trade
15 
16 logger = logging.getLogger(__name__)
17 
18 # must align with columns in backtest.py
19 BT_DATA_COLUMNS = ["pair", "profitperc", "open_time", "close_time", "index", "duration",
20                    "open_rate", "close_rate", "open_at_end", "sell_reason"]
21 
22 
23 def load_backtest_data(filename) -> pd.DataFrame:
24     """
25     Load backtest data file.
26     :param filename: pathlib.Path object, or string pointing to the file.
27     :return: a dataframe with the analysis results
28     """
29     if isinstance(filename, str):
30         filename = Path(filename)
31 
32     if not filename.is_file():
33         raise ValueError(f"File {filename} does not exist.")
34 
35     with filename.open() as file:
36         data = json_load(file)
37 
38     df = pd.DataFrame(data, columns=BT_DATA_COLUMNS)
39 
40     df['open_time'] = pd.to_datetime(df['open_time'],
41                                      unit='s',
42                                      utc=True,
43                                      infer_datetime_format=True
44                                      )
45     df['close_time'] = pd.to_datetime(df['close_time'],
46                                       unit='s',
47                                       utc=True,
48                                       infer_datetime_format=True
49                                       )
50     df['profitabs'] = df['close_rate'] - df['open_rate']
51     df = df.sort_values("open_time").reset_index(drop=True)
52     return df
53 
54 
55 def evaluate_result_multi(results: pd.DataFrame, freq: str, max_open_trades: int) -> pd.DataFrame:
56     """
57     Find overlapping trades by expanding each trade once per period it was open
58     and then counting overlaps
59     :param results: Results Dataframe - can be loaded
60     :param freq: Frequency used for the backtest
61     :param max_open_trades: parameter max_open_trades used during backtest run
62     :return: dataframe with open-counts per time-period in freq
63     """
64     dates = [pd.Series(pd.date_range(row[1].open_time, row[1].close_time, freq=freq))
65              for row in results[['open_time', 'close_time']].iterrows()]
66     deltas = [len(x) for x in dates]
67     dates = pd.Series(pd.concat(dates).values, name='date')
68     df2 = pd.DataFrame(np.repeat(results.values, deltas, axis=0), columns=results.columns)
69 
70     df2 = pd.concat([dates, df2], axis=1)
71     df2 = df2.set_index('date')
72     df_final = df2.resample(freq)[['pair']].count()
73     return df_final[df_final['pair'] > max_open_trades]
74 
75 
76 def load_trades_from_db(db_url: str) -> pd.DataFrame:
77     """
78     Load trades from a DB (using dburl)
79     :param db_url: Sqlite url (default format sqlite:///tradesv3.dry-run.sqlite)
80     :return: Dataframe containing Trades
81     """
82     trades: pd.DataFrame = pd.DataFrame([], columns=BT_DATA_COLUMNS)
83     persistence.init(db_url, clean_open_orders=False)
84 
85     columns = ["pair", "open_time", "close_time", "profit", "profitperc",
86                "open_rate", "close_rate", "amount", "duration", "sell_reason",
87                "fee_open", "fee_close", "open_rate_requested", "close_rate_requested",
88                "stake_amount", "max_rate", "min_rate", "id", "exchange",
89                "stop_loss", "initial_stop_loss", "strategy", "ticker_interval"]
90 
91     trades = pd.DataFrame([(t.pair,
92                             t.open_date.replace(tzinfo=pytz.UTC),
93                             t.close_date.replace(tzinfo=pytz.UTC) if t.close_date else None,
94                             t.calc_profit(), t.calc_profit_percent(),
95                             t.open_rate, t.close_rate, t.amount,
96                             (round((t.close_date.timestamp() - t.open_date.timestamp()) / 60, 2)
97                                 if t.close_date else None),
98                             t.sell_reason,
99                             t.fee_open, t.fee_close,
100                             t.open_rate_requested,
101                             t.close_rate_requested,
102                             t.stake_amount,
103                             t.max_rate,
104                             t.min_rate,
105                             t.id, t.exchange,
106                             t.stop_loss, t.initial_stop_loss,
107                             t.strategy, t.ticker_interval
108                             )
109                            for t in Trade.query.all()],
110                           columns=columns)
111 
112     return trades
113 
114 
115 def load_trades(source: str, db_url: str, exportfilename: str) -> pd.DataFrame:
116     """
117     Based on configuration option "trade_source":
118     * loads data from DB (using `db_url`)
119     * loads data from backtestfile (using `exportfilename`)
120     """
121     if source == "DB":
122         return load_trades_from_db(db_url)
123     elif source == "file":
124         return load_backtest_data(Path(exportfilename))
125 
126 
127 def extract_trades_of_period(dataframe: pd.DataFrame, trades: pd.DataFrame) -> pd.DataFrame:
128     """
129     Compare trades and backtested pair DataFrames to get trades performed on backtested period
130     :return: the DataFrame of a trades of period
131     """
132     trades = trades.loc[(trades['open_time'] >= dataframe.iloc[0]['date']) &
133                         (trades['close_time'] <= dataframe.iloc[-1]['date'])]
134     return trades
135 
136 
137 def combine_tickers_with_mean(tickers: Dict[str, pd.DataFrame], column: str = "close"):
138     """
139     Combine multiple dataframes "column"
140     :param tickers: Dict of Dataframes, dict key should be pair.
141     :param column: Column in the original dataframes to use
142     :return: DataFrame with the column renamed to the dict key, and a column
143         named mean, containing the mean of all pairs.
144     """
145     df_comb = pd.concat([tickers[pair].set_index('date').rename(
146         {column: pair}, axis=1)[pair] for pair in tickers], axis=1)
147 
148     df_comb['mean'] = df_comb.mean(axis=1)
149 
150     return df_comb
151 
152 
153 def create_cum_profit(df: pd.DataFrame, trades: pd.DataFrame, col_name: str,
154                       timeframe: str) -> pd.DataFrame:
155     """
156     Adds a column `col_name` with the cumulative profit for the given trades array.
157     :param df: DataFrame with date index
158     :param trades: DataFrame containing trades (requires columns close_time and profitperc)
159     :param col_name: Column name that will be assigned the results
160     :param timeframe: Timeframe used during the operations
161     :return: Returns df with one additional column, col_name, containing the cumulative profit.
162     """
163     from freqtrade.exchange import timeframe_to_minutes
164     ticker_minutes = timeframe_to_minutes(timeframe)
165     # Resample to ticker_interval to make sure trades match candles
166     _trades_sum = trades.resample(f'{ticker_minutes}min', on='close_time')[['profitperc']].sum()
167     df.loc[:, col_name] = _trades_sum.cumsum()
168     # Set first value to 0
169     df.loc[df.iloc[0].name, col_name] = 0
170     # FFill to get continuous
171     df[col_name] = df[col_name].ffill()
172     return df
173
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/freqtrade/data/btanalysis.py b/freqtrade/data/btanalysis.py
--- a/freqtrade/data/btanalysis.py
+++ b/freqtrade/data/btanalysis.py
@@ -52,16 +52,18 @@
     return df
 
 
-def evaluate_result_multi(results: pd.DataFrame, freq: str, max_open_trades: int) -> pd.DataFrame:
+def analyze_trade_parallelism(results: pd.DataFrame, timeframe: str) -> pd.DataFrame:
     """
     Find overlapping trades by expanding each trade once per period it was open
-    and then counting overlaps
+    and then counting overlaps.
     :param results: Results Dataframe - can be loaded
-    :param freq: Frequency used for the backtest
-    :param max_open_trades: parameter max_open_trades used during backtest run
-    :return: dataframe with open-counts per time-period in freq
+    :param timeframe: Timeframe used for backtest
+    :return: dataframe with open-counts per time-period in timeframe
     """
-    dates = [pd.Series(pd.date_range(row[1].open_time, row[1].close_time, freq=freq))
+    from freqtrade.exchange import timeframe_to_minutes
+    timeframe_min = timeframe_to_minutes(timeframe)
+    dates = [pd.Series(pd.date_range(row[1].open_time, row[1].close_time,
+                                     freq=f"{timeframe_min}min"))
              for row in results[['open_time', 'close_time']].iterrows()]
     deltas = [len(x) for x in dates]
     dates = pd.Series(pd.concat(dates).values, name='date')
@@ -69,8 +71,23 @@
 
     df2 = pd.concat([dates, df2], axis=1)
     df2 = df2.set_index('date')
-    df_final = df2.resample(freq)[['pair']].count()
-    return df_final[df_final['pair'] > max_open_trades]
+    df_final = df2.resample(f"{timeframe_min}min")[['pair']].count()
+    df_final = df_final.rename({'pair': 'open_trades'}, axis=1)
+    return df_final
+
+
+def evaluate_result_multi(results: pd.DataFrame, timeframe: str,
+                          max_open_trades: int) -> pd.DataFrame:
+    """
+    Find overlapping trades by expanding each trade once per period it was open
+    and then counting overlaps
+    :param results: Results Dataframe - can be loaded
+    :param timeframe: Frequency used for the backtest
+    :param max_open_trades: parameter max_open_trades used during backtest run
+    :return: dataframe with open-counts per time-period in freq
+    """
+    df_final = analyze_trade_parallelism(results, timeframe)
+    return df_final[df_final['open_trades'] > max_open_trades]
 
 
 def load_trades_from_db(db_url: str) -> pd.DataFrame:

{"golden_diff": "diff --git a/freqtrade/data/btanalysis.py b/freqtrade/data/btanalysis.py\n--- a/freqtrade/data/btanalysis.py\n+++ b/freqtrade/data/btanalysis.py\n@@ -52,16 +52,18 @@\n     return df\n \n \n-def evaluate_result_multi(results: pd.DataFrame, freq: str, max_open_trades: int) -> pd.DataFrame:\n+def analyze_trade_parallelism(results: pd.DataFrame, timeframe: str) -> pd.DataFrame:\n     \"\"\"\n     Find overlapping trades by expanding each trade once per period it was open\n-    and then counting overlaps\n+    and then counting overlaps.\n     :param results: Results Dataframe - can be loaded\n-    :param freq: Frequency used for the backtest\n-    :param max_open_trades: parameter max_open_trades used during backtest run\n-    :return: dataframe with open-counts per time-period in freq\n+    :param timeframe: Timeframe used for backtest\n+    :return: dataframe with open-counts per time-period in timeframe\n     \"\"\"\n-    dates = [pd.Series(pd.date_range(row[1].open_time, row[1].close_time, freq=freq))\n+    from freqtrade.exchange import timeframe_to_minutes\n+    timeframe_min = timeframe_to_minutes(timeframe)\n+    dates = [pd.Series(pd.date_range(row[1].open_time, row[1].close_time,\n+                                     freq=f\"{timeframe_min}min\"))\n              for row in results[['open_time', 'close_time']].iterrows()]\n     deltas = [len(x) for x in dates]\n     dates = pd.Series(pd.concat(dates).values, name='date')\n@@ -69,8 +71,23 @@\n \n     df2 = pd.concat([dates, df2], axis=1)\n     df2 = df2.set_index('date')\n-    df_final = df2.resample(freq)[['pair']].count()\n-    return df_final[df_final['pair'] > max_open_trades]\n+    df_final = df2.resample(f\"{timeframe_min}min\")[['pair']].count()\n+    df_final = df_final.rename({'pair': 'open_trades'}, axis=1)\n+    return df_final\n+\n+\n+def evaluate_result_multi(results: pd.DataFrame, timeframe: str,\n+                          max_open_trades: int) -> pd.DataFrame:\n+    \"\"\"\n+    Find overlapping trades by expanding each trade once per period it was open\n+    and then counting overlaps\n+    :param results: Results Dataframe - can be loaded\n+    :param timeframe: Frequency used for the backtest\n+    :param max_open_trades: parameter max_open_trades used during backtest run\n+    :return: dataframe with open-counts per time-period in freq\n+    \"\"\"\n+    df_final = analyze_trade_parallelism(results, timeframe)\n+    return df_final[df_final['open_trades'] > max_open_trades]\n \n \n def load_trades_from_db(db_url: str) -> pd.DataFrame:\n", "issue": "Strategy analysis -> how many max_open_trades i will use for this strategy ?\nAs an algo trade\r\nI want to perform statistics like maximum drawdown, profit and find an optimum between stake_amount and max_open_trade so i run and export the backtest with --disable-max-market-positions flag and make simulations in jupyter.\r\nSo that i can find a comprise between risk and profit.\r\n\r\nTo archive that i need to find trades that happens at the same time and flag them (open_trade_number) and then filter then.\r\n\r\nI don't know if it can be useful to have this straight in a column of the dataframe of load_backtest_data() ?\r\n\r\nMaybe it is a too specific need.\r\n\r\nHave a nice day.\n", "before_files": [{"content": "\"\"\"\nHelpers when analyzing backtest data\n\"\"\"\nimport logging\nfrom pathlib import Path\nfrom typing import Dict\n\nimport numpy as np\nimport pandas as pd\nimport pytz\n\nfrom freqtrade import persistence\nfrom freqtrade.misc import json_load\nfrom freqtrade.persistence import Trade\n\nlogger = logging.getLogger(__name__)\n\n# must align with columns in backtest.py\nBT_DATA_COLUMNS = [\"pair\", \"profitperc\", \"open_time\", \"close_time\", \"index\", \"duration\",\n                   \"open_rate\", \"close_rate\", \"open_at_end\", \"sell_reason\"]\n\n\ndef load_backtest_data(filename) -> pd.DataFrame:\n    \"\"\"\n    Load backtest data file.\n    :param filename: pathlib.Path object, or string pointing to the file.\n    :return: a dataframe with the analysis results\n    \"\"\"\n    if isinstance(filename, str):\n        filename = Path(filename)\n\n    if not filename.is_file():\n        raise ValueError(f\"File {filename} does not exist.\")\n\n    with filename.open() as file:\n        data = json_load(file)\n\n    df = pd.DataFrame(data, columns=BT_DATA_COLUMNS)\n\n    df['open_time'] = pd.to_datetime(df['open_time'],\n                                     unit='s',\n                                     utc=True,\n                                     infer_datetime_format=True\n                                     )\n    df['close_time'] = pd.to_datetime(df['close_time'],\n                                      unit='s',\n                                      utc=True,\n                                      infer_datetime_format=True\n                                      )\n    df['profitabs'] = df['close_rate'] - df['open_rate']\n    df = df.sort_values(\"open_time\").reset_index(drop=True)\n    return df\n\n\ndef evaluate_result_multi(results: pd.DataFrame, freq: str, max_open_trades: int) -> pd.DataFrame:\n    \"\"\"\n    Find overlapping trades by expanding each trade once per period it was open\n    and then counting overlaps\n    :param results: Results Dataframe - can be loaded\n    :param freq: Frequency used for the backtest\n    :param max_open_trades: parameter max_open_trades used during backtest run\n    :return: dataframe with open-counts per time-period in freq\n    \"\"\"\n    dates = [pd.Series(pd.date_range(row[1].open_time, row[1].close_time, freq=freq))\n             for row in results[['open_time', 'close_time']].iterrows()]\n    deltas = [len(x) for x in dates]\n    dates = pd.Series(pd.concat(dates).values, name='date')\n    df2 = pd.DataFrame(np.repeat(results.values, deltas, axis=0), columns=results.columns)\n\n    df2 = pd.concat([dates, df2], axis=1)\n    df2 = df2.set_index('date')\n    df_final = df2.resample(freq)[['pair']].count()\n    return df_final[df_final['pair'] > max_open_trades]\n\n\ndef load_trades_from_db(db_url: str) -> pd.DataFrame:\n    \"\"\"\n    Load trades from a DB (using dburl)\n    :param db_url: Sqlite url (default format sqlite:///tradesv3.dry-run.sqlite)\n    :return: Dataframe containing Trades\n    \"\"\"\n    trades: pd.DataFrame = pd.DataFrame([], columns=BT_DATA_COLUMNS)\n    persistence.init(db_url, clean_open_orders=False)\n\n    columns = [\"pair\", \"open_time\", \"close_time\", \"profit\", \"profitperc\",\n               \"open_rate\", \"close_rate\", \"amount\", \"duration\", \"sell_reason\",\n               \"fee_open\", \"fee_close\", \"open_rate_requested\", \"close_rate_requested\",\n               \"stake_amount\", \"max_rate\", \"min_rate\", \"id\", \"exchange\",\n               \"stop_loss\", \"initial_stop_loss\", \"strategy\", \"ticker_interval\"]\n\n    trades = pd.DataFrame([(t.pair,\n                            t.open_date.replace(tzinfo=pytz.UTC),\n                            t.close_date.replace(tzinfo=pytz.UTC) if t.close_date else None,\n                            t.calc_profit(), t.calc_profit_percent(),\n                            t.open_rate, t.close_rate, t.amount,\n                            (round((t.close_date.timestamp() - t.open_date.timestamp()) / 60, 2)\n                                if t.close_date else None),\n                            t.sell_reason,\n                            t.fee_open, t.fee_close,\n                            t.open_rate_requested,\n                            t.close_rate_requested,\n                            t.stake_amount,\n                            t.max_rate,\n                            t.min_rate,\n                            t.id, t.exchange,\n                            t.stop_loss, t.initial_stop_loss,\n                            t.strategy, t.ticker_interval\n                            )\n                           for t in Trade.query.all()],\n                          columns=columns)\n\n    return trades\n\n\ndef load_trades(source: str, db_url: str, exportfilename: str) -> pd.DataFrame:\n    \"\"\"\n    Based on configuration option \"trade_source\":\n    * loads data from DB (using `db_url`)\n    * loads data from backtestfile (using `exportfilename`)\n    \"\"\"\n    if source == \"DB\":\n        return load_trades_from_db(db_url)\n    elif source == \"file\":\n        return load_backtest_data(Path(exportfilename))\n\n\ndef extract_trades_of_period(dataframe: pd.DataFrame, trades: pd.DataFrame) -> pd.DataFrame:\n    \"\"\"\n    Compare trades and backtested pair DataFrames to get trades performed on backtested period\n    :return: the DataFrame of a trades of period\n    \"\"\"\n    trades = trades.loc[(trades['open_time'] >= dataframe.iloc[0]['date']) &\n                        (trades['close_time'] <= dataframe.iloc[-1]['date'])]\n    return trades\n\n\ndef combine_tickers_with_mean(tickers: Dict[str, pd.DataFrame], column: str = \"close\"):\n    \"\"\"\n    Combine multiple dataframes \"column\"\n    :param tickers: Dict of Dataframes, dict key should be pair.\n    :param column: Column in the original dataframes to use\n    :return: DataFrame with the column renamed to the dict key, and a column\n        named mean, containing the mean of all pairs.\n    \"\"\"\n    df_comb = pd.concat([tickers[pair].set_index('date').rename(\n        {column: pair}, axis=1)[pair] for pair in tickers], axis=1)\n\n    df_comb['mean'] = df_comb.mean(axis=1)\n\n    return df_comb\n\n\ndef create_cum_profit(df: pd.DataFrame, trades: pd.DataFrame, col_name: str,\n                      timeframe: str) -> pd.DataFrame:\n    \"\"\"\n    Adds a column `col_name` with the cumulative profit for the given trades array.\n    :param df: DataFrame with date index\n    :param trades: DataFrame containing trades (requires columns close_time and profitperc)\n    :param col_name: Column name that will be assigned the results\n    :param timeframe: Timeframe used during the operations\n    :return: Returns df with one additional column, col_name, containing the cumulative profit.\n    \"\"\"\n    from freqtrade.exchange import timeframe_to_minutes\n    ticker_minutes = timeframe_to_minutes(timeframe)\n    # Resample to ticker_interval to make sure trades match candles\n    _trades_sum = trades.resample(f'{ticker_minutes}min', on='close_time')[['profitperc']].sum()\n    df.loc[:, col_name] = _trades_sum.cumsum()\n    # Set first value to 0\n    df.loc[df.iloc[0].name, col_name] = 0\n    # FFill to get continuous\n    df[col_name] = df[col_name].ffill()\n    return df\n", "path": "freqtrade/data/btanalysis.py"}], "after_files": [{"content": "\"\"\"\nHelpers when analyzing backtest data\n\"\"\"\nimport logging\nfrom pathlib import Path\nfrom typing import Dict\n\nimport numpy as np\nimport pandas as pd\nimport pytz\n\nfrom freqtrade import persistence\nfrom freqtrade.misc import json_load\nfrom freqtrade.persistence import Trade\n\nlogger = logging.getLogger(__name__)\n\n# must align with columns in backtest.py\nBT_DATA_COLUMNS = [\"pair\", \"profitperc\", \"open_time\", \"close_time\", \"index\", \"duration\",\n                   \"open_rate\", \"close_rate\", \"open_at_end\", \"sell_reason\"]\n\n\ndef load_backtest_data(filename) -> pd.DataFrame:\n    \"\"\"\n    Load backtest data file.\n    :param filename: pathlib.Path object, or string pointing to the file.\n    :return: a dataframe with the analysis results\n    \"\"\"\n    if isinstance(filename, str):\n        filename = Path(filename)\n\n    if not filename.is_file():\n        raise ValueError(f\"File {filename} does not exist.\")\n\n    with filename.open() as file:\n        data = json_load(file)\n\n    df = pd.DataFrame(data, columns=BT_DATA_COLUMNS)\n\n    df['open_time'] = pd.to_datetime(df['open_time'],\n                                     unit='s',\n                                     utc=True,\n                                     infer_datetime_format=True\n                                     )\n    df['close_time'] = pd.to_datetime(df['close_time'],\n                                      unit='s',\n                                      utc=True,\n                                      infer_datetime_format=True\n                                      )\n    df['profitabs'] = df['close_rate'] - df['open_rate']\n    df = df.sort_values(\"open_time\").reset_index(drop=True)\n    return df\n\n\ndef analyze_trade_parallelism(results: pd.DataFrame, timeframe: str) -> pd.DataFrame:\n    \"\"\"\n    Find overlapping trades by expanding each trade once per period it was open\n    and then counting overlaps.\n    :param results: Results Dataframe - can be loaded\n    :param timeframe: Timeframe used for backtest\n    :return: dataframe with open-counts per time-period in timeframe\n    \"\"\"\n    from freqtrade.exchange import timeframe_to_minutes\n    timeframe_min = timeframe_to_minutes(timeframe)\n    dates = [pd.Series(pd.date_range(row[1].open_time, row[1].close_time,\n                                     freq=f\"{timeframe_min}min\"))\n             for row in results[['open_time', 'close_time']].iterrows()]\n    deltas = [len(x) for x in dates]\n    dates = pd.Series(pd.concat(dates).values, name='date')\n    df2 = pd.DataFrame(np.repeat(results.values, deltas, axis=0), columns=results.columns)\n\n    df2 = pd.concat([dates, df2], axis=1)\n    df2 = df2.set_index('date')\n    df_final = df2.resample(f\"{timeframe_min}min\")[['pair']].count()\n    df_final = df_final.rename({'pair': 'open_trades'}, axis=1)\n    return df_final\n\n\ndef evaluate_result_multi(results: pd.DataFrame, timeframe: str,\n                          max_open_trades: int) -> pd.DataFrame:\n    \"\"\"\n    Find overlapping trades by expanding each trade once per period it was open\n    and then counting overlaps\n    :param results: Results Dataframe - can be loaded\n    :param timeframe: Frequency used for the backtest\n    :param max_open_trades: parameter max_open_trades used during backtest run\n    :return: dataframe with open-counts per time-period in freq\n    \"\"\"\n    df_final = analyze_trade_parallelism(results, timeframe)\n    return df_final[df_final['open_trades'] > max_open_trades]\n\n\ndef load_trades_from_db(db_url: str) -> pd.DataFrame:\n    \"\"\"\n    Load trades from a DB (using dburl)\n    :param db_url: Sqlite url (default format sqlite:///tradesv3.dry-run.sqlite)\n    :return: Dataframe containing Trades\n    \"\"\"\n    trades: pd.DataFrame = pd.DataFrame([], columns=BT_DATA_COLUMNS)\n    persistence.init(db_url, clean_open_orders=False)\n\n    columns = [\"pair\", \"open_time\", \"close_time\", \"profit\", \"profitperc\",\n               \"open_rate\", \"close_rate\", \"amount\", \"duration\", \"sell_reason\",\n               \"fee_open\", \"fee_close\", \"open_rate_requested\", \"close_rate_requested\",\n               \"stake_amount\", \"max_rate\", \"min_rate\", \"id\", \"exchange\",\n               \"stop_loss\", \"initial_stop_loss\", \"strategy\", \"ticker_interval\"]\n\n    trades = pd.DataFrame([(t.pair,\n                            t.open_date.replace(tzinfo=pytz.UTC),\n                            t.close_date.replace(tzinfo=pytz.UTC) if t.close_date else None,\n                            t.calc_profit(), t.calc_profit_percent(),\n                            t.open_rate, t.close_rate, t.amount,\n                            (round((t.close_date.timestamp() - t.open_date.timestamp()) / 60, 2)\n                                if t.close_date else None),\n                            t.sell_reason,\n                            t.fee_open, t.fee_close,\n                            t.open_rate_requested,\n                            t.close_rate_requested,\n                            t.stake_amount,\n                            t.max_rate,\n                            t.min_rate,\n                            t.id, t.exchange,\n                            t.stop_loss, t.initial_stop_loss,\n                            t.strategy, t.ticker_interval\n                            )\n                           for t in Trade.query.all()],\n                          columns=columns)\n\n    return trades\n\n\ndef load_trades(source: str, db_url: str, exportfilename: str) -> pd.DataFrame:\n    \"\"\"\n    Based on configuration option \"trade_source\":\n    * loads data from DB (using `db_url`)\n    * loads data from backtestfile (using `exportfilename`)\n    \"\"\"\n    if source == \"DB\":\n        return load_trades_from_db(db_url)\n    elif source == \"file\":\n        return load_backtest_data(Path(exportfilename))\n\n\ndef extract_trades_of_period(dataframe: pd.DataFrame, trades: pd.DataFrame) -> pd.DataFrame:\n    \"\"\"\n    Compare trades and backtested pair DataFrames to get trades performed on backtested period\n    :return: the DataFrame of a trades of period\n    \"\"\"\n    trades = trades.loc[(trades['open_time'] >= dataframe.iloc[0]['date']) &\n                        (trades['close_time'] <= dataframe.iloc[-1]['date'])]\n    return trades\n\n\ndef combine_tickers_with_mean(tickers: Dict[str, pd.DataFrame], column: str = \"close\"):\n    \"\"\"\n    Combine multiple dataframes \"column\"\n    :param tickers: Dict of Dataframes, dict key should be pair.\n    :param column: Column in the original dataframes to use\n    :return: DataFrame with the column renamed to the dict key, and a column\n        named mean, containing the mean of all pairs.\n    \"\"\"\n    df_comb = pd.concat([tickers[pair].set_index('date').rename(\n        {column: pair}, axis=1)[pair] for pair in tickers], axis=1)\n\n    df_comb['mean'] = df_comb.mean(axis=1)\n\n    return df_comb\n\n\ndef create_cum_profit(df: pd.DataFrame, trades: pd.DataFrame, col_name: str,\n                      timeframe: str) -> pd.DataFrame:\n    \"\"\"\n    Adds a column `col_name` with the cumulative profit for the given trades array.\n    :param df: DataFrame with date index\n    :param trades: DataFrame containing trades (requires columns close_time and profitperc)\n    :param col_name: Column name that will be assigned the results\n    :param timeframe: Timeframe used during the operations\n    :return: Returns df with one additional column, col_name, containing the cumulative profit.\n    \"\"\"\n    from freqtrade.exchange import timeframe_to_minutes\n    ticker_minutes = timeframe_to_minutes(timeframe)\n    # Resample to ticker_interval to make sure trades match candles\n    _trades_sum = trades.resample(f'{ticker_minutes}min', on='close_time')[['profitperc']].sum()\n    df.loc[:, col_name] = _trades_sum.cumsum()\n    # Set first value to 0\n    df.loc[df.iloc[0].name, col_name] = 0\n    # FFill to get continuous\n    df[col_name] = df[col_name].ffill()\n    return df\n", "path": "freqtrade/data/btanalysis.py"}]}