Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plot resample=True: DataError: No numeric types to aggregate #309

Open
Haakam21 opened this issue Apr 13, 2021 · 4 comments
Open

Plot resample=True: DataError: No numeric types to aggregate #309

Haakam21 opened this issue Apr 13, 2021 · 4 comments
Labels
bug Something isn't working Hacktoberfest https://hacktoberfest.digitalocean.com

Comments

@Haakam21
Copy link

Expected Behavior

No errors, plot shows.

Actual Behavior

/usr/local/lib/python3.7/dist-packages/backtesting/_plotting.py:104: UserWarning: Data contains too many candlesticks to plot; downsampling to '15T'. See `Backtest.plot(resample=...)`
  warnings.warn(f"Data contains too many candlesticks to plot; downsampling to {freq!r}. "
---------------------------------------------------------------------------
DataError                                 Traceback (most recent call last)
<ipython-input-25-5a9b4a5c2a1c> in <module>()
----> 1 bt.plot(resample=True)

11 frames
/usr/local/lib/python3.7/dist-packages/backtesting/backtesting.py in plot(self, results, filename, plot_width, plot_equity, plot_return, plot_pl, plot_volume, plot_drawdown, smooth_equity, relative_equity, superimpose, resample, reverse_indicators, show_legend, open_browser)
   1719             reverse_indicators=reverse_indicators,
   1720             show_legend=show_legend,
-> 1721             open_browser=open_browser)

/usr/local/lib/python3.7/dist-packages/backtesting/_plotting.py in plot(results, df, indicators, filename, plot_width, plot_equity, plot_return, plot_pl, plot_volume, plot_drawdown, smooth_equity, relative_equity, superimpose, resample, reverse_indicators, show_legend, open_browser)
    184     if is_datetime_index:
    185         df, indicators, equity_data, trades = _maybe_resample_data(
--> 186             resample, df, indicators, equity_data, trades)
    187 
    188     df.index.name = None  # Provides source name @index

/usr/local/lib/python3.7/dist-packages/backtesting/_plotting.py in _maybe_resample_data(resample_rule, df, indicators, equity_data, trades)
    113                                     # HACK: override `data` for its index
    114                                     data=pd.Series(np.nan, index=df.index)))
--> 115                   for i in indicators]
    116     assert not indicators or indicators[0].df.index.equals(df.index)
    117 

/usr/local/lib/python3.7/dist-packages/backtesting/_plotting.py in <listcomp>(.0)
    113                                     # HACK: override `data` for its index
    114                                     data=pd.Series(np.nan, index=df.index)))
--> 115                   for i in indicators]
    116     assert not indicators or indicators[0].df.index.equals(df.index)
    117 

/usr/local/lib/python3.7/dist-packages/pandas/core/resample.py in g(self, _method, *args, **kwargs)
    935     def g(self, _method=method, *args, **kwargs):
    936         nv.validate_resampler_func(_method, args, kwargs)
--> 937         return self._downsample(_method)
    938 
    939     g.__doc__ = getattr(GroupBy, method).__doc__

/usr/local/lib/python3.7/dist-packages/pandas/core/resample.py in _downsample(self, how, **kwargs)
   1041         # we are downsampling
   1042         # we want to call the actual grouper method here
-> 1043         result = obj.groupby(self.grouper, axis=self.axis).aggregate(how, **kwargs)
   1044 
   1045         result = self._apply_loffset(result)

/usr/local/lib/python3.7/dist-packages/pandas/core/groupby/generic.py in aggregate(self, func, engine, engine_kwargs, *args, **kwargs)
    949         func = maybe_mangle_lambdas(func)
    950 
--> 951         result, how = self._aggregate(func, *args, **kwargs)
    952         if how is None:
    953             return result

/usr/local/lib/python3.7/dist-packages/pandas/core/base.py in _aggregate(self, arg, *args, **kwargs)
    305 
    306         if isinstance(arg, str):
--> 307             return self._try_aggregate_string_function(arg, *args, **kwargs), None
    308 
    309         if isinstance(arg, dict):

/usr/local/lib/python3.7/dist-packages/pandas/core/base.py in _try_aggregate_string_function(self, arg, *args, **kwargs)
    261         if f is not None:
    262             if callable(f):
--> 263                 return f(*args, **kwargs)
    264 
    265             # people may try to aggregate on a non-callable attribute

/usr/local/lib/python3.7/dist-packages/pandas/core/groupby/groupby.py in mean(self, numeric_only)
   1396             "mean",
   1397             alt=lambda x, axis: Series(x).mean(numeric_only=numeric_only),
-> 1398             numeric_only=numeric_only,
   1399         )
   1400 

/usr/local/lib/python3.7/dist-packages/pandas/core/groupby/generic.py in _cython_agg_general(self, how, alt, numeric_only, min_count)
   1020     ) -> DataFrame:
   1021         agg_blocks, agg_items = self._cython_agg_blocks(
-> 1022             how, alt=alt, numeric_only=numeric_only, min_count=min_count
   1023         )
   1024         return self._wrap_agged_blocks(agg_blocks, items=agg_items)

/usr/local/lib/python3.7/dist-packages/pandas/core/groupby/generic.py in _cython_agg_blocks(self, how, alt, numeric_only, min_count)
   1128 
   1129         if not (agg_blocks or split_frames):
-> 1130             raise DataError("No numeric types to aggregate")
   1131 
   1132         if split_items:

DataError: No numeric types to aggregate

Steps to Reproduce

Dataframe:

                                Low      High      Open     Close    Volume
time                                                                       
2021-01-01 00:00:00-05:00  29265.74  29299.56  29292.74  29287.87  0.949564
2021-01-01 00:01:00-05:00  29266.47  29288.03  29284.16  29266.47  0.567982
2021-01-01 00:02:00-05:00  29233.22  29265.01  29265.01  29234.09  0.886784
2021-01-01 00:03:00-05:00  29210.85  29250.01  29234.08  29210.86  0.601799
2021-01-01 00:04:00-05:00  29199.03  29239.87  29199.03  29239.24  0.275364
...                             ...       ...       ...       ...       ...
2021-03-31 23:55:00-04:00  59023.33  59054.50  59033.91  59042.72  0.934562
2021-03-31 23:56:00-04:00  59042.71  59049.49  59042.72  59048.45  0.027263
2021-03-31 23:57:00-04:00  59023.34  59065.00  59042.72  59058.80  0.318494
2021-03-31 23:58:00-04:00  59065.00  59141.90  59065.00  59088.48  0.362681
2021-03-31 23:59:00-04:00  59088.48  59135.54  59088.48  59135.54  0.104990

[129330 rows x 5 columns]

Code:

bt = Backtest(data, MyStrategy, cash=1000000, commission=0.001)
stats = bt.run()
bt.plot(resample=True)

Additional info

  • Backtesting version: 0.3.1
@kernc
Copy link
Owner

kernc commented Apr 13, 2021

This breaks in .mean():

indicators = [_Indicator(i.df.resample(freq, label='right').mean()
.dropna().reindex(df.index).values.T,
**dict(i._opts, name=i.name,
# Replace saved index with the resampled one
index=df.index))
for i in indicators]

I'm assuming, is your strategy creating an indicator that is not numeric? Such as:

        self.I(np.random.choice, ['a', 'b'], len(self.data))

@Haakam21
Copy link
Author

In some sense you are correct. I am using Tulip and for lagging indicators, it returns shorter arrays. To circumvent this, I pad the array with None values. This causes the plotting error when resampling. So the fix is to use 0 or some numerical value for padding.

@kernc
Copy link
Owner

kernc commented Apr 13, 2021

So the fix is to use 0 or some numerical value for padding.

The standard for numeric arrays is NaN: np.nan.


I think we might want to catch/mitigate this.

@kernc kernc reopened this Apr 13, 2021
@kernc kernc added the bug Something isn't working label Apr 13, 2021
@Haakam21
Copy link
Author

Oh ok. Yes, Nan is better. Sorry for preemptively closing the issue.

@kernc kernc changed the title Plot error when resampling Plot resample=True: DataError: No numeric types to aggregate Apr 13, 2021
@kernc kernc added the Hacktoberfest https://hacktoberfest.digitalocean.com label Oct 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working Hacktoberfest https://hacktoberfest.digitalocean.com
Projects
None yet
Development

No branches or pull requests

2 participants