python中的Hurst指数

时间:2016-09-14 11:01:59

标签: python math finance

from datetime import datetime
from pandas.io.data import DataReader
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"""
    # Create the range of lag values
    lags = range(2, 100)

    # Calculate the array of the variances of the lagged differences
    # Here it calculates the variances, but why it uses 
    # standard deviation and then make a root of it?
    tau = [sqrt(std(subtract(ts[lag:], ts[:-lag]))) for lag in lags]

    # Use a linear fit to estimate the Hurst Exponent
    poly = polyfit(log(lags), log(tau), 1)

    # Return the Hurst exponent from the polyfit output
    return poly[0]*2.0


# Download the stock prices series from Yahoo
aapl = DataReader("AAPL", "yahoo", datetime(2012,1,1), datetime(2015,9,18))

# Call the function
hurst(aapl['Adj Close'])

从这个用于估算Hurst指数的代码中,当我们想要计算滞后差的方差时,为什么我们仍然使用标准差并取平方根?我困惑了很长时间,我不知道为什么其他人不会有同样的混淆。我误解了背后的数学吗?谢谢!

4 个答案:

答案 0 :(得分:7)

我也很困惑。我不明白std的sqrt来自哪里,并花了3天时间试图找出它。最后,我注意到QuantStart将Tom Starke博士归功于使用略有不同的代码。 Tom Starke博士将Ernie Chan博士归功于his blog。我能够找到足够的信息来汇总我自己的原则代码。这不使用sqrt,使用variance而不是std,并在末尾使用2.0除数而不是2.0乘数。最后,它似乎给出了与你发布的quantstart代码相同的结果,但我能够从第一原理中理解它,我认为这很重要。我把一个更加清晰的Jupyter笔记本放在一起,但我不确定我是否可以在这里发布,所以我会尽力在这里解释一下。首先粘贴代码,然后解释。

lags = range(2,100)
def hurst_ernie_chan(p):

    variancetau = []; tau = []

    for lag in lags: 

        #  Write the different lags into a vector to compute a set of tau or lags
        tau.append(lag)

        # Compute the log returns on all days, then compute the variance on the difference in log returns
        # call this pp or the price difference
        pp = subtract(p[lag:], p[:-lag])
        variancetau.append(var(pp))

    # we now have a set of tau or lags and a corresponding set of variances.
    #print tau
    #print variancetau

    # plot the log of those variance against the log of tau and get the slope
    m = polyfit(log10(tau),log10(variancetau),1)

    hurst = m[0] / 2

    return hurst
陈博士没有在这个页面上给出任何代码(我相信他的工作在MATLAB而不是Python)。因此,我需要将他自己的代码放在他在博客中提供的笔记中,并将答案提供给他在博客上提出的问题。

  1. 陈博士指出,如果z是对数价格,那么以τ的间隔采样的波动率是波动率(τ)=√(Var(z(t)-z(t-τ)))。对我来说另一种描述波动率的方法是标准差,所以std(τ)=√(Var(z(t)-z(t-τ)))

  2. std只是方差的根,所以var(τ)=(Var(z(t)-z(t-τ)))

  3. 陈博士然后说:一般来说,我们可以写Var(τ)ατ^(2H)其中H是赫斯特指数

  4. 因此(Var(z(t)-z(t-τ)))ατ^(2H)

  5. 取每边的对数得到log(Var(z(t)-z(t-τ)))α2Hlogτ

  6. [log(Var(z(t)-z(t-τ)))/logτ] /2αH(给出赫斯特指数)我们知道最左边的方括号中的项是tau的对数 - 对数图的斜率和一组相应的方差。

  7. 如果您运行该功能并比较Quantstart功能的答案,它们应该是相同的。不确定这是否有帮助。

答案 1 :(得分:3)

这里发生的一切都是数学符号的变化

我将定义

d = subtract(ts[lag:], ts[:-lag])

然后很明显

np.log(np.std(d)**2) == np.log(np.var(d))
np.log(np.std(d)) == .5*np.log(np.var(d))

然后你有等价

2*np.log(np.sqrt(np.std(d))) == .5*np.log(np.sqrt(np.var(d)))

polyfit的功能输出与其输入按比例缩放

答案 2 :(得分:1)

根据 Ernest Chan 的“算法交易”(第 44 页)中的直观定义:

<块引用>

直观地说,“平稳”的价格序列意味着价格扩散 比几何随机游走慢。

人们想要检查时间序列的方差,随着滞后的增加对滞后。这是因为对于正态分布 - 并且日志价格被认为是正常的(在某种程度上) - 正态分布总和的方差是成分方差的总和。根据 Ernest Chan 的引用,对于均值恢复过程,实现的方差将小于理论预测。

将其放入代码中:

def hurst(p, l):
    """
    Arguments:
        p: ndarray -- the price series to be tested
        l: list of integers or an integer -- lag(s) to test for mean reversion
    Returns:
        Hurst exponent
    """
    if isinstance(l, int):
        lags = [1, l]
    else:
        lags = l
    assert lags[-1] >=2, "Lag in prices must be greater or equal 2"
    print(f"Price lags of {lags[1:]} are included")
    lp = np.log(p)
    var = [np.var(lp[l:] - lp[:-l]) for l in lags]
    hr = linregress(np.log(lags), np.log(var))[0] / 2
    return hr

答案 3 :(得分:0)

OP发布的代码是正确的。

混淆的原因是它首先执行平方根,然后通过将斜率(由polyfit返回)乘以2来对抗它。

有关更详细的说明,请继续阅读。

tau用“额外”平方根计算。然后,计算其日志。 log(sqrt(x))= log(x ^ 0.5)= 0.5 * log(x)(这是密钥)。 polyfit现在用y乘以“额外0.5”来进行拟合。因此,获得的结果也乘以接近0.5。返回两次(返回poly [0] * 2.0)对应初始(看似)额外的0.5。

希望这更清楚。