Skip to content

Commit 2c47212

Browse files
committed
REF: Save only df.index in _Array._opts instead of the full df
This should somewhat decrease serialized size when pickling `_Array` objects over multiprocessing.
1 parent d4c76c7 commit 2c47212

File tree

4 files changed

+13
-9
lines changed

4 files changed

+13
-9
lines changed

backtesting/_plotting.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,8 @@ def _maybe_resample_data(resample_rule, df, indicators, equity_data, trades):
110110
indicators = [_Indicator(i.df.resample(freq, label='right').mean()
111111
.dropna().reindex(df.index).values.T,
112112
**dict(i._opts, name=i.name,
113-
# HACK: override `data` for its index
114-
data=pd.Series(np.nan, index=df.index)))
113+
# Replace saved index with the resampled one
114+
index=df.index))
115115
for i in indicators]
116116
assert not indicators or indicators[0].df.index.equals(df.index)
117117

backtesting/_util.py

+7-5
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,14 @@ def to_series(self):
8585
@property
8686
def s(self) -> pd.Series:
8787
values = np.atleast_2d(self)
88-
return pd.Series(values[0], index=self._opts['data'].index, name=self.name)
88+
index = self._opts['index'][:values.shape[1]]
89+
return pd.Series(values[0], index=index, name=self.name)
8990

9091
@property
9192
def df(self) -> pd.DataFrame:
9293
values = np.atleast_2d(np.asarray(self))
93-
df = pd.DataFrame(values.T, index=self._opts['data'].index,
94-
columns=[self.name] * len(values))
94+
index = self._opts['index'][:values.shape[1]]
95+
df = pd.DataFrame(values.T, index=index, columns=[self.name] * len(values))
9596
return df
9697

9798

@@ -128,10 +129,11 @@ def _set_length(self, i):
128129
self.__cache.clear()
129130

130131
def _update(self):
131-
self.__arrays = {col: _Array(arr, data=self)
132+
index = self.__df.index.copy()
133+
self.__arrays = {col: _Array(arr, index=index)
132134
for col, arr in self.__df.items()}
133135
# Leave index as Series because pd.Timestamp nicer API to work with
134-
self.__arrays['__index'] = self.__df.index.copy()
136+
self.__arrays['__index'] = index
135137

136138
def __repr__(self):
137139
i = min(self.__i, len(self.__df) - 1)

backtesting/backtesting.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ def init():
153153
value = _Indicator(value, name=name, plot=plot, overlay=overlay,
154154
color=color, scatter=scatter,
155155
# _Indicator.s Series accessor uses this:
156-
data=self.data)
156+
index=self.data.index)
157157
self._indicators.append(value)
158158
return value
159159

backtesting/test/_test.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -901,9 +901,11 @@ def next(self):
901901
Backtest(GOOG.iloc[:20], S).run()
902902

903903
def test_indicators_picklable(self):
904+
bt = Backtest(SHORT_DATA, SmaCross)
904905
with ProcessPoolExecutor() as executor:
905-
stats = executor.submit(Backtest.run, Backtest(SHORT_DATA, SmaCross)).result()
906+
stats = executor.submit(Backtest.run, bt).result()
906907
assert stats._strategy._indicators[0]._opts, '._opts and .name were not unpickled'
908+
bt.plot(results=stats, resample='2d', open_browser=False)
907909

908910

909911
class TestDocs(TestCase):

0 commit comments

Comments
 (0)