建造水库是一个高风险的问题。如果计算错误,成千上万的人可能会失去他们的家园。在20世纪中期,英国水文学家埃德温-哈罗德-赫斯特在解决这类问题方面取得了重大突破。他开发了后来被称为Hurst指数的东西,这是一个衡量时间序列中自动相关的指标。虽然它是为了估计河流中的水量而开发,但正如我们所期望的那样,对于涉及时间序列的数学计算,Hurst指数在金融市场研究中得到了有趣的应用。

下面将展示如何计算Hurst指数,并使用它来评估标准普尔500指数、比特币和美元/瑞士法郎交易对的特性,看看我们是否能理解这些金融序列的交易趋势。

什么是Hurst指数?

Hurst指数可以用来确定一个时间序列是否倾向于向单一方向移动(H>0.5),振荡(H<0.5),或随机(H=0.5)。

虽然赫斯特发现这种关系在各种自然现象中很有用,如洪水、河流排放和树木年轮,但我们也可以用它来将一个市场归类为趋势性或均值回归性。如果我们知道一个市场倾向于以某种方式行事,我们可以尝试用适当的均值回归或趋势跟踪策略来捕捉这一点,或者在你的算法交易系统中使用它作为一个过滤器。

如何计算Hurst指数?计算Hurst指数需要估计多个不同时间段的R/S统计量,然后将其与各时间段绘制成对数图,并找出斜率。这条线的斜率就是Hurst指数 —— H。

有多种方法来估计Hurst指数。就我所知,重新标定的范围分析方法是最古老的,但使用去趋势波动分析(DFA)是最常见的。我们将使用后者,因为尽管它听起来很复杂,但它只需要3-4行代码就能运行,而且比我的重标范围分析实现快一个数量级。这两种方法都是可行的,但它们略有不同。

假设我们有一个价格序列,我们称之为x。然后我们可以看一下x在不同时间t的差异,并取其差值。这个时间差将被称为lag(滞后)。我们想得到这些滞后差值的标准差的关系。

我们可以按以下步骤写出我们的计算结果。

1、选择一个滞后期的范围(如2到100)。

2、计算x中所有点的滞后差值。

3、计算每个lag的标准差。

4、将标准差的对数与lag的对数作图,以估计H。

数学上的公式为:

将所有的数据插入最后一个方程,我们可以找到最佳拟合线,我们就得到了H的值。让我们来看看如何用Python来做这件事!

用Python中计算Hurst指数

首先导入几个包:

import numpy as np
import matplotib.pyplot as plt

然后定义我们的 hurst()函数。

def hurst(price, min_lag=2, max_lag=100):lags = np.arange(min_lag, max_lag + 1)tau = [np.std(np.subtract(price[lag:], price[:-lag])) for lag in lags]m = np.polyfit(np.log10(lags), np.log10(tau), 1)return m, lags, tau

我们可以通过使用一个计算所有滞后差值的标准差的列表来理解,将所有的东西整合在几行紧凑的线条中。

接下来,让我们在一些我们知道答案的序列上测试这个函数。这将有助于确保我们的计算是正确的。

N = 10000
rand = np.cumsum(np.random.randn(N) + 0.01)
mr = np.cumsum(np.sin(np.linspace(0, N/3*np.pi, N))/2 + 1)
tr = np.cumsum(np.arange(N)/N)
m_rand, lag_rand, rs_rand = hurst(rand)
m_mr, lag_mr, rs_mr = hurst(mr)
m_tr, lag_tr, rs_tr = hurst(tr)
print(f"Hurst(Random):\t{m_rand[0]:.3f}")
print(f"Hurst(MR):\t{m_mr[0]:.3f}")
print(f"Hurst(TR):\t{m_tr[0]:.3f}")
Hurst(Random):    0.499
Hurst(MR):        0.075
Hurst(TR):        0.997

此外,我们可以将这些系列与我们的lag值和统计数据的对数图一起绘制。

左栏中的图是对数图。你可以看到我们试图在Y轴上拟合标准差统计数字。对于随机和趋势的时间序列,它们匹配得很好。均值回归的是一个快速振荡的正弦波——完全不一致,但斜率仍然是正的,并且小于0.5。在你的生活中,你永远不会看到这样的金融时间序列,但它应该给你信心,我们的函数是有效的!

金融时间序列的Hurst指数

将Hurst应用于金融数据也同样简单明了。我们可以把它应用于一些常见的时间序列,看看我们得到什么。

我们将使用美元/瑞士法郎交易对、BTC和SPY来感受一下这些数据。

用yfinance软件包抓取数据。

import pandas as pd
import yfinance as yf
tickers = ['CHF=X', 'BTC-USD', 'SPY', 'GLD', 'USO']
start = '2010-01-01'
end = '2021-12-31'
yfObj = yf.Tickers(tickers)
df = yfObj.history(start=start, end=end)
df.drop(['Stock Splits', 'Dividends', 'Volume', 'Open', 'High', 'Low'], axis=1, inplace=True)
df.columns = df.columns.swaplevel()

我们在这里只对收盘价感兴趣,所以我们可以放弃所有其他的列,并在这些列上运行swaplevel(),这样我们就可以按股票代码进行索引。

接下来,我们需要通过Hurst()函数运行每个时间序列,以获得指数和相关值。

vals = {c[0]: hurst(df[c].dropna().values) for c in df.columns}

一旦完成,我有一个辅助函数来绘制结果。

def plotHurst(m, x, y, series, name):fig, ax = plt.subplots(1, 2, figsize=(15, 6))ax[0].plot(np.log10(x), m[0] * np.log10(x) + m[1]) ax[0].scatter(np.log10(x), np.log10(y), c=colors[1])ax[0].set_title(f"{name} (H = {m[0]:.3f})")ax[0].set_xlabel(r"log($\tau$)")ax[0].set_ylabel(r"log($\sigma_\tau$)")ax[1].plot(series)ax[1].set_title(f"{name}")ax[1].set_ylabel("Price ($)")ax[1].set_xlabel("Date")return fig, ax

这使得绘制我们的数值变得更加容易。如果我们想绘制所有的数值,我们可以循环浏览我们的vals字典,并调用plt.show(),如下面的代码所示。

for k, v in vals.items():fig, ax = plotHurst(*v, df[k], k)plt.show()

让我们依次看一下结果,看看我们是否能从Hurst指数告诉我们的东西中得到一些启示。

美元/瑞士法郎交易对均值回归

我们将从Hurst指标中看到的最强烈的信号开始,即美元/瑞士法郎交叉。

大多数交易员都有一种直觉,即货币对总体上是均值回归的,而对于强势货币之间的货币对,如美元和瑞士法郎,它尤其明显。

这正是我们在这里看到的情况。

不过,值得注意的是,较短的时间框架与我们在这里看到的较长的时间框架有一定的偏差。在最短的时间范围内,已实现波动率的期限结构(即蓝点所在的位置)低于红线。

出于好奇,我绘制了各种最大lag值的Hurst指数,看看这个系列是否曾经成为一个趋势系列。

并非如此。

它确实越长越平均,表明美元和瑞士法郎之间有一个相当稳定的长期关系。这是每日数据,所以它可以提供一些指导,作为你应该交易的时间框架。考虑到它在60天以上会变得更加均值化,也许在这个时间范围内(或更长)运行的均值化策略将是最有效的。

比特币是一种动量游戏

比特币暴涨暴跌的势头恰恰相反。

Hurst指数给出了一个相当明确的信号:这是一个动量交易,而已实现的波动率期限结构显示出令人惊讶的少数偏差。

但有趣的是,2021年的情况。

在比特币2020年的巨大牛市之后,它在2021年度过了一个随机/平均回归阶段。请注意,这不是那么多的数据,但有趣的是,不知道比特币是否已经进入了一个趋势变化。在2017年的大牛市之后,它在2018-2019年进入了一个类似的趋势,它有两年时间在进行均值回归,直到2020年起飞。

到目前为止,2022年已经显示出类似的模式。它能在今年剩下的时间里持续下去吗?

标准普尔500指数的均值回归

这个对我来说是最大的惊喜。Hurst指数显示,标普500指数是一个平均回归的时间序列。

看看它右边的价格图,它看起来有一个强大的上升趋势。

我们的算法揭示了我们眼睛看不到的东西。

我们可以对标准普尔500指数进行与美元/瑞士法郎汇率相同的分析,看看在不同的滞后期是否有任何拐点或赫斯特指数的变化。

当我们这样做时,我们会得到下面的图表。

在这幅图中,H值随着滞后期的变化而明显变化。在中短期内,该系列是平均回归的,但在较长的时间范围内,它变得有强烈的趋势性。在非常长的时间内(超过400天),它又回到了强烈的均值回归。

让我们看看这在不同的时间范围内是否成立。

我们将回到过去,从1993年开始到2021年,获取SPY的数据。这将产生7,284个交易日。此外,我们将把它分为四个时间段,并在这四个时间段中的每一个时间段运行相同的分析,以查看SPY的行为是否在较小的间隔内发生变化。

这就产生了下面的图表。

这表明,标准普尔500指数在不同的lag(滞后)期会经历更多的趋势和更多的均值回归时期。例如,比较2000-2007年期间。在这里,我们从互联网的繁荣和萧条到全球金融危机的高峰,几乎所有的滞后期都是趋势的。从那时起,在200-300区间内,趋势的持续程度较低,但其他地方的均值回归更为普遍。

值得注意的是,在我们看的每一个时间框架内,该系列似乎都在200-300天范围内有趋势。这似乎表明,标普500指数在这些时间范围内表现出强烈的趋势行为,可以通过趋势跟踪模型加以利用,而均值回归模型在较短的时间范围内会更有价值。

这种对200-300天范围内趋势的观察似乎与著名的海龟交易员杰里-帕克的轶事观察相吻合,即现代趋势跟踪在这些200天以上的时间范围内效果最好。

总结

一个市场是倾向于趋势、均值回归,还是随机的,这对交易者来说是有价值的信息。虽然赫斯特指数本身并不是一个入场信号,但它可以作为一个系统的过滤器。考虑到市场制度可能会随着时间的推移而发生变化,有利于一种或另一种方法,用Hurst过滤器覆盖你的模型,可以帮助防止你的算法在均值回归的市场中买入突破,或在市场走向新高时在回撤之前做空。

从本质上讲,它可以帮助你的算法与它所交易的市场相匹配。当然,这需要大量的回测。

用 Python 计算 Hurst 指数并预测市场趋势相关推荐

  1. Python的Mann-Kendall非参数检验和计算Hurst指数

    Mann-Kendall 检验法简称为 M-K 法, 是一种非参数统计检验方法, 可适用于不具有正态分布特征变量的趋势分析[38].假定X1,X2,...Xn为时间序列变量[1],n为时间序列的长度, ...

  2. 获取铁矿石和螺纹钢期货数据。对收益率序列进行描述性统计、jb检验,反正是否符合分形市场假说。计算Hurst指数,制定跨品种套利策略,并进行回测,对跨品种套利效果进行评估。寻求改进空间。

    源码已上传至github 项目简介 获取铁矿石和螺纹钢期货数据.对收益率序列进行描述性统计.jb检验,反正是否符合分形市场假说.计算Hurst指数,制定跨品种套利策略,并进行回测,对跨品种套利效果进行 ...

  3. 使用matlab计算hurst指数的代码

    您可以使用以下代码来计算Hurst指数: % 加载数据 data = load('your_data.txt');% 计算数据的长度 N = length(data);% 初始化矩阵 rs = zer ...

  4. Python 计算EMA(指数移动平均线)

    总结 使用递归和循环两种方法来完成 python环境下循环相比于递归更快,更适应极端样本情况 递归 def _ema(arr,i=None):N = len(arr) α = 2/(N+1) #平滑指 ...

  5. 时间序列中Hurst指数的计算(python代码)

    在做时间序列分析时,需要计算Hurst指数,由于Hurst指数计算比较复杂,刚开始懒得自己写,就在github上进行搜索,多是这个代码: from numpy import std, subtract ...

  6. Hurst指数以及MF-DFA

    转:https://uqer.io/home/ https://uqer.io/community/share/564c3bc2f9f06c4446b48393 写在前面 9月的时候说想把arch包加 ...

  7. dfa matlab用法,关于使用MF-DFA方法计算广义Hurst指数的MATLAB操作问题

    我在论坛上复制了一个代码,是使用MF-DFA方法计算广义Hurst指数的,但不知道需填入的各个变量的名称,我是零基础,但任务时间很紧,来不及现学,所以想先用来算个数,请各位高手指教,不胜感激! 请问括 ...

  8. R语言 Hurst指数计算

    GPS filenum=c(11:15,19:24) roads=c("鞍山西道","白堤路","保山道","复康路", ...

  9. 用Python计算点估计预测评价指标(误差指标RMSE、MSE、MAE、MAPE) ,画图展示

    机器学习的回归问题常用RMSE,MSE, MAE,MAPE等评价指标,还有拟合优度R2.由于每次预测出来的预测值再去和原始数据进行误差评价指标的计算很麻烦,所以这里就直接给出他们五个指标的计算函数.把 ...

  10. 使用python根据身高体重计算BMI指数

    #python(day01) 根据身高.体重计算BMI指数 创建两个变量:一个用于计算身高(单位:米),一个用来记录体重(单位:千克),根据公式"BMI=体重/(身高*身高)",代 ...

最新文章

  1. Java项目:医院管理系统(java+javaweb+jdbc+Mysql+lw)
  2. uc/os中对任务的总体理解
  3. buuoj-crypto 2
  4. P1080 国王游戏(贪心)
  5. 01-JVM与Java体系结构
  6. 微软面向初学者的机器学习课程:1.2-机器学习的历史
  7. 数据增长浪潮下,PCIe 6.0的问与Rambus的答
  8. C#方法的参数 Ref Out Params 4种类型的参数
  9. 从零开始学前端:if判断,for循环,,switch判断 --- 今天你学习了吗?(JS:Day4)
  10. c语言用梯形法计算积分,c语言用梯形法求积分
  11. Oracle学习总结(6)—— SQL注入技术
  12. Web移动开发基本概念
  13. 【Tools】TCP/IP 测试工具——SocketTools
  14. Tomcat8卸载+重装
  15. C# 解析JSON方法总结
  16. 计算机教师继续教育心得,教师继续教育个人总结(通用5篇)
  17. ADS2015导入飞思卡尔元器件模型 安装DesignKit
  18. whois信息收集企业备案信息
  19. 什么是Xcelsius
  20. 为什么128KB的魂斗罗可以实现那么长的剧情?

热门文章

  1. imitate wechat - 4
  2. python --爬虫 --下载小说
  3. 作业四:结对编程项目--四则运算
  4. MySQL 复制表结构、数据
  5. govendor使用笔记
  6. 运营15年的飞扬军事论坛宣布停止运营 关闭服务器
  7. 51单片机学习笔记——OLED贪吃蛇
  8. 2022年“研究生科研素养提升”系列公益讲座在线测评
  9. linux改文件夹e45,linux 编辑文件时 E45: 'readonly' option is set (add ! to override) 隐藏属性 chattr lsattr...
  10. php5 ereg,ereg / eregi替代PHP 5.3