Hurst 指数 - 使用 DFA(而不是 R/S) - 平滑的 Hurst 指数值相同且绘图不正确

问题描述 投票:0回答:0

我正在编写一个脚本,使用 Python 计算和绘制股票历史价格数据的赫斯特指数和平滑赫斯特指数。当我运行脚本时,我面临两个主要问题:

Smoothed Hurst Exponent 和 Hurst Exponent 值相同。我希望平滑的 Hurst 指数与 Hurst 指数不同,因为它应该是 Hurst 指数的移动平均值。

绘图似乎没有正确完成。我正在尝试绘制 Hurst 指数、平滑的 Hurst 指数和置信区间,但生成的图未按预期显示数据。

我正在寻求帮助,以确定我的代码中导致这些问题的问题以及如何解决这些问题的建议。

Example Output

任何帮助将不胜感激

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import yfinance as yf
from scipy.stats import linregress

# (a) - inputs
def inputs(barsize=100, slen=18, Min=8, Max=2):
    return barsize, slen, Min, Max

# (b) - Declaration
Min = 8
Max = 2
fluc = np.full(10, np.nan)
scale = np.full(10, np.nan)
slope = np.nan

# (c) - SS function
def ss(series, period):
    PI = 2.0 * np.arcsin(1.0)
    SQRT2 = np.sqrt(2.0)
    _lambda = PI * SQRT2 / period
    a1 = np.exp(-_lambda)
    coeff2 = 2.0 * a1 * np.cos(_lambda)
    coeff3 = - np.power(a1, 2.0)
    coeff1 = 1.0 - coeff2 - coeff3
    filt1 = np.zeros_like(series)
    
    for i in range(2, len(series)):
        filt1[i] = coeff1 * (series[i] + (series[i - 1] if i - 1 >= 0 else 0)) * 0.5 + coeff2 * filt1[i - 1] + coeff3 * filt1[i - 2]

    return filt1

# (d) - Calculations
def RMS(N1, N, csum):
    seq = np.arange(1, N + 1)
    y = csum[N1 : N1 + N]
    sdx = np.std(seq) * np.sqrt(N / (N - 1))
    sdy = np.std(y) * np.sqrt(N / (N - 1))
    cov = np.cov(seq, y, bias=True)[0, 1] * (N / (N - 1))
    r2 = np.power(cov / (sdx * sdy), 2)
    rms = np.sqrt(1 - r2) * sdy
    return rms

def Arms(bar, csum, barsize):
    num = np.floor(barsize / bar).astype(int)
    sumr = sum(RMS(i * bar, bar, csum) for i in range(num))
    avg = np.log10(sumr / num)
    return avg

def fs(x, barsize, Min, Max):
    return np.round(Min * np.power(np.power(barsize / (Max * Min), 0.1111111111), x)).astype(int)

def hurst_exponent(close, barsize=100, slen=18, Min=8, Max=2):
    # Calculate Log Return
    r = np.log(close / np.roll(close, 1))
    # Mean of Log Return
    mean = np.convolve(r, np.ones(barsize) / barsize, mode="valid")
    mean = np.pad(mean, (barsize - 1, 0), 'constant', constant_values=0)

    # Calculate Cumulative Sum
    csum = np.cumsum(r - mean)

    # Set Ten Points of Root Mean Square Average along the Y log axis
    fluc = np.array([Arms(fs(i, barsize, Min, Max), csum, barsize) for i in range(10)])

    # Set Ten Points of data scale along the X log axis
    scale = np.array([np.log10(fs(i, barsize, Min, Max)) for i in range(10)])

        # Calculate Slope Measured From RMS and Scale on Log log plot using linear regression
    slopes = np.array([np.cov(scale, fluc, bias=True)[0, 1] / np.var(scale, ddof=0) for i in range(len(close) - barsize + 1)])

    # Calculate Moving Average Smoothed Hurst Exponent
    smooth = ss(slopes, slen)

    # Calculate Critical Value based on Confidence Interval (95% Confidence)
    ci = 1.645 * (0.3912 / np.power(barsize, 0.3))
    # Calculate Expected Value plus Critical Value
    cu = 0.5 + ci
    cd = 0.5 - ci

    return slopes, smooth, cu, cd

# (e) - Plots
def plot_hurst_exponent(close, barsize=100, slen=18, Min=8, Max=2):
    slopes, smooth, cu, cd = hurst_exponent(close, barsize, slen, Min, Max)

    # Color of HE
    c = "green" if slopes[-1] > cu else "blue" if slopes[-1] >= 0.5 else "red" if slopes[-1] < cd else "orange" if slopes[-1] < 0.5 else "black"

    # Text of Table
    text = "Significant Trend" if slopes[-1] > cu else "Trend" if slopes[-1] >= 0.5 else "Significant Mean Reversion" if slopes[-1] < cd else "Mean Reversion" if slopes[-1] < 0.5 else "N/A"

    # Plotting
    fig, ax = plt.subplots()

    # Hurst Exponent
    ax.plot(slope, label="Hurst Exponent", color=c, linewidth=2)

    # Confidence Interval
    ax.axhline(cu, label="Confidence Interval", color="purple", linestyle="--")
    ax.axhline(cd, label="Confidence Interval", color="purple", linestyle="--")

    # Moving Average
    ax.plot(smooth, label="MA", color="gray", linewidth=1)

    # 0.5 Mid Level
    ax.axhline(0.5, color="black", linestyle="dashed")

    # Display legend and text
    ax.legend()
    plt.title(f"Hurst Exponent: {slopes[-1]:.3f} ({text})") 
    
    print(f"Hurst Exponent: {slopes[-1]:.3f}")
    print(f"Smoothed Hurst Exponent: {smooth[-1]:.3f}")
    
    plt.show()

# Example usage
import yfinance as yf

# Fetch historical stock data for Apple Inc. (AAPL)
ticker = "AAPL"
data = yf.download(ticker, start="2020-01-01", end="2021-01-01")

# Use the 'Close' column for Hurst Exponent calculation
close_prices = data['Close'].values

plot_hurst_exponent(close_prices)```


I tried converting the Pine Script from the TradingView link (https://www.tradingview.com/script/vTloluai-Hurst-Exponent-Detrended-Fluctuation-Analysis-pig/) to Python, aiming to achieve an identical plotting of the Hurst Exponent and Smoothed Hurst Exponent.

I expected my Python script to calculate and plot the Hurst Exponent and Smoothed Hurst Exponent in a similar manner to the TradingView script. However, the calculated Hurst Exponent and Smoothed Hurst Exponent values in my Python script are the same, which is not the expected result. Additionally, the plot generated by my script is not correct, as it does not resemble the one shown in the TradingView link.

I need assistance in identifying the issues in my code and achieving the correct calculations and plot to match the Pine Script's output.
python math statistics probability quantitative-finance
© www.soinside.com 2019 - 2024. All rights reserved.