Closed gcmsrc closed 5 months ago
Sorry for the late reply. Sounds like this could indeed be a problem. PRs are welcome in case you want to come up with a solution?
Closing due to lack of activity; feel free to reopen if the issue persists, or submit a PR.
Date index inconsistency when creating input for
pyfolio
In a nutshell
alphalens
-generated input forpyfolio
(e.g., returns series) is indexed using a 1D resampled index. This implies that non-trading days would be present in the portfolio returns series (e.g., December 25th would be there).Example
Using your example notebook, we get the following:
Index of
pf_returns
fromalphalens
-generated input forpyfolio
(including non-trading days)Index of original
factor_data
(following trading calendar)As you can see, January 10th, 2015 (a Saturday) is not in
factor_data
but it is present inpf_returns
.Implications
While this is not an issue per se, inconsistencies emerge when running, for example,
pyfolio.timeseries.perf_stats
(link). In the case ofempyrical.stats.annual_return
(link) - for example - annual return would calculate # of years using the default annualization factor for trading calendars (i.e., 252 days) instead of 365 days as per a full calendar year. This results in a inconsistent calculation.In particular, in
empyrical.stats.annual_return
, # of years is calculated as:num_years = len(returns) / ann_factor
where
len(returns)
- ifreturns
is portfolio return coming fromalpha lens.performance.create_pyfolio_input
- will be inflated by including non-trading days. To calculate # years, as of current implementation, we will divide number of days (including non trading days) by 252. For example, # years for a portfolio returns series starting for 2002/01/01 to 2003/01/01 will be equal to 365 / 252 instead of 365 / 365.Feedback
@stefan-jansen - am I missing something here? As of now, I am taking the output of
alphalens.performance.create_pyfolio_input
and filter it by keeping only rows for trading days. An alternative option would be that of letting the user specify theannualization
argument ofempyrical.stats.annual_return
inalphalens.performance.create_pyfolio_input
(and propagate the change downstream to all dependent methods). What do you think?