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

qs.reports.html(), ValueError: cannot convert float NaN to integer #58

Closed
nistrup opened this issue Dec 27, 2020 · 17 comments
Closed

qs.reports.html(), ValueError: cannot convert float NaN to integer #58

nistrup opened this issue Dec 27, 2020 · 17 comments

Comments

@nistrup
Copy link

nistrup commented Dec 27, 2020

Hi, I'm experiencing problems simply using the example from the README to make a report, ie.:

%matplotlib inline
import quantstats as qs

# extend pandas functionality with metrics, etc.
qs.extend_pandas()

# fetch the daily returns for a stock
stock = qs.utils.download_returns('FB')

qs.reports.html(stock, "SPY)

This results in

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-112-5ce6901da6d9> in <module>
----> 1 qs.reports.html(stock, benchmark)

~/WORKSPACE/venv/lib/python3.8/site-packages/quantstats/reports.py in html(returns, benchmark, rf, grayscale, title, output, compounded)
     56     tpl = tpl.replace('{{v}}', __version__)
     57 
---> 58     mtrx = metrics(returns=returns, benchmark=benchmark,
     59                    rf=rf, display=False, mode='full',
     60                    sep=True, internal="True",

~/WORKSPACE/venv/lib/python3.8/site-packages/quantstats/reports.py in metrics(returns, benchmark, rf, display, mode, sep, compounded, **kwargs)
    297 
    298     # return df
--> 299     dd = _calc_dd(df, display=(display or "internal" in kwargs))
    300 
    301     metrics = _pd.DataFrame()

~/WORKSPACE/venv/lib/python3.8/site-packages/quantstats/reports.py in _calc_dd(df, display)
    573                 by='max drawdown', ascending=True
    574             )['max drawdown'].values[0] / pct,
--> 575             'Longest DD Days': str(round(ret_dd.sort_values(
    576                 by='days', ascending=False)['days'].values[0])),
    577             'Avg. Drawdown %': ret_dd['max drawdown'].mean() / pct,

ValueError: cannot convert float NaN to integer

Any help would be much appreciated.

@orshemtov
Copy link

I've encountered the same issue

@TradeProphet
Copy link

same here

@Onepamopa
Copy link

And how long are the backtests you guys running? Cause I've not seen any such errors but my tests are >10 years.

@TradeProphet
Copy link

TradeProphet commented Dec 31, 2020 via email

@gmjohns
Copy link
Contributor

gmjohns commented Jan 4, 2021

has anyone found a solution to this?

@TradeProphet
Copy link

TradeProphet commented Jan 5, 2021 via email

@ranaroussi
Copy link
Owner

Hi @nistrup - I can't seem to reproduce this. Can you please post the returns csv here?

Thanks!

@Onepamopa
Copy link

Onepamopa commented Jan 5, 2021

@ranaroussi it does occur, so does the "Inf" problem as well, I had to adjust several functions and replace Inf & so forth with 0.
stats.py rolling_greeks:
result = _pd.DataFrame(index=returns.index, data={
"beta": beta,
"alpha": alpha
}).fillna(0)
result = result.replace([_np.inf, -_np.inf, -0], 0) # Replace any Inf's with 0 (taken from to_drawdown_series())
return result

stats.py ulcer_index:
dd = dd.replace([_np.inf, -_np.inf, -0], 0) # Replace any Inf's with 0 (taken from to_drawdown_series())

result = _np.sqrt(_np.divide((dd**2).sum(), returns.shape[0] - 1))
return result

The problem is not with _prepare_returns - I checked - it doesn't have any NaN or Inf, but they appear after some calculation (placed in a new dataframe).

@Onepamopa
Copy link

I can post the returns dataframe (as sent to quantstats), if that'll help.
I get it from a "cash_market" analyzer in backtrader and convert it as:
rets = self.analyzers.getbyname(self.testId).get_analysis()
#self.log.debug(rets)
df_values = pd.DataFrame(rets).T # .T = transpose
df_values = df_values.iloc[:, 1]
returns = qs.utils.to_returns(df_values, rf=0.)
returns.index = pd.to_datetime(returns.index)

returns is then sent to qs.reports.html(returns=returns, . . . . . . .)

@ranaroussi
Copy link
Owner

@Onepamopa - It will help :) Please post the returns dataframe here. Thanks!

@TradeProphet
Copy link

TradeProphet commented Jan 5, 2021 via email

@Onepamopa
Copy link

Onepamopa commented Jan 5, 2021

@ranaroussi Here's the dataframe after calling to_returns()
df.txt

@gmjohns
Copy link
Contributor

gmjohns commented Jan 5, 2021

@ranaroussi I'll include mine as well. This is obviously before converting to returns:
nlv.txt

ranaroussi added a commit that referenced this issue Jan 5, 2021
@ranaroussi
Copy link
Owner

ranaroussi commented Jan 5, 2021

Please upgrade to 0.0.26 by running pip install quantstats -U and let me know if at least some of the problems were fixed. I was able to create a tearsheet with your data without problems using the new verison

@Onepamopa
Copy link

I'll check tomorrow and let you know.

@gmjohns
Copy link
Contributor

gmjohns commented Jan 6, 2021

for me the latest version fixed the error stated in this original issue.... still not producing a report tho:

   3209             if (isinstance(converted_limit, Real)
   3210                     and not np.isfinite(converted_limit)):
-> 3211                 raise ValueError("Axis limits cannot be NaN or Inf")
   3212             return converted_limit
   3213 

ValueError: Axis limits cannot be NaN or Inf

I'll try to debug this, could be something simple

@oudingfan
Copy link

for me the latest version fixed the error stated in this original issue.... still not producing a report tho:

   3209             if (isinstance(converted_limit, Real)
   3210                     and not np.isfinite(converted_limit)):
-> 3211                 raise ValueError("Axis limits cannot be NaN or Inf")
   3212             return converted_limit
   3213 

ValueError: Axis limits cannot be NaN or Inf

I'll try to debug this, could be something simple

if isinstance(benchmark, _pd.Series):

Add benchmark = _utils.group_returns(benchmark, benchmark.index.year, True) after this line works for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants