(resample_rule, df, indicators, equity_data, trades)
| 115 | |
| 116 | |
| 117 | def _maybe_resample_data(resample_rule, df, indicators, equity_data, trades): |
| 118 | if isinstance(resample_rule, str): |
| 119 | freq = resample_rule |
| 120 | else: |
| 121 | if resample_rule is False or len(df) <= _MAX_CANDLES: |
| 122 | return df, indicators, equity_data, trades |
| 123 | |
| 124 | freq_minutes = pd.Series({ |
| 125 | "1min": 1, |
| 126 | "5min": 5, |
| 127 | "10min": 10, |
| 128 | "15min": 15, |
| 129 | "30min": 30, |
| 130 | "1h": 60, |
| 131 | "2h": 60 * 2, |
| 132 | "4h": 60 * 4, |
| 133 | "8h": 60 * 8, |
| 134 | "1D": 60 * 24, |
| 135 | "1W": 60 * 24 * 7, |
| 136 | "1ME": np.inf, |
| 137 | }) |
| 138 | timespan = df.index[-1] - df.index[0] |
| 139 | require_minutes = (timespan / _MAX_CANDLES).total_seconds() // 60 |
| 140 | freq = freq_minutes.where(freq_minutes >= require_minutes).first_valid_index() |
| 141 | warnings.warn(f"Data contains too many candlesticks to plot; downsampling to {freq!r}. " |
| 142 | "See `Backtest.plot(resample=...)`") |
| 143 | |
| 144 | from .lib import OHLCV_AGG, TRADES_AGG, _EQUITY_AGG |
| 145 | df = df.resample(freq, label='right').agg(OHLCV_AGG).dropna() |
| 146 | |
| 147 | def try_mean_first(indicator): |
| 148 | nonlocal freq |
| 149 | resampled = indicator.df.fillna(np.nan).resample(freq, label='right') |
| 150 | try: |
| 151 | return resampled.mean() |
| 152 | except Exception: |
| 153 | return resampled.first() |
| 154 | |
| 155 | indicators = [_Indicator(try_mean_first(i).dropna().reindex(df.index).values.T, |
| 156 | **dict(i._opts, name=i.name, |
| 157 | # Replace saved index with the resampled one |
| 158 | index=df.index)) |
| 159 | for i in indicators] |
| 160 | assert not indicators or indicators[0].df.index.equals(df.index) |
| 161 | |
| 162 | equity_data = equity_data.resample(freq, label='right').agg(_EQUITY_AGG).dropna(how='all') |
| 163 | assert equity_data.index.equals(df.index) |
| 164 | |
| 165 | def _weighted_returns(s, trades=trades): |
| 166 | df = trades.loc[s.index] |
| 167 | return ((df['Size'].abs() * df['ReturnPct']) / df['Size'].abs().sum()).sum() |
| 168 | |
| 169 | def _group_trades(column): |
| 170 | def f(s, new_index=pd.Index(df.index.astype(np.int64)), bars=trades[column]): |
| 171 | if s.size: |
| 172 | # Via int64 because on pandas recently broken datetime |
| 173 | mean_time = int(bars.loc[s.index].astype(np.int64).mean()) |
| 174 | new_bar_idx = new_index.get_indexer([mean_time], method='nearest')[0] |
no test coverage detected