ranaroussi / quantstats

Portfolio analytics for quants, written in Python
Apache License 2.0
4.82k stars 841 forks source link

qs.reports.metrics() and qs.reports.full() give different results using same data #314

Open BlackArbsCEO opened 10 months ago

BlackArbsCEO commented 10 months ago

So far I found cumulative returns, time in market, average drawdown and average drawdown days to be different but there could be others. You can reproduce this issue with the following code:

version: quantstats                0.0.62 

np.random.seed(0)
ts = pd.Series(np.random.randint(1, high=4, size=12), index=pd.date_range(start='2021-05-01', periods=12))

qs.reports.full(ts, compounded=True)
                           Strategy
-------------------------  -----------------
Start Period               2021-05-01
End Period                 2021-05-12
Risk-Free Rate             0.0%
Time in Market             67.0%

Cumulative Return          200.0%
CAGR﹪                     8519501800313.54%

Sharpe                     6.62
Prob. Sharpe Ratio         95.99%
Smart Sharpe               3.4

qs.reports.metrics(ts, compounded=True)
                    Strategy
------------------  -----------------
Start Period        2021-05-01
End Period          2021-05-12
Risk-Free Rate      0.0%
Time in Market      100.0%

Cumulative Return   11,059,100.00%
CAGR﹪              8519501800313.54%

Sharpe              6.62
Prob. Sharpe Ratio  95.59%
Sortino             20.04
timnilson commented 9 months ago

The below is probably a different issues if your values are totally different, but here goes...

I have been finding that the call to:

metrics = qs.reports.metrics(returns, display=False, sep=False, mode="full")

Gives you values that are rounded. Max Drawdown for example comes back as -0.08 if the drawdown was -8.38% for example. I have been unable to find any option that would change the output values so they are not rounded. What you can do is can pass internal=True like:

metrics = qs.reports.metrics(returns, display=False, sep=False, mode="full", internal=True)

But, this will return strings of numbers used in the HTML report. So, for Max Drawdown for example you would get back "-8.3%", which is better than -0.08. But since this is a string, also not exactly what you want.

You could use the qs.stats method to return un-rounded values, but that is less elegant as you need to know all the key names for each stat. For instance, you could call:

mdd = qs.stats.max_drawdown()

This will get you the full value, which you can then round / multiply how you want. I was hoping I could get the the qs.metrics method to return all the un-rounded values.

grzesir commented 2 months ago

Check out https://github.com/Lumiwealth/quantstats_lumi, which is being updated regularly. We are a fork of this library that is being maintained by Lumiwealth