Search code examples
pythonfinancequantitative-finance

Hurst Exponent turns nan - Python 3


I'm wanting to determine whether a time series is mean-reverting or not, but I'm running into some issues when calculating the Hurst exponent. It's supposed to print 0.5-ish, but instead I get a "nan". All help would be appreciated.

I get the following error/warning:

RuntimeWarning: divide by zero encountered in log
  poly = polyfit(log(lags), log(tau), 1)

Below is the code I'm working on.

import statsmodels.tsa.stattools as ts
from datetime import datetime

from pandas_datareader import DataReader
security = DataReader("GOOG", "yahoo", datetime(2000,1,1), datetime(2013,1,1))
ts.adfuller(security['Adj Close'], 1)



from numpy import cumsum, log, polyfit, sqrt, std, subtract
from numpy.random import randn

def hurst(ts):
    """Returns the Hurst Exponent of the time series vector ts"""

    lags = range(2, 100)

    tau = [sqrt(std(subtract(ts[lag:], ts[:-lag]))) for lag in lags]

    poly = polyfit(log(lags), log(tau), 1)


    return poly[0]*2.0


gbm = log(cumsum(randn(100000))+1000)
mr = log(randn(100000)+1000)
tr = log(cumsum(randn(100000)+1)+1000)

print ("Hurst(GBM):   %s" % hurst(gbm))
print ("Hurst(MR):    %s" % hurst(mr))
print ("Hurst(TR):    %s" % hurst(tr))
print ("Hurst(SECURITY):  %s" % hurst(security['Adj Close']))



print ("Hurst(GBM):   %s" % hurst(gbm))
print ("Hurst(MR):    %s" % hurst(mr))
print ("Hurst(TR):    %s" % hurst(tr))
print ("Hurst(SECURITY):  %s" % hurst(security['Adj Close']))
Hurst(GBM):   0.5039604262314196
Hurst(MR):    -2.3832407841923795e-05
Hurst(TR):    0.962521148986032
Hurst(SECURITY):  nan
__main__:11: RuntimeWarning: divide by zero encountered in log

Solution

  • I had the same problem when sending Series as the ts argument. All you have to do is send a List not a Series or:

    def hurst(ts):
        """Returns the Hurst Exponent of the time series vector ts"""
        ts = ts if not isinstance(ts, pd.Series) else ts.to_list()
        lags = range(2, 100)
        tau = [sqrt(std(subtract(ts[lag:], ts[:-lag]))) for lag in lags]
        poly = polyfit(log(lags), log(tau), 1)
        return poly[0]*2.0
    

    NaN values might be an issue as well, I would check if is ok to dropna() before to_list()