Lumiwealth / quantstats_lumi

Apache License 2.0
83 stars 27 forks source link

TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe'' #38

Closed Thomas4390 closed 4 months ago

Thomas4390 commented 4 months ago

Hello,

When I try to use the reports.html function in quantstats, I get a surprising error that never happened before:

File src/main.py", line 264, in analyze_strategy_returns strategy_performance_analyzer.generate_backtesting_report_html( File src/strategy_performance_analysis/strategy_performance_analyzer.py", line 150, in generate_backtesting_report_html qs.reports.html( File quantstats_lumi/reports.py", line 174, in html mtrx = metrics( ^^^^^^^^ File quantstats_lumi/reports.py", line 913, in metrics metrics["Time in Market % "] = _stats.exposure(df, prepare_returns=False) pct ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File quantstats_lumi/stats.py", line 174, in exposure _df[col] = _exposure(returns[col]) ^^^^^^^^^^^^^^^^^^^^^^^ File quantstats_lumi/stats.py", line 168, in _exposure ex = len(ret[(~_np.isnan(ret)) & (ret != 0)]) / len(ret) ^^^^^^^^^^^^^^ File pandas/core/generic.py", line 2171, in __array_ufunc__ return arraylike.array_ufunc(self, ufunc, method, inputs, *kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File pandas/core/arraylike.py", line 399, in array_ufunc result = getattr(ufunc, method)(inputs, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

I had the reflex to check but two series of data (portfolio returns as well as benchark returns) but neither series show any anomalies (no NaN values).

What I understand is that the np.isnan function in pandas can't handle the arrays provided by quantstats. Others functions with np.isnan in it are also concerned. It's strange because I didn't have this error before.

I can provide more information if needed to make debugging easier.

Thanks for your precious help.

Thomas4390 commented 4 months ago

More info on ret (alias benchmark_returns) in the _exposure function (stats.py module of quantstats-lumi): <class 'pandas.core.series.Series'> DatetimeIndex: 5795 entries, 2001-02-02 to 2024-02-29 Series name: returns Non-Null Count Dtype


5795 non-null object dtypes: object(1) memory usage: 219.6+ KB

I notice that the dtype is object. I would have expected float64 instead, is this normal? However, benchmark_returns is of type float64 before being given as input to reports.html...

PS: np.isnan is working with a pandas series float64 but not with object dtype. An unnecessary conversion from float64 to object in my pandas series seems to take place in quanstats but I can't figure out why. Any help would be appreciated.

Thomas4390 commented 4 months ago

I finally found the solution. The problem was not my series of benchmark_returns but my series of portfolio returns, which was dtype object. All I had to do was convert the series to float64 numeric to solve the problem.