Python金融编程:移动平均 Hurst指数计算(摘抄)

郑志勇 ArisZheng

文本是使用Python实现Hurst指数计算,作者王玮珩,从事股票策略研发兼回测系统开发;

Hurst指数是分形技术在金融量化分析中的典型应用。分形是以非整数维形式充填空间的形态特征分形可以说是来自于一种思维上的理论存在1973年,曼德勃罗(B.B.Man-

delbrot) 在法兰西学院讲课时,首次提出了分维和分形几何的设想。分形(Fractal)一词,是曼 德勃罗创造出来的,其原意具有不规则、支离破碎等意义,分形几何学是一门以非规则几何形态为研究对象的几何学。由于不规则现象在自然界是普遍存在的,因此分形几何又称为描述 大自然的几何学。分形几何建立以后,很快就引起了许多学科的关注,这是由于它不仅在理论 上,而且在实用上都具有重要价值。

一、Hurst指数简介

基于重标极差(R/S)分析方法基础上的 Hurst(赫斯特)指数(H)研究是由英国水文专家 H.E.Hurst(1900—1978)在研究尼罗河水库水流量和贮存能力的关系时,发现用有偏的随机 游走(分形布朗运动)能够更好地描述水库的长期贮存能力,并在此基础上提出了用重标极差 (R/S)分析方法来建立 Hurst指数,作为判断时间序列数据遵从随机游走还是有偏的随机游 走过程的指标。

Hurst指数有三种形式:

① 如果 H=0.5,表明时间序列可以用随机游走来描述;

② 如果0.5

③ 如果0≤H<0.5,表明粉红噪声(反持续性),即均值回复过程。< span="">

也就是说,只要 H ≠0.5,就可以用有偏的布朗运动(分形布朗运动)来描述该时间序列

数据。

Mandelbrot在1972年首次将 R/S分析应用于美国证券市场,分析股票收益的变化,Pe-ters把这种方法作为其分形市场假说最重要的研究工具进行了详细的讨论和发展,并做了很

多实证研究。经典的金融理论一般认为股票市场是有效的,已有的信息已经充分在股价上得到了反映,无法帮助预测未来走势,下一时刻的变动独立于历史价格变动。因此股市变化没有 记忆。实际上中国股市并非完全有效,在一定程度上表现出长期记忆性(LongTermMemo-

ry)。中国股市的牛熊交替(2001—2017),伴随着对股市趋势的记忆的加强和减弱的轮换,分 形理论中的重标极差法导出的 Hurst指数可以反映股市的长期记忆性的强弱。用移动时间 区间的 Hurst指数来对照股指的变化,可以分析Hurst指数的高低与市场指数走势的关系。

赫斯特指数预测股票市值走势的三种形式:

① 如果 H=0.5,表明时间序列可以用随机游走来描述。股市未来方向(上涨或者下跌)

无法确定,市场处于震荡行情中。

有方向,若时间周期序列长度为120,当最近半年市场上涨(横盘、下跌),则市场很可能将继续 上涨(横盘、下跌),H 值越大市场保持原有趋势的惯性越大。

③ 如果0≤H<0.5,表明粉红噪声(反持续性),即均值回复过程。股市将改变原有方向, 若时间周期序列长度为120,当最近半年市场上涨(横盘、下跌),则市场很可能将继续下跌或="" 者横盘(上涨或下跌、横盘或上涨),h值越小市场改变原有趋势的可能性越大。<="" span="">

中国的证券市场随着金融产品丰富、监管效率的提高,未来的中国证券市场的有效性将越 来越高。

二、R/S方法计算 Hurst指数

具体参见《金融数量分析基于Matlab编程》第16章

三、 移动平均 Hurst指数计算程序

(1)时间序列分段

子区间长度n 是可变的,如果回归分析需要将时间序列进行分段,例如若时间序列长度为

240,则其可以分解成4段长度为60的等长子区间,或者6段长度为40的等长子区间……

时间序列分段函数(除因子2外,例如240分为2与120或者120与2,因数据段数太少或

者子区间长度太短将影响回归效果)语法如下:

FactorMatrix,FactorNum = HurstFactorization(x)

x:时间序列长度。

输出参数:

FactorMatrix:时间序列分段方案;

FactorNum:时间序列分段方案数量。

py文件 HurstFactorization.py如下:

# -*- coding: utf-8 -*-

import math

def HurstFactorization(x): # hurstFactorization

# codebyawang6254978@163.com

# 2017 09 20

# 因子分解,以4开始以X/4结束

# floor函数表示四舍五入

FactorMatrix = []

N = int(math.floor(x / 4))

# 方案数量初始为0

FactorNum = 0

for i in range(4, N + 1):

# i可以被x整除,即得到一组分解方案

if x % i == 0:

# 方案数量+1

FactorNum = FactorNum + 1

# 将可行方案存储到FactorMatrix中

FactorMatrix.append([i, x / i])

return FactorMatrix, FactorNum

函数测试240共有14个分段方案:

X=240

%调用HurstFactorization函数

﹥﹥[FactorMatrix,FactorNum]=HurstFactorization(x)

%分解方案序列

FactorMatrix=

4 60

……

60 4

FactorNum=

14

(2) Hurst指数计算

时间序列 Hurst指数计算函数语法如下:

HurstExponent=HurstCompute(Xtimes)

输入参数:

Xtimes:时间序列数据。

HurstExponent:为二元向量,第一元素为时间序列的 Hurst指数,第二元素为回归分 析常数项。

注:回归模型log((R/S)n)=log(K)+Hlog(n)。

PY文件 HurstCompute.py如下:

# -*- coding: utf-8 -*-

import numpy as np

from numpy.matlib import repmat

from HurstFactorization import HurstFactorization

def HurstCompute(Xtimes):

# HurstCompute

#codebyawang6254978@163.com

# 2017-09-20

# 输入参数为Xtimes

LengthX = len(Xtimes)

# 进行因式分解

FactorMatrix, FactorNum =HurstFactorization(LengthX)

# 定义LogRS

LogRS = []

# 定义LogN

#LogN=np.zeros([FactorNum, 1])

LogN = []

# 分组计算

for i in range(0,FactorNum):

# 根据因式分解方案,将数量进行分组

# 例如 FactorMatrix(i,:)=[8 30]

# 将240个元素的列向量,转换为8X30的矩阵

dataM = np.reshape(Xtimes,FactorMatrix[i])

# print dataM.shape

#dataM=reshape(Xtimes,FactorMatrix(i,:))

# 计算矩阵每列的均值

MeanM = np.mean(dataM, axis=0)

SubM = dataM - repmat(MeanM, FactorMatrix[i][0], 1)

RVector = np.zeros([FactorMatrix[i][1], 1])

SVector = np.zeros([FactorMatrix[i][1], 1])

# 计算(R/S)n的累加

for j in xrange(0, FactorMatrix[i][1]):

SubVector = np.cumsum(SubM[:, j])

RVector[j] = max(SubVector) - min(SubVector)

SVector[j] = np.std(dataM[:, j])

# 分别计算LogRS、LogN

LogRS.append(np.log(np.sum(RVector / SVector) / FactorMatrix[i][1]))

LogN.append(np.log(FactorMatrix[i][0]))

# 使用最小二乘法进行回归,计算赫斯特指数HurstExponent

HurstExponent = np.polyfit(LogN, LogRS, 1)

return HurstExponent

return HurstExponent函数测试的 PY 文件testHurstCompute.py如下测试方法生成一组布朗运动序列,计算布朗运动序列对数序列的 Hurst指数,共测试10次:

# -*- coding: utf-8-*-

from HurstCompute import HurstCompute

import matplotlib.pyplot as plt

testNum = 10

# 并将结果存储在result中

result = np.zeros([testNum, 2])

for i in xrange(0, testNum):

n = 120 *(i + 1)

dt = 1

# 生存长度不同的布朗运动序列

y =np.cumsum(dt ** 0.5 * np.random.random((1, n)))

# 计算每组序列的Hurst值

result[i,:] = HurstCompute(np.log(y))

#生成图表

plt.plot(range(len(result)), result[:, 0], '*')

#设置标题

plt.title("PyPlot First Example")

#显示图表

plt.show()

测试结果图像如图所示。

图片发自简书App

结果说明:图16.1横轴表示1~10共10次计算测试,纵轴表示每次测试计算出的 Hurst

指数值。

(3) 移动平均 Hurst指数计算

使用上证指数2000至2017年上证综指时间序列数据,计算其给定移动平均长度的 Hurst指数。编写 MoveHurst.m函数,其中cyclength为计算周期,用户可根据需求 进行修改。

例如计算120个交易日的 Husrt指数,使用的数据为[t-119,t]的价格数据,移动平均的意思为根据t的向前移动,计算指数的数据为[t-119,t]的价格数据,同时根据t进行移动。代码如下:

import xlrd

# MoveHurst

# codebyawwheng 2017 9 20

# 读取xlsx文件

workbook = xlrd.open_workbook("shindex.xlsx")

# 读取Sheet1工作簿

sheet1 = workbook.sheet_by_name('Sheet1')

# 获取行指针

rows = sheet1.nrows

Prices = []

dates = []

for i inxrange(rows): # 循环指针并读取价格与时间数据至Prices,dates Prices.append(sheet1.row_values(i)[0])

dates.append(int(sheet1.row_values(i)[1]))

# 数据长度

DataLength = len(Prices)

# 计算周期

cyclength = 120

# 数据长度是否大于计算周期,若只有100个数据

# 不可能计算出120计算周期的Hurst指数的

if cyclength> DataLength:

plt.plot(range(1, 100), range(1,100), "r*", range(1, 100), range(100, 1, -1), "ro")

else:

# 将价格数据转换为对数数据

logData = np.log(Prices)

# 计算价格的对数数据对应的每日收益率

IndexReturn=(np.array(logData[1:])-np.array(logData[:-1]).tolis())

# 生成Hurst指数并初始化为NaN

hurstE = np.array([np.nan] *DataLength)

# 计算移动的hurst指数

for i in xrange(0, DataLength -cyclength + 1):

HurstExponent =HurstCompute(IndexReturn[i:i + cyclength - 1])

hurstE[cyclength + i - 1] =HurstExponent[0]

# 创建图表

plt.figure(1)

# 在图表1中创建HurstExponent子图

ax1 = plt.subplot(211)

# 设置y轴标签

plt.ylabel("HurstExponent")

# 设置X轴刻度

ax.set_xticklabels(dates,rotation=1)

# 设置数据与数据宽度

plt.plot(hurstE, linewidth=0.5)

# 在图表2中创建logIndex子图2

ax2 = plt.subplot(212)

plt.ylabel("logIndex")

plt.plot(logData, linewidth=0.5)

图片发自简书App
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容