pmorissette / ffn

ffn - a financial function library for Python
pmorissette.github.io/ffn
MIT License
1.97k stars 294 forks source link

"ZeroDivisionError: float division by zero" when calculating PerformanceStats.yearly_sharpe if all values in timeseries are same #14

Closed spencerns closed 6 years ago

spencerns commented 7 years ago

Hey there!

In the following lines:

self.yearly_vol = yr.std() self.yearly_sharpe = ((self.yearly_mean - self._yearly_rf) / self.yearly_vol)

self.yearly_vol is type 'float' instead of type 'numpy.float64' like self.monthly_vol and self.daily_vol so when you try to calculate self.yearly_sharpe you get a division by zero error.

I managed a workaround by calculating the yearly volatility like:

self.yearly_vol = yr.std() / np.sqrt(1)

similar to how you calculated the daily and monthly volatility

best, Spencer

xgdgsc commented 6 years ago

Also when max_drawdown is zero I get /site-packages/ffn/core.py:209: RuntimeWarning: divide by zero encountered in double_scalars self.calmar = self.cagr / abs(self.max_drawdown). And then the display() function would issue:

---------------------------------------------------------------------------
RecursionError                            Traceback (most recent call last)
<ipython-input-124-bbf8aa440547> in <module>()
----> 1 stats.display()

~/anaconda3/lib/python3.6/site-packages/ffn/core.py in display(self)
    789             row = [n]
    790             for key in self._names:
--> 791                 raw = getattr(self[key], k)
    792                 if f is None:
    793                     row.append(raw)

~/anaconda3/lib/python3.6/site-packages/ffn/core.py in __getitem__(self, key)
    648     def __getitem__(self, key):
    649         if type(key) == int:
--> 650             return self[self._names[key]]
    651         else:
    652             return self.get(key)

... last 1 frames repeated, from the frame below ...

~/anaconda3/lib/python3.6/site-packages/ffn/core.py in __getitem__(self, key)
    648     def __getitem__(self, key):
    649         if type(key) == int:
--> 650             return self[self._names[key]]
    651         else:
    652             return self.get(key)

RecursionError: maximum recursion depth exceeded while calling a Python object
JordanPlatts commented 6 years ago

This should be fixed now.