金融市场通常会呈现2,3种市场状态(牛市, 熊市,震荡市)。每种市场状态分别代表的市场指数不同的特性:
我们可以将中证500从2013年7月至2015年9月的净值曲线分为如上几个状态:
source("gmmhmm.R")
data <- read.csv("data/NAV_5ETFs.csv")
zz500 <- as.xts(data[, 2], order.by=strptime(data[, 1], format="%Y-%m-%d", tz=""))
zz500 <- na.omit(cbind(zz500, Return.calculate(zz500)))
colnames(zz500) <- c('zz500', 'zz500.ret')
将中证500指数的日回报数据进行分析,我们可以看到它并不是一个理论的高斯正态分布,表现出负对称性和左端的厚尾。
## zz500.ret
## Observations 1602.0000
## NAs 0.0000
## Minimum -0.0843
## Quartile 1 -0.0087
## Median 0.0026
## Arithmetic Mean 0.0009
## Geometric Mean 0.0007
## Quartile 3 0.0128
## Maximum 0.0987
## SE Mean 0.0005
## LCL Mean (0.95) -0.0001
## UCL Mean (0.95) 0.0019
## Variance 0.0004
## Stdev 0.0203
## Skewness -0.4888
## Kurtosis 2.2795
因此,如果我们将市场指数(如沪深300)日回报(daily return),划分为如上所述的3个市场状态的3组数据, 则它们应该会整体呈现出如下特征:
所以如果我们可以通过机器学习以及相关的分类模型的方法, 对市场数据进行分析, 我们就可以更深入的了解当前的市场状态, 并作出相应的投资决策。
这里我们使用两者机器学习领域常用的模型:
首先我们简要介绍一下什么是高斯混合模型GMM。
GMM模型可以如何帮我们实现对市场数据的分析呢? 首先, 当我们认为市场存在n个状态(n=2是牛熊市, n=3是牛熊市和震荡市, 当然n可以为任何>1的自然数),GMM分析所有的数据,并找到最佳的n个市场状态的中心点(中心点定义为该市场状态下的平均回报率r和波动性\(\sigma\)。 其次, GMM根据每个数据点距离n个分组中心点的距离(距离是由我们选定的每个分组的概率分布pdf方程决定的), 告诉我们该数据点属于哪个分组的几率最高。
也就是说,我们只要告诉GMM我们在寻找n=3个市场状态, 以及每个市场状态下数据的概率分布方程(Probability Distribution Function)是什么:通常选择正态分布(Normal Distribution), GMM就会自动帮我们将市场数据分成几类。
基于上述的分析, 我们用R中间的depmix软件包来分析中证500最近2008至2015年的数据。
Case 1: 我们选择2个市场状态,来看看HMM是否可以有效的将市场数据分开:
library(depmixS4)
set.seed(1)
HMM <- depmix(list(zz500.ret~1), data = zz500,
nstates = 2, family=list(gaussian()))
HMMfit <- fit(HMM, verbose=FALSE)
## converged at iteration 59 with logLik: 4145.246
HMMpost <- posterior(HMMfit)
regimes <- as.xts(HMMpost$state, order.by = index(zz500), tzone=Sys.getenv("TZ"))
## regime1 regime2 zz500.ret
## Observations 1602.0000 1602.0000 1602.0000
## NAs 0.0000 0.0000 0.0000
## Minimum -0.0501 -0.0843 -0.0843
## Quartile 1 -0.0021 0.0000 -0.0087
## Median 0.0000 0.0000 0.0026
## Arithmetic Mean 0.0013 -0.0004 0.0009
## Geometric Mean 0.0012 -0.0005 0.0007
## Quartile 3 0.0077 0.0000 0.0128
## Maximum 0.0418 0.0987 0.0987
## SE Mean 0.0003 0.0004 0.0005
## LCL Mean (0.95) 0.0007 -0.0012 -0.0001
## UCL Mean (0.95) 0.0019 0.0004 0.0019
## Variance 0.0001 0.0003 0.0004
## Stdev 0.0116 0.0166 0.0203
## Skewness -0.3233 -0.5801 -0.4888
## Kurtosis 1.6955 7.3995 2.2795
## regime1 regime2 zz500.ret
## Annualized Return 0.3636 -0.1284 0.1885
## Annualized Std Dev 0.1838 0.2637 0.3219
## Annualized Sharpe (Rf=0%) 1.9779 -0.4869 0.5857
case 2:
library(depmixS4)
set.seed(1)
HMM <- depmix(list(zz500.ret~1), data = zz500,
nstates = 4, family=list(gaussian()))
#HMM <- depmix(list(shanghai~1, lag1~1, lag2~1, ATR~1), data = data_test1,
# nstates = 5, family=list(gaussian(), gaussian(), gaussian(), gaussian()))
HMMfit <- fit(HMM, verbose=FALSE)
HMMpost <- posterior(HMMfit)
regimes <- as.xts(HMMpost$state, order.by = index(zz500), tzone=Sys.getenv("TZ"))
regimes_ordered <- regimes * 0;
regimes_ordered[regimes == 3] <- 5;
regimes_ordered[regimes == 2] <- 1;
regimes_ordered[regimes == 5] <- 3;
regimes_ordered[regimes == 1] <- 2;
regimes_ordered[regimes == 4] <- 4;
ret_regimes <- na.omit(cbind(
zz500$zz500.ret * (regimes==1),
zz500$zz500.ret*(regimes==2),
zz500$zz500.ret * (regimes==3),
zz500$zz500.ret * (regimes==4),
#data_test1[, 1] * (regimes==5),
zz500$zz500.ret))
charts.PerformanceSummary(ret_regimes)