模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列


原文链接:http://tecdat.cn/?p=20015
本文将说明单变量和多变量金融时间序列的不同模型 , 特别是条件均值和条件协方差矩阵、波动率的模型 。
均值模型 本节探讨条件均值模型 。
iid模型
我们从简单的iid模型开始 。 iid模型假定对数收益率xt为N维高斯时间序列:

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

均值和协方差矩阵的样本估计量分别是样本均值

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

和样本协方差矩阵

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

我们从生成数据开始 , 熟悉该过程并确保估计过程给出正确的结果(即完整性检查) 。 然后使用真实的市场数据并拟合不同的模型 。
让我们生成合成iid数据并估算均值和协方差矩阵:

  1. # 生成综合收益数据
  2. X <- rmvnorm(n = T, mean = mu, sigma = Sigma)
  3. # 样本估计(样本均值和样本协方差矩阵)
  4. mu_sm <- colMeans(X)
  5. Sigma_scm <- cov(X)
  6. # 误差
  7. norm(mu_sm - mu, "2")
  8. #> [1] 2.44
  9. norm(Sigma_scm - Sigma, "F")
  10. #> [1] 70.79
现在 , 让我们针对不同数量的观测值T再做一次:
  1. # 首先生成所有数据
  2. X <- rmvnorm(n = T_max, mean = mu, sigma = Sigma)
  3. # 现在遍历样本的子集
  4. for (T_ in T_sweep) {
  5. # 样本估算
  6. mu_sm <- colMeans(X_)
  7. Sigma_scm <- cov(X_)
  8. # 计算误差
  9. error_mu_vs_T <- c(error_mu_vs_T, norm(mu_sm - mu, "2"))
  10. error_Sigma_vs_T <- c(error_Sigma_vs_T, norm(Sigma_scm - Sigma, "F"))
  11. # 绘图
  12. plot(T_sweep, error_mu_vs_T,
  13. main = "mu估计误差",

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

  1. plot(T_sweep, error_Sigma_vs_T
  2. main = "Sigma估计中的误差", ylab = "误差"

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

单变量ARMA模型
对数收益率xt上的ARMA(p , q)模型是

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

其中wt是均值为零且方差为σ2的白噪声序列 。 模型的参数是系数?i , θi和噪声方差σ2 。
请注意 , ARIMA(p , d , q)模型是时间差分为d阶的ARMA(p , q)模型 。 因此 , 如果我们用xt代替对数价格 , 那么先前的对数收益模型实际上就是ARIMA(p , 1 , q)模型 , 因为一旦对数价格差分 , 我们就获得对数收益 。
rugarch生成数据
我们将使用rugarch包 生成单变量ARMA数据 , 估计参数并进行预测 。
首先 , 我们需要定义模型:
  1. # 指定具有给定系数和参数的AR(1)模型
  2. #>
  3. #> *----------------------------------*
  4. #> * ARFIMA Model Spec *
  5. #> *----------------------------------*
  6. #> Conditional Mean Dynamics
  7. #> ------------------------------------
  8. #> Mean Model : ARFIMA(1,0,0)
  9. #> Include Mean : TRUE
  10. #>
  11. #> Conditional Distribution
  12. #> ------------------------------------
  13. #> Distribution : norm
  14. #> Includes Skew : FALSE
  15. #> Includes Shape : FALSE
  16. #> Includes Lambda : FALSE
  17. #> Level Fixed Include Estimate LB UB
  18. #> mu 0.01 1 1 0 NA NA
  19. #> ar1 -0.90 1 1 0 NA NA
  20. #> ma 0.00 0 0 0 NA NA
  21. #> arfima 0.00 0 0 0 NA NA
  22. #> archm 0.00 0 0 0 NA NA
  23. #> mxreg 0.00 0 0 0 NA NA
  24. #> sigma 0.20 1 1 0 NA NA
  25. #> alpha 0.00 0 0 0 NA NA
  26. #> beta 0.00 0 0 0 NA NA
  27. #> gamma 0.00 0 0 0 NA NA
  28. #> eta1 0.00 0 0 0 NA NA
  29. #> eta2 0.00 0 0 0 NA NA
  30. #> delta 0.00 0 0 0 NA NA
  31. #> lambda 0.00 0 0 0 NA NA
  32. #> vxreg 0.00 0 0 0 NA NA
  33. #> skew 0.00 0 0 0 NA NA
  34. #> shape 0.00 0 0 0 NA NA
  35. #> ghlambda 0.00 0 0 0 NA NA
  36. #> xi 0.00 0 0 0 NA NA
  37. fixed.pars
  38. #> $mu
  39. #> [1] 0.01
  40. #>
  41. #> $ar1
  42. #> [1] -0.9
  43. #>
  44. #> $sigma
  45. #> [1] 0.2
  46. true_params
  47. #> mu ar1 sigma
  48. #> 0.01 -0.90 0.20
然后 , 我们可以生成时间序列:
  1. # 模拟一条路径
  2. apath(spec, n.sim = T)
  3. # 转换为xts并绘图
  4. plot(synth_log_returns, main = "ARMA模型的对数收益率"
  5. plot(synth_log_prices, main = "ARMA模型的对数价格"

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片


模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

ARMA模型
现在 , 我们可以估计参数(我们已经知道):
  1. # 指定AR(1)模型
  2. arfimaspec(mean.model = list(armaOrder = c(1,0), include.mean = TRUE))
  3. # 估计模型
  4. #> mu ar1 sigma
  5. #> 0.0083 -0.8887 0.1987
  6. #> mu ar1 sigma
  7. #> 0.01 -0.90 0.20
我们还可以研究样本数量T对参数估计误差的影响:
  1. # 循环
  2. for (T_ in T_sweep) {
  3. estim_coeffs_vs_T <- rbind(estim_coeffs_vs_T, coef(arma_fit))
  4. error_coeffs_vs_T <- rbind(error_coeffs_vs_T, abs(coef(arma_fit) - true_params)/true_params)
  5. # 绘图
  6. matplot(T_sweep, estim_coeffs_vs_T,
  7. main = "估计的ARMA系数", xlab = "T", ylab = "值",

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

  1. matplot(T_sweep, 100*error_coeffs_vs_T,
  2. main = "估计ARMA系数的相对误差", xlab = "T", ylab = "误差 (%)",

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

首先 , 真正的μ几乎为零 , 因此相对误差可能显得不稳定 。 在T = 800个样本之后 , 其他系数得到了很好的估计 。
ARMA预测
为了进行健全性检查 , 我们现在将比较两个程序包 Forecast 和 rugarch的结果:
  1. # 指定具有给定系数和参数的AR(1)模型
  2. spec(mean.model = list(armaOrder = c(1,0), include.mean = TRUE),
  3. fixed.pars = list(mu = 0.005, ar1 = -0.9, sigma = 0.1))
  4. # 生成长度为1000的序列
  5. arfima(arma_fixed_spec, n.sim = 1000)@path$seriesSim
  6. # 使用 rugarch包指定和拟合模型
  7. spec(mean.model = list(armaOrder = c(1,0), include.mean = TRUE))
  8. # 使用包“ forecast”拟合模型
  9. #> ARIMA(1,0,0) with non-zero mean
  10. #>
  11. #> Coefficients:
  12. #> ar1 mean
  13. #> -0.8982 0.0036
  14. #> s.e. 0.0139 0.0017
  15. #>
  16. #> sigma^2 estimated as 0.01004: log likelihood=881.6
  17. #> AIC=-1757.2 AICc=-1757.17 BIC=-1742.47
  18. # 比较模型系数
  19. #> ar1 intercept sigma
  20. #> -0.898181148 0.003574781 0.100222964
  21. #> mu ar1 sigma
  22. #> 0.003605805 -0.898750138 0.100199956
确实 , 这两个软件包给出了相同的结果 。
ARMA模型选择
在先前的实验中 , 我们假设我们知道ARMA模型的阶数 , 即p = 1和q = 0 。 实际上 , 阶数是未知的 , 因此必须尝试不同的阶数组合 。 阶数越高 , 拟合越好 , 但这将不可避免地导致过度拟合 。 已经开发出许多方法来惩罚复杂性的增加以避免过度拟合 , 例如AIC , BIC , SIC , HQIC等 。
  1. # 尝试不同的组合
  2. # 查看排名
  3. #> AR MA Mean ARFIMA BIC converged
  4. #> 1 1 0 1 0 -0.38249098 1
  5. #> 2 1 1 1 0 -0.37883157 1
  6. #> 3 2 0 1 0 -0.37736340 1
  7. #> 4 1 2 1 0 -0.37503980 1
  8. #> 5 2 1 1 0 -0.37459177 1
  9. #> 6 3 0 1 0 -0.37164609 1
  10. #> 7 1 3 1 0 -0.37143480 1
  11. #> 8 2 2 1 0 -0.37107841 1
  12. #> 9 3 1 1 0 -0.36795491 1
  13. #> 10 2 3 1 0 -0.36732669 1
  14. #> 11 3 2 1 0 -0.36379209 1
  15. #> 12 3 3 1 0 -0.36058264 1
  16. #> 13 0 3 1 0 -0.11875575 1
  17. #> 14 0 2 1 0 0.02957266 1
  18. #> 15 0 1 1 0 0.39326050 1
  19. #> 16 0 0 1 0 1.17294875 1
  20. #选最好的
  21. armaOrder
  22. #> AR MA
  23. #> 1 0
在这种情况下 , 由于观察次数T = 1000足够大 , 因此阶数被正确地检测到 。 相反 , 如果尝试使用T = 200 , 则检测到的阶数为p = 1 , q = 3 。
ARMA预测
一旦估计了ARMA模型参数?i ^ i和θ^j , 就可以使用该模型预测未来的值 。 例如 , 根据过去的信息对xt的预测是

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

并且预测误差将为xt-x ^ t = wt(假设参数已被估计) , 其方差为σ2 。 软件包 rugarch 使对样本外数据的预测变得简单:
  1. # 估计模型(不包括样本外)
  2. coef(arma_fit)
  3. #> mu ar1 sigma
  4. #> 0.007212069 -0.898745183 0.200400119
  5. # 整个样本外的预测对数收益
  6. forecast_log_returns <- xts(arma_fore@forecast$seriesFor[1, ], dates_out_of_sample)
  7. # 恢复对数价格
  8. prev_log_price <- head(tail(synth_log_prices, out_of_sample+1), out_of_sample)
  9. # 对数收益图
  10. plot(cbind("fitted" = fitted(arma_fit),
  11. # 对数价格图
  12. plot(cbind("forecast" = forecast_log_prices,
  13. main = "对数价格预测", legend.loc = "topleft")

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片


模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

多元VARMA模型
对数收益率xt上的VARMA(p , q)模型是

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

其中wt是具有零均值和协方差矩阵Σw的白噪声序列 。 该模型的参数是矢量/矩阵系数?0 , Φi , Θj和噪声协方差矩阵Σw 。
比较
让我们首先加载S&P500:
  1. # 加载标普500数据
  2. head(SP500_index_prices)
  3. #> SP500
  4. #> 2012-01-03 1277.06
  5. #> 2012-01-04 1277.30
  6. #> 2012-01-05 1281.06
  7. #> 2012-01-06 1277.81
  8. #> 2012-01-09 1280.70
  9. #> 2012-01-10 1292.08
  10. # 准备训练和测试数据
  11. logreturns_trn <- logreturns[1:T_trn]
  12. logreturns_tst <- logreturns[-c(1:T_trn)]
  13. # 绘图
  14. { plot(logreturns,
  15. addEventLines(xts("训练"

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

现在 , 我们使用训练数据(即 , 对于t = 1 , … , Ttrnt = 1 , … , Ttrn)来拟合不同的模型(请注意 , 通过指示排除了样本外数据 out.sample = T_tst) 。 特别是 , 我们将考虑iid模型 , AR模型 , ARMA模型以及一些ARCH和GARCH模型(稍后将对方差建模进行更详细的研究) 。
  1. # 拟合i.i.d.模型
  2. coef(iid_fit)
  3. #> mu sigma
  4. #> 0.0005712982 0.0073516993
  5. mean(logreturns_trn)
  6. #> [1] 0.0005681388
  7. sd(logreturns_trn)
  8. #> [1] 0.007360208
  9. # 拟合AR(1)模型
  10. coef(ar_fit)
  11. #> mu ar1 sigma
  12. #> 0.0005678014 -0.0220185181 0.0073532716
  13. # 拟合ARMA(2,2)模型
  14. coef(arma_fit)
  15. #> mu ar1 ar2 ma1 ma2 sigma
  16. #> 0.0007223304 0.0268612636 0.9095552008 -0.0832923604 -0.9328475211 0.0072573570
  17. # 拟合ARMA(1,1)+ ARCH(1)模型
  18. coef(arch_fit)
  19. #> mu ar1 ma1 omega alpha1
  20. #> 6.321441e-04 8.720929e-02 -9.391019e-02 4.898885e-05 9.986975e-02
  21. #拟合ARMA(0,0)+ARCH(10)模型
  22. coef(long_arch_fit)
  23. #> mu omega alpha1 alpha2 alpha3 alpha4 alpha5
  24. #> 7.490786e-04 2.452099e-05 6.888561e-02 7.207551e-02 1.419938e-01 1.909541e-02 3.082806e-02
  25. #> alpha6 alpha7 alpha8 alpha9 alpha10
  26. #> 4.026539e-02 3.050040e-07 9.260183e-02 1.150128e-01 1.068426e-06
  27. # 拟合ARMA(1,1)+GARCH(1,1)模型
  28. coef(garch_fit)
  29. #> mu ar1 ma1 omega alpha1 beta1
  30. #> 6.660346e-04 9.664597e-01 -1.000000e+00 7.066506e-06 1.257786e-01 7.470725e-01
我们使用不同的模型来预测对数收益率:
  1. # 准备预测样本外周期的对数收益
  2. # i.i.d.模型预测
  3. forecast(iid_fit, n.ahead = 1, n.roll = T_tst - 1)
  4. dates_out_of_sample)
  5. # AR(1)模型进行预测
  6. forecast(ar_fit, n.ahead = 1, n.roll = T_tst - 1)
  7. dates_out_of_sample)
  8. # ARMA(2,2)模型进行预测
  9. forecast(arma_fit, n.ahead = 1, n.roll = T_tst - 1)
  10. dates_out_of_sample)
  11. # 使用ARMA(1,1)+ ARCH(1)模型进行预测
  12. forecast(arch_fit, n.ahead = 1, n.roll = T_tst - 1)
  13. dates_out_of_sample)
  14. # ARMA(0,0)+ARCH(10)模型预测
  15. forecast(long_arch_fit, n.ahead = 1, n.roll = T_tst - 1)
  16. dates_out_of_sample)
  17. # ARMA(1,1)+GARCH(1,1)模型预测
  18. forecast(garch_fit, n.ahead = 1, n.roll = T_tst - 1)
  19. dates_out_of_sample)
我们可以计算不同模型的预测误差(样本内和样本外):
  1. print(error_var)
  2. #> in-sample out-of-sample
  3. #> iid 5.417266e-05 8.975710e-05
  4. #> AR(1) 5.414645e-05 9.006139e-05
  5. #> ARMA(2,2) 5.265204e-05 1.353213e-04
  6. #> ARMA(1,1) + ARCH(1) 5.415836e-05 8.983266e-05
  7. #> ARCH(10) 5.417266e-05 8.975710e-05
  8. #> ARMA(1,1) + GARCH(1,1) 5.339071e-05 9.244012e-05
我们可以观察到 , 随着模型复杂度的增加 , 样本内误差趋于变小(由于拟合数据的自由度更高) , 尽管差异可以忽略不计 。 重要的实际上是样本外误差:我们可以看到 , 增加模型复杂度可能会得出较差的结果 。 就预测收益的误差而言 , 似乎最简单的iid模型已经足够了 。
最后 , 让我们展示一些样本外误差的图表:
  1. plot(error,
  2. main = "不同模型收益预测的样本外误差",

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

请注意 , 由于我们没有重新拟合模型 , 因此随着时间的发展 , 误差越大(对于ARCH建模尤其明显) 。
滚动窗口比较
让我们首先通过一个简单的示例比较静态预测与滚动预测的概念:
  1. #ARMA(2,2)模型
  2. spec <- spec(mean.model = list(armaOrder = c(2,2), include.mean = TRUE))
  3. # 静态拟合和预测
  4. ar_static_fit <- fit(spec = spec, data = https://www.sohu.com/a/logreturns, out.sample = T_tst)
  5. #滚动拟合和预测
  6. modelroll <- aroll(spec = spec, data = https://www.sohu.com/a/logreturns, n.ahead = 1,
  7. # 预测图
  8. plot(cbind("static forecast" = ar_static_fore_logreturns,
  9. main = "使用ARMA(2,2)模型进行预测", legend.loc = "topleft")
  10. # 预测误差图
  11. plot(error_logreturns, col = c("black", "red"), lwd = 2,
  12. main = "ARMA(2,2)模型的预测误差", legend.loc = "topleft")

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片


模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

我们可以清楚地观察到滚动窗口过程对时间序列的影响 。
现在 , 我们可以在滚动窗口的基础上重做所有模型的所有预测:
  1. # 基于i.i.d.模型的滚动预测
  2. roll(iid_spec, data = https://www.sohu.com/a/logreturns, n.ahead = 1, forecast.length = T_t
  3. # AR(1)模型的滚动预测
  4. roll(ar_spec, data = https://www.sohu.com/a/logreturns, n.ahead = 1, forecast.length = T_tst,
  5. # ARMA(2,2)模型的滚动预测
  6. roll(arma_spec, data = https://www.sohu.com/a/logreturns, n.ahead = 1, forecast.length = T_tst,
  7. # ARMA(1,1)+ ARCH(1)模型的滚动预测
  8. roll(arch_spec, data = https://www.sohu.com/a/logreturns, n.ahead = 1, forecast.length = T_tst,
  9. refit.every = 50, refit.win
  10. # ARMA(0,0)+ ARCH(10)模型的滚动预测
  11. roll(long_arch_spec, data = https://www.sohu.com/a/logreturns, n.ahead = 1, forecast.length = T_tst,
  12. refit.every = 50,
  13. # ARMA(1,1)+ GARCH(1,1)模型的滚动预测
  14. roll(garch_spec, data = https://www.sohu.com/a/logreturns, n.ahead = 1, forecast.length = T_tst,
  15. refit.every = 50, refit.window
让我们看看滚动基准情况下的预测误差:
  1. print(rolling_error_var)
  2. #> in-sample out-of-sample
  3. #> iid 5.417266e-05 8.974166e-05
  4. #> AR(1) 5.414645e-05 9.038057e-05
  5. #> ARMA(2,2) 5.265204e-05 8.924223e-05
  6. #> ARMA(1,1) + ARCH(1) 5.415836e-05 8.991902e-05
  7. #> ARCH(10) 5.417266e-05 8.976736e-05
  8. #> ARMA(1,1) + GARCH(1,1) 5.339071e-05 8.895682e-05
和一些图表:
  1. plot(error_logreturns,
  2. main = "不同模型的滚动预测误差", legend.loc = "topleft"

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

我们看到 , 现在所有模型都拟合了时间序列 。 此外 , 我们在模型之间没有发现任何显着差异 。
我们最终可以比较静态误差和滚动误差:
  1. barplot(rbind(error_var[, "out-of-sample"], rolling_error_var[, "out-of-sample"])
  2. col = c("darkblue", "darkgoldenrod"),
  3. legend = c("静态预测", "滚动预测"),

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

我们可以看到 , 滚动预测在某些情况下是必须的 。 因此 , 实际上 , 我们需要定期进行滚动预测改进 。
方差模型 ARCH和GARCH模型
对数收益率残差wt的ARCH(m)模型为

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

其中zt是具有零均值和恒定方差的白噪声序列 , 而条件方差σ2t建模为

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

其中 , m为模型阶数 , ω> 0 , αi≥0为参数 。
GARCH(m , s)模型使用σ2t上的递归项扩展了ARCH模型:

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

其中参数ω> 0 , αi≥0 , βj≥0需要满足∑mi =1αi+ ∑sj = 1βj≤1的稳定性 。
rugarch生成数据
首先 , 我们需要定义模型:
  1. # 指定具有给定系数和参数的GARCH模型
  2. #>
  3. #> *---------------------------------*
  4. #> * GARCH Model Spec *
  5. #> *---------------------------------*
  6. #>
  7. #> Conditional Variance Dynamics
  8. #> ------------------------------------
  9. #> GARCH Model : sGARCH(1,1)
  10. #> Variance Targeting : FALSE
  11. #>
  12. #> Conditional Mean Dynamics
  13. #> ------------------------------------
  14. #> Mean Model : ARFIMA(1,0,0)
  15. #> Include Mean : TRUE
  16. #> GARCH-in-Mean : FALSE
  17. #>
  18. #> Conditional Distribution
  19. #> ------------------------------------
  20. #> Distribution : norm
  21. #> Includes Skew : FALSE
  22. #> Includes Shape : FALSE
  23. #> Includes Lambda : FALSE
  24. #> Level Fixed Include Estimate LB UB
  25. #> mu 0.005 1 1 0 NA NA
  26. #> ar1 -0.900 1 1 0 NA NA
  27. #> ma 0.000 0 0 0 NA NA
  28. #> arfima 0.000 0 0 0 NA NA
  29. #> archm 0.000 0 0 0 NA NA
  30. #> mxreg 0.000 0 0 0 NA NA
  31. #> omega 0.001 1 1 0 NA NA
  32. #> alpha1 0.300 1 1 0 NA NA
  33. #> beta1 0.650 1 1 0 NA NA
  34. #> gamma 0.000 0 0 0 NA NA
  35. #> eta1 0.000 0 0 0 NA NA
  36. #> eta2 0.000 0 0 0 NA NA
  37. #> delta 0.000 0 0 0 NA NA
  38. #> lambda 0.000 0 0 0 NA NA
  39. #> vxreg 0.000 0 0 0 NA NA
  40. #> skew 0.000 0 0 0 NA NA
  41. #> shape 0.000 0 0 0 NA NA
  42. #> ghlambda 0.000 0 0 0 NA NA
  43. #> xi 0.000 0 0 0 NA NA
  44. #> $mu
  45. #> [1] 0.005
  46. #>
  47. #> $ar1
  48. #> [1] -0.9
  49. #>
  50. #> $omega
  51. #> [1] 0.001
  52. #>
  53. #> $alpha1
  54. #> [1] 0.3
  55. #>
  56. #> $beta1
  57. #> [1] 0.65
  58. true_params
  59. #> mu ar1 omega alpha1 beta1
  60. #> 0.005 -0.900 0.001 0.300 0.650
然后 , 我们可以生成收益率时间序列:
  1. # 模拟一条路径
  2. hpath(garch_spec, n.sim = T)
  3. #> num [1:2000, 1] 0.167 -0.217
  4. # 绘图对数收益
  5. { plot(synth_log_returns, main = "GARCH模型的对数收益", lwd = 1.5)
  6. lines(synth_volatility

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

GARCH
现在 , 我们可以估计参数:
  1. # 指定一个GARCH模型
  2. ugarchspec(mean.model = list(armaOrder = c(1,0)
  3. # 估计模型
  4. coef(garch_fit)
  5. #> mu ar1 omega alpha1 beta1
  6. #> 0.0036510100 -0.8902333595 0.0008811434 0.2810460728 0.6717486402
  7. #> mu ar1 omega alpha1 beta1
  8. #> 0.005 -0.900 0.001 0.300 0.650
  9. # 系数误差
  10. #> mu ar1 omega alpha1 beta1
  11. #> 0.0013489900 0.0097666405 0.0001188566 0.0189539272 0.0217486402
我们还可以研究样本数量T对参数估计误差的影响:
  1. # 循环
  2. for (T_ in T_sweep) {
  3. garch_fit
  4. error_coeffs_vs_T <- rbind(error_coeffs_vs_T, abs((coef(garch_fit) - true_params)/true_params))
  5. estim_coeffs_vs_T <- rbind(estim_coeffs_vs_T, coef(garch_fit))
  6. # 绘图
  7. matplot(T_sweep, 100*error_coeffs_vs_T,
  8. main = "估计GARCH系数的相对误差", xlab = "T", ylab = "误差 (%)",

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

真实的ω几乎为零 , 因此误差非常不稳定 。 至于其他系数 , 就像在ARMA情况下一样 , μ的估计确实很差(相对误差超过50%) , 而其他系数似乎在T = 800个样本后得到了很好的估计 。
GARCH结果比较
作为健全性检查 , 我们现在将比较两个软件包 fGarch 和 rugarch的结果:
  1. # 指定具有特定参数值的ARMA(0,0)-GARCH(1,1)作为数据生成过程
  2. garch_spec
  3. #生成长度为1000的数据
  4. path(garch_fixed_spec, n.sim = 1000)@path$
  5. # 使用“ rugarch”包指定和拟合模型
  6. rugarch_fit <- ugarchfit(spec = garch_spec, data = https://www.sohu.com/a/x)
  7. # 使用包“ fGarch”拟合模型
  8. garchFit(formula = ~ garch(1, 1), data = https://www.sohu.com/a/x, trace = FALSE)
  9. # 比较模型系数
  10. #> mu omega alpha1 beta1
  11. #> 0.09749904 0.01395109 0.13510445 0.73938595
  12. #> mu omega alpha1 beta1
  13. #> 0.09750394 0.01392648 0.13527024 0.73971658
  14. # 比较拟合的标准偏差
  15. print(head(fGarch_fi
  16. #> [1] 0.3513549 0.3254788 0.3037747 0.2869034 0.2735266 0.2708994
  17. print(head(rugar
  18. #> [1] 0.3538569 0.3275037 0.3053974 0.2881853 0.2745264 0.2716555
确实 , 这两个软件包给出了相同的结果 。
使用rugarch包进行GARCH预测
一旦估计出GARCH模型的参数 , 就可以使用该模型预测未来的值 。 例如 , 基于过去的信息对条件方差的单步预测为

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

给定ω^ /(1-∑mi =1α^ i-∑sj =1β^ j) 。 软件包 rugarch 使对样本外数据的预测变得简单:
  1. # 估计模型 , 不包括样本外
  2. garch_fit
  3. coef(garch_fit)
  4. #> mu ar1 omega alpha1 beta1
  5. #> 0.0034964331 -0.8996287630 0.0006531088 0.3058756796 0.6815452241
  6. # 预测整个样本的对数收益
  7. garch_fore@forecast$sigmaFor[1, ]
  8. # 对数收益图
  9. plot(cbind("fitted" = fitted(garch_fit),
  10. main = "合成对数收益预测", legend.loc = "topleft")

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

  1. #波动率对数收益图
  2. plot(cbind("fitted volatility" = sigma(garch_fit),
  3. main = "预测合成对数收益率的波动性", legend.loc = "topleft")

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

不同方法
让我们首先加载S&P500:
  1. # 加载标准普尔500指数数据
  2. head(SP500_index_prices)
  3. #> SP500
  4. #> 2008-01-02 1447.16
  5. #> 2008-01-03 1447.16
  6. #> 2008-01-04 1411.63
  7. #> 2008-01-07 1416.18
  8. #> 2008-01-08 1390.19
  9. #> 2008-01-09 1409.13
  10. # 准备训练和测试数据
  11. x_trn <- x[1:T_trn]
  12. x_tst <- x[-c(1:T_trn)]
  13. # 绘图
  14. { plot(x, main = "收益"
  15. addEventLines(xts("训练", in

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

常数
让我们从常数开始:
  1. plot(cbind(sqrt(var_constant), x_trn)
  2. main = "常数")

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

移动平均值
现在 , 让我们使用平方收益的移动平均值:

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

  1. plot(cbind(sqrt(var_t), x_trn),
  2. main = "基于简单滚动平方均值的包络线(时间段=20)

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

EWMA
指数加权移动平均线(EWMA):

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

请注意 , 这也可以建模为ETS(A , N , N)状态空间模型:

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

  1. plot(cbind(std_t, x_trn),
  2. main = "基于平方EWMA的包络")

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

乘法ETS
我们还可以尝试ETS模型的不同变体 。 例如 , 具有状态空间模型的乘性噪声版本ETS(M , N , N):

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

  1. plot(cbind(std_t, x_trn), col = c("red", "black")
  2. main = "基于平方的ETS(M , N , N)的包络"

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

ARCH
现在 , 我们可以使用更复杂的ARCH建模:

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

  1. plot(cbind(std_t, x_trn), col = c("red", "black")
  2. main = "基于ARCH(5)的包络")

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

GARCH
我们可以将模型提升到GARCH:

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

  1. plot(cbind(std_t, x_trn), col = c("red", "black")
  2. main = "基于GARCH(1,1)的包络")

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

SV随机波动率
最后 , 我们可以使用随机波动率建模:

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

或者 , 等效地 ,

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

  1. plot(cbind(std_t, x_trn), col = c("red", "black"),
  2. main = "基于随机波动率的包络分析")

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

比较
现在 , 我们可以比较每种方法在样本外期间的方差估计中的误差:
  1. #> MA EWMA ETS(M,N,N) ARCH(5) GARCH(1,1) SV
  2. #> 2.204965e-05 7.226188e-06 3.284057e-06 7.879039e-05 6.496545e-06 6.705059e-06
  3. barplot(error_all, main = "样本外方差估计中的误差"

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

滚动窗口比较
六种方法的滚动窗口比较:MA , EWMA , ETS(MNN) , ARCH(5) , GARCH(1,1)和SV 。
  1. #滚动窗口
  2. lookback <- 200
  3. len_tst <- 40
  4. for (i in seq(lookback, T-len_tst, by = len_tst)) {
  5. # MA
  6. var_t <- roll_meanr(x_trn^2, n = 20, fill = NA)
  7. var_fore <- var(x_trn/sqrt(var_t), na.rm = TRUE) * tail(var_t, 1)
  8. error_ma <- c(error_ma, abs(var_fore - var_tst))
  9. # EWMA
  10. error_ewma <- c(error_ewma, abs(var_fore - var_tst))
  11. # ETS(M,N,N)
  12. error_ets_mnn <- c(error_ets_mnn, abs(var_fore - var_tst))
  13. # ARCH
  14. error_arch <- c(error_arch, abs(var_fore - var_tst))
  15. # GARCH
  16. error_garch <- c(error_garch, abs(var_fore - var_tst))
  17. # SV
  18. error_sv <- c(error_sv, abs(var_fore - var_tst))
  19. }
  20. barplot(error_all, main = "方差估计误差",

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

多元GARCH模型
出于说明目的 , 我们将仅考虑恒定条件相关(CCC)和动态条件相关(DCC)模型 , 因为它们是最受欢迎的模型 。 对数收益率残差wt建模为

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

其中zt是具有零均值和恒定协方差矩阵II的iid白噪声序列 。 条件协方差矩阵Σt建模为

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

其中Dt = Diag(σ1 , t , ... , σN , t)是标准化噪声向量C , 协方差矩阵ηt=C-1wt(即 , 它包含等于1的对角线元素) 。
基本上 , 使用此模型 , 对角矩阵Dt包含一组单变量GARCH模型 , 然后矩阵C包含序列之间的一些相关性 。 该模型的主要缺点是矩阵C是恒定的 。 为了克服这个问题 , DCC被提议为

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

其中Ct包含等于1的对角元素 。 要强制等于1的对角元素 , Engle将其建模为

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

Qt具有任意对角线元素并遵循模型

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

我们将生成数据 , 估计参数和预测 。
从加载多元ETF数据开始:
  • SPDR S&P 500 ETF
  • 20年以上国债ETF
  • IEF:7-10年期国债ETF
  1. # 下载数据
  2. prices <- xts()
  3. head(prices)
  4. #> SPY TLT IEF
  5. #> 2013-01-02 127.8779 99.85183 93.65224
  6. #> 2013-01-03 127.5890 98.49886 93.17085
  7. #> 2013-01-04 128.1493 98.88306 93.21463
  8. #> 2013-01-07 127.7991 98.92480 93.26714
  9. #> 2013-01-08 127.4314 99.57622 93.49468
  10. #> 2013-01-09 127.7553 99.48438 93.54719
  11. # 绘制三个对数价格序列
  12. plot(log(prices)
  13. main = "三个ETF的对数价格", legend.loc = "topleft")

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

首先 , 我们定义模型:
  1. # 指定i.i.d.单变量时间序列模型
  2. ugarch_spec
  3. # 指定DCC模型
  4. spec( multispec(replicate(spec, n = 3))
接下来 , 我们拟合模型:
  1. # 估计模型
  2. #>
  3. #> *---------------------------------*
  4. #> * DCC GARCH Fit *
  5. #> *---------------------------------*
  6. #>
  7. #> Distribution : mvnorm
  8. #> Model : DCC(1,1)
  9. #> No. Parameters : 44
  10. #> [VAR GARCH DCC UncQ] : [30+9+2+3]
  11. #> No. Series : 3
  12. #> No. Obs. : 1007
  13. #> Log-Likelihood : 12198.4
  14. #> Av.Log-Likelihood : 12.11
  15. #>
  16. #> Optimal Parameters
  17. #> -----------------------------------
  18. #> Estimate Std. Error t value Pr(>|t|)
  19. #> [SPY].omega 0.000004 0.000000 11.71585 0.000000
  20. #> [SPY].alpha1 0.050124 0.005307 9.44472 0.000000
  21. #> [SPY].beta1 0.870051 0.011160 77.96041 0.000000
  22. #> [TLT].omega 0.000001 0.000001 0.93156 0.351563
  23. #> [TLT].alpha1 0.019716 0.010126 1.94707 0.051527
  24. #> [TLT].beta1 0.963760 0.006434 149.79210 0.000000
  25. #> [IEF].omega 0.000000 0.000001 0.46913 0.638979
  26. #> [IEF].alpha1 0.031741 0.023152 1.37097 0.170385
  27. #> [IEF].beta1 0.937777 0.016498 56.84336 0.000000
  28. #> [Joint]dcca1 0.033573 0.014918 2.25044 0.024421
  29. #> [Joint]dccb1 0.859787 0.079589 10.80278 0.000000
  30. #>
  31. #> Information Criteria
  32. #> ---------------------
  33. #>
  34. #> Akaike -24.140
  35. #> Bayes -23.925
  36. #> Shibata -24.143
  37. #> Hannan-Quinn -24.058
  38. #>
  39. #>
  40. #> Elapsed time : 0.8804049
我们可以绘制时变相关性:
  1. # 提取时变协方差和相关矩阵
  2. dim(dcc_cor)
  3. #> [1] 3 3 1007
  4. #绘图
  5. plot(corr_t
  6. main = "时变相关", legend.loc = "left")

模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

我们看到两个收益ETF之间的相关性非常高且相当稳定 。 与SPY的相关性较小 , 在小于0的区间波动 。
【模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列】
模型|拓端tecdat|R语言多元ARMA,GARCH ,EWMA, ETS,随机波动率SV模型金融时间序列
文章图片

最受欢迎的见解
1.HAR-RV-J与递归神经网络(RNN)混合模型预测和交易大型股票指数的高频波动率
2.R语言中基于混合数据抽样(MIDAS)回归的HAR-RV模型预测GDP增长
3.波动率的实现:ARCH模型与HAR-RV模型
4.R语言ARMA-EGARCH模型、集成预测算法对SPX实际波动率进行预测
5.GARCH(1,1) , MA以及历史模拟法的VaR比较
6.R语言多元COPULA GARCH 模型时间序列预测
7.R语言基于ARMA-GARCH过程的VAR拟合和预测
8.matlab预测ARMA-GARCH 条件均值和方差模型
9.R语言对S&P500股票指数进行ARIMA + GARCH交易策略

    推荐阅读