Python Forum

Full Version: Hurst Exponent in Rolling Basis
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hello,

I have come across code (https://github.com/Mottl/hurst/blob/mast..._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
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?