vendredi 2 juillet 2021

Problem in computing Hurst Exponent in Python

This is my first post here, so I hope I am writing everything in the right way. I wanted to implement an algorithm to perform the Rescal Range Analysis to computer the Hurst Exponent.

The problem is that I do not have a nice line in the log-log plot and thus the Hurst exponent of my random walk process does not happen to be 0.5 as it should be. I suppose that the problem lies in the RescaledRangeAnalysis(x) function that I wrote, but I am not able to find where the algorithm is wrong as I followed the steps posted on wikipedia. Can you help me find the problem?


CODE BELOW:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression

Rescale Range

I then proceeded to implement the algorithm as listed here on wikipedia: https://en.wikipedia.org/wiki/Rescaled_range

def RescaledRangeAnalysis(x):
    xm = np.mean(x)
    y = x - xm
    z = np.cumsum(y)
    
    R = np.empty(len(z))
    for t in range(len(z)):
        R[t] = max(z[:t+1]) - min(z[:t+1])
       
    S = np.empty(len(z))
    for t in range(len(z)):
        S[t] = np.std(z[:t+1])
        
    #I have to avoid returning the 0th element because the std of a single term is 0 => avoid division by 0
    return R[1:]/S[1:] 

Random Walk

As a random walk should have a Hurst exponent of 0.5 I tried with this code snipped I found here to generate a random walk process: https://towardsdatascience.com/random-walks-with-python-8420981bc4bc

# Define parameters for the walk
dims = 1
step_n = 10000
step_set = [-1, 0, 1]
origin = np.zeros((1,dims))

# Simulate steps in 1D
step_shape = (step_n,dims)
steps = np.random.choice(a=step_set, size=step_shape)
path = np.concatenate([origin, steps]).cumsum(0)
start = path[:1]
stop = path[-1:]

# Plot the path
fig = plt.figure(figsize=(10,5))
ax = fig.add_subplot(111)
ax.scatter(np.arange(step_n+1), path, c="blue",alpha=0.25,s=0.05);
ax.plot(path,c="blue",alpha=0.5,lw=1,ls='-',);
ax.plot(0, start, c="red", marker="+")
ax.plot(step_n, stop, c="black", marker="o")
plt.grid()
plt.title("1D Random Walk")
plt.tight_layout(pad=0)


#path is my vector containing random walk data

Computation of R/S

R_over_S = RescaledRangeAnalysis(path) #Outout of the above algorithm

t = np.array(range(len(R_over_S))) + 1 #Number of samples used to perform the algorithm
reg = LinearRegression().fit(np.log10(t).reshape(-1, 1), np.log10(R_over_S))

hurst = reg.coef_[0]
intercept = reg.intercept_

x = np.linspace(0, int(max(np.log10(t))), 1000)
y = hurst*x + intercept

plt.figure(figsize=(10,5))
plt.plot(np.log10(t), np.log10(R_over_S))
plt.plot(x, y)
plt.xlabel("logt")
plt.ylabel("logR/S")
plt.show()



Aucun commentaire:

Enregistrer un commentaire