stefan-jansen / pyfolio-reloaded

Portfolio and risk analytics in Python
https://pyfolio.ml4trading.io/
Apache License 2.0
348 stars 109 forks source link

plot_rolling_returns: Passing list-likes to .loc or [] with any missing labels is no longer supported. #11

Closed yingh2013 closed 2 years ago

yingh2013 commented 2 years ago

Problem Description

https://github.com/stefan-jansen/machine-learning-for-trading/blob/main/18_convolutional_neural_nets/08_backtesting_with_zipline.ipynb

plot_rolling_returns: Passing list-likes to .loc or [] with any missing labels is no longer supported.

Please provide a minimal, self-contained, and reproducible example:

.........
PyFolio Analysis
returns, positions, transactions = pf.utils.extract_rets_pos_txn_from_zipline(results)
benchmark = web.DataReader('SP500', 'fred', '2010', '2018').squeeze()
benchmark = benchmark.pct_change().tz_localize('UTC')
LIVE_DATE = '2018-01-01'
fig, axes = plt.subplots(ncols=2, figsize=(16, 5))
plot_rolling_returns(returns,
                     factor_returns=benchmark,
                     live_start_date=LIVE_DATE,
                     logy=False,
                     cone_std=2,
                     legend_loc='best',
                     volatility_match=False,
                     cone_function=forecast_cone_bootstrap,
                     ax=axes[0])
plot_rolling_sharpe(returns, ax=axes[1], rolling_window=63)
axes[0].set_title('Cumulative Returns - In and Out-of-Sample')
axes[1].set_title('Rolling Sharpe Ratio (3 Months)')
fig.tight_layout()
fig.savefig((results_path / 'pyfolio_out_of_sample').as_posix(), dpi=300)

Please provide the full traceback:


---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
/tmp/ipykernel_1051187/904506437.py in <module>
      1 fig, axes = plt.subplots(ncols=2, figsize=(16, 5))
----> 2 plot_rolling_returns(returns,
      3                      factor_returns=benchmark,
      4                      live_start_date=LIVE_DATE,
      5                      logy=False,

/media/ralph/ssda1/ml4t/env_tf27/lib/python3.8/site-packages/pyfolio/plotting.py in plot_rolling_returns(returns, factor_returns, live_start_date, logy, cone_std, legend_loc, volatility_match, cone_function, ax, **kwargs)
    816     if factor_returns is not None:
    817         cum_factor_returns = ep.cum_returns(
--> 818             factor_returns[cum_rets.index], 1.0
    819         )
    820         cum_factor_returns.plot(

/media/ralph/ssda1/ml4t/env_tf27/lib/python3.8/site-packages/pandas/core/series.py in __getitem__(self, key)
    875             return self._get_values(key)
    876 
--> 877         return self._get_with(key)
    878 
    879     def _get_with(self, key):

/media/ralph/ssda1/ml4t/env_tf27/lib/python3.8/site-packages/pandas/core/series.py in _get_with(self, key)
    915 
    916         # handle the dup indexing case GH#4246
--> 917         return self.loc[key]
    918 
    919     def _get_values_tuple(self, key):

/media/ralph/ssda1/ml4t/env_tf27/lib/python3.8/site-packages/pandas/core/indexing.py in __getitem__(self, key)
    893 
    894             maybe_callable = com.apply_if_callable(key, self.obj)
--> 895             return self._getitem_axis(maybe_callable, axis=axis)
    896 
    897     def _is_scalar_access(self, key: Tuple):

/media/ralph/ssda1/ml4t/env_tf27/lib/python3.8/site-packages/pandas/core/indexing.py in _getitem_axis(self, key, axis)
   1111                     raise ValueError("Cannot index with multidimensional key")
   1112 
-> 1113                 return self._getitem_iterable(key, axis=axis)
   1114 
   1115             # nested tuple slicing

/media/ralph/ssda1/ml4t/env_tf27/lib/python3.8/site-packages/pandas/core/indexing.py in _getitem_iterable(self, key, axis)
   1051 
   1052         # A collection of keys
-> 1053         keyarr, indexer = self._get_listlike_indexer(key, axis, raise_missing=False)
   1054         return self.obj._reindex_with_indexers(
   1055             {axis: [keyarr, indexer]}, copy=True, allow_dups=True

/media/ralph/ssda1/ml4t/env_tf27/lib/python3.8/site-packages/pandas/core/indexing.py in _get_listlike_indexer(self, key, axis, raise_missing)
   1264             keyarr, indexer, new_indexer = ax._reindex_non_unique(keyarr)
   1265 
-> 1266         self._validate_read_indexer(keyarr, indexer, axis, raise_missing=raise_missing)
   1267         return keyarr, indexer
   1268 

/media/ralph/ssda1/ml4t/env_tf27/lib/python3.8/site-packages/pandas/core/indexing.py in _validate_read_indexer(self, key, indexer, axis, raise_missing)
   1319 
   1320             with option_context("display.max_seq_items", 10, "display.width", 80):
-> 1321                 raise KeyError(
   1322                     "Passing list-likes to .loc or [] with any missing labels "
   1323                     "is no longer supported. "

KeyError: "Passing list-likes to .loc or [] with any missing labels is no longer supported. The following labels were missing: DatetimeIndex(['2011-04-27 00:00:00+00:00', '2011-04-28 00:00:00+00:00',\n               '2011-04-29 00:00:00+00:00', '2011-05-02 00:00:00+00:00',\n               '2011-05-03 00:00:00+00:00',\n               ...\n               '2011-11-10 00:00:00+00:00', '2011-11-11 00:00:00+00:00',\n               '2011-11-14 00:00:00+00:00', '2011-11-15 00:00:00+00:00',\n               '2011-11-16 00:00:00+00:00'],\n              dtype='datetime64[ns, UTC]', length=143, freq=None). See https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#deprecate-loc-reindex-listlike"

Please provide any additional information below:

Versions

yingh2013 commented 2 years ago

it can run if I use None as input parameter for factor_returns. then I found that benchmark1 has short history than returns history. so, here is what I did:

mask = returns.index.intersection(benchmark.index) returns1 = returns[mask] benchmark1 = benchmark[mask]

plot_rolling_returns(returns1, factor_returns=benchmark1, live_start_date=LIVE_DATE, logy=False, cone_std=2, legend_loc='best', volatility_match=False, cone_function=forecast_cone_bootstrap, ax=axes[0])