Python Forum
Hurst Exponent in Rolling Basis - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: Data Science (https://python-forum.io/forum-44.html)
+--- Thread: Hurst Exponent in Rolling Basis (/thread-31829.html)



Hurst Exponent in Rolling Basis - illmattic - Jan-05-2021

Hello,

I have come across code (https://github.com/Mottl/hurst/blob/master/hurst/__init__.py) that calculates the Hurst exponent from a time series. I have simplified it for my purpose:
def custom_hurst(series):
    series = series.tail(365)
    max_window = len(series)
    min_window = 15
    
    ndarray_likes = [np.ndarray]
    if "pandas.core.series" in sys.modules.keys():
        ndarray_likes.append(pd.core.series.Series)
    
        # convert series to numpy array if series is not numpy array or pandas Series
    if type(series) not in ndarray_likes:
        series = np.array(series)
    
    if "pandas.core.series" in sys.modules.keys() and type(series) == pd.core.series.Series:
            if series.isnull().values.any():
                raise ValueError("Series contains NaNs")
            series = series.values  # convert pandas Series to numpy array
    elif np.isnan(np.min(series)):
            raise ValueError("Series contains NaNs")
    
    def to_inc(x):
        incs = x[1:] - x[:-1]
        return incs
    
    def to_pct(x):
        pcts = x[1:] / x[:-1] - 1.
        return pcts
    
    def RS_func(series):
        incs = to_pct(series)
        mean_inc = np.sum(incs) / len(incs)
        deviations = incs - mean_inc
        Z = np.cumsum(deviations)
        R = max(Z) - min(Z)
        S = np.std(incs, ddof=1)
        return R / S
    
    
    err = np.geterr()
    np.seterr(all='raise')
    
    max_window = max_window or len(series)-1
    window_sizes = [15,30,45,90,182,365]
    
    RS = []
    
    for w in window_sizes:
            rs = []
            for start in range(0, len(series), w):
                if (start+w)>len(series):
                    break
                _ = RS_func(series[start:start+w])
                if _ != 0:
                    rs.append(_)
            RS.append(np.mean(rs))
    
    A = np.vstack([np.log10(window_sizes), np.ones(len(RS))]).T
    H, c = np.linalg.lstsq(A, np.log10(RS), rcond=-1)[0]
    np.seterr(**err)
    
    c = 10**c

    return H
Not being proficient in python, I am struggling to workout a way to have this code applied on a rolling basis to calculate a Hurst value for each previous 365 values in the time series instead of just one Hurst value for the last 365 values.

Any help would be appreciated.
Thanks
Matt


RE: Hurst Exponent in Rolling Basis - illmattic - Jan-06-2021

I've tried using the function like this:

df.apply(lambda row: custom_hurst(df), axis=1)
Output:
1983-03-30 0.682463 1983-03-31 0.682463 1983-04-04 0.682463 1983-04-05 0.682463 1983-04-06 0.682463 2020-12-29 0.682463 2020-12-30 0.682463 2020-12-31 0.682463 2021-01-04 0.682463 2021-01-05 0.682463
but as you see, the function is inputting the same 365 rows of the df. How would I adjust the code so that it rolls with the dates instead of being static?