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
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()