zoukankan      html  css  js  c++  java
  • 拓端数据tecdat|R语言Fama-French三因子模型实际应用:优化投资组合

    原文链接:http://tecdat.cn/?p=20360 

    本文将说明金融数学中的R 语言优化投资组合,因子模型的实现和使用。

    具有单一市场因素的宏观经济因素模型

    我们将从一个包含单个已知因子(即市场指数)的简单示例开始。该模型为

    其中显式因子ft为S&P 500指数。我们将做一个简单的最小二乘(LS)回归来估计截距α和加载β:

    大多数代码行用于准备数据,而不是执行因子建模。让我们开始准备数据:

    1.  
       
    2.  
       
    3.  
      # 设置开始结束日期和股票名称列表
    4.  
      begin_date <- "2016-01-01"
    5.  
      end_date <- "2017-12-31"
    6.  
       
    7.  
       
    8.  
      # 从YahooFinance下载数据
    9.  
      data_set <- xts()
    10.  
      for (stock_index in 1:length(stock_namelist))
    11.  
      data_set <- cbind(data_set, Ad(getSymbols(stock_namelist[stock_index],
    12.  
      from = begin_date, to = end_date,
    13.  
      head(data_set)
    14.  
      #> AAPL AMD ADI ABBV AEZS A APD AA CF
    15.  
      #> 2016-01-04 98.74225 2.77 49.99239 49.46063 4.40 39.35598 107.89010 23.00764 35.13227
    16.  
      #> 2016-01-05 96.26781 2.75 49.62508 49.25457 4.21 39.22057 105.96097 21.96506 34.03059
    17.  
      #> 2016-01-06 94.38389 2.51 47.51298 49.26315 3.64 39.39467 103.38042 20.40121 31.08988
    18.  
      #> 2016-01-07 90.40047 2.28 46.30082 49.11721 3.29 37.72138 99.91463 19.59558 29.61520
    19.  
      #> 2016-01-08 90.87848 2.14 45.89677 47.77789 3.29 37.32482 99.39687 19.12169 29.33761
    20.  
      #> 2016-01-11 92.35001 2.34 46.98954 46.25827 3.13 36.69613 99.78938 18.95583 28.14919
    21.  
       
    22.  
      head(SP500_index)
    23.  
      #> index
    24.  
      #> 2016-01-04 2012.66
    25.  
      #> 2016-01-05 2016.71
    26.  
      #> 2016-01-06 1990.26
    27.  
      #> 2016-01-07 1943.09
    28.  
      #> 2016-01-08 1922.03
    29.  
      #> 2016-01-11 1923.67
    30.  
      plot(SP500_index)
    31.  
       

    1.  
       
    2.  
      # 计算股票和SP500指数的对数收益率作为显式因子
    3.  
      X <- diff(log(data_set), na.pad = FALSE)
    4.  
      N <- ncol(X) # 股票数量
    5.  
      T <- nrow(X) # 天数

    现在我们准备进行因子模型拟合。LS拟合很容易在R中实现,如下所示:

    1.  
       
    2.  
      beta <- cov(X,f)/as.numeric(var(f))
    3.  
      alpha <- colMeans(X) - beta*colMeans(f)
    4.  
      sigma2 <- rep(NA, N)
    5.  
       
    6.  
      print(alpha)
    7.  
      #> index
    8.  
      #> AAPL 0.0003999086
    9.  
      #> AMD 0.0013825599
    10.  
      #> ADI 0.0003609968
    11.  
      #> ABBV 0.0006684632
    12.  
      #> AEZS -0.0022091301
    13.  
      #> A 0.0002810616
    14.  
      #> APD 0.0001786375
    15.  
      #> AA 0.0006429140
    16.  
      #> CF -0.0006029705
    17.  
      print(beta)
    18.  
      #> index
    19.  
      #> AAPL 1.0957919
    20.  
      #> AMD 2.1738304
    21.  
      #> ADI 1.2683047
    22.  
      #> ABBV 0.9022748
    23.  
      #> AEZS 1.7115761
    24.  
      #> A 1.3277212
    25.  
      #> APD 1.0239453
    26.  
      #> AA 1.8593524
    27.  
      #> CF 1.5702493

    或者,我们可以使用矩阵表示法进行拟合,我们定义和扩展因子。然后最小化

    1.  
      t(X) %*% F_ %*% solve(t(F_) %*% F_)
    2.  
       
    3.  
      #> alpha beta
    4.  
      #> AAPL 0.0003999086 1.0957919
    5.  
      #> AMD 0.0013825599 2.1738304
    6.  
      #> ADI 0.0003609968 1.2683047
    7.  
      #> ABBV 0.0006684632 0.9022748
    8.  
      #> AEZS -0.0022091301 1.7115761
    9.  
      #> A 0.0002810616 1.3277212
    10.  
      #> APD 0.0001786375 1.0239453
    11.  
      #> AA 0.0006429140 1.8593524
    12.  
      #> CF -0.0006029705 1.5702493
    13.  
      E <- xts(t(t(X) - Gamma %*% t(F_)), index(X)) # 残差
    14.  
       

    另外,我们可以简单地使用R为我们完成工作:

    1.  
       
    2.  
      cbind(alpha = factor_model$alpha, beta = factor_model$beta)
    3.  
      #> alpha index
    4.  
      #> AAPL 0.0003999086 1.0957919
    5.  
      #> AMD 0.0013825599 2.1738304
    6.  
      #> ADI 0.0003609968 1.2683047
    7.  
      #> ABBV 0.0006684632 0.9022748
    8.  
      #> AEZS -0.0022091301 1.7115761
    9.  
      #> A 0.0002810616 1.3277212
    10.  
      #> APD 0.0001786375 1.0239453
    11.  
      #> AA 0.0006429140 1.8593524
    12.  
      #> CF -0.0006029705 1.5702493

    可视化协方差矩阵

    有趣的是,可视化对数收益率[算术处理误差]以及残差Ψ的估计协方差矩阵。让我们从对数收益率的协方差矩阵开始:

    1.  
       
    2.  
      main = "单因子模型对数收益的协方差矩阵")

    我们可以观察到所有股票都是高度相关的,这是市场因素的影响。为了检查股票相关关系,我们绘制相关图:

    1.  
      plot(cov2cor(Psi),
    2.  
      main = "残差协方差矩阵")

    1.  
       
    2.  
      cbind(stock_namelist, sector_namelist) # 股票的行业
    3.  
      #> stock_namelist sector_namelist
    4.  
      #> [1,] "AAPL" "Information Technology"
    5.  
      #> [2,] "AMD" "Information Technology"
    6.  
      #> [3,] "ADI" "Information Technology"
    7.  
      #> [4,] "ABBV" "Health Care"
    8.  
      #> [5,] "AEZS" "Health Care"
    9.  
      #> [6,] "A" "Health Care"
    10.  
      #> [7,] "APD" "Materials"
    11.  
      #> [8,] "AA" "Materials"
    12.  
      #> [9,] "CF" "Materials"

    有趣的是,我们可以观察到对Ψ执行的自动聚类可以正确识别股票的行业。

    评估投资资金

    在此示例中,我们将基于因子模型评估几种投资基金的绩效。我们将标准普尔500指数作为明确的市场因素,并假设无风险收益为零 rf = 0。特别是,我们考虑六种交易所买卖基金(ETF):

    我们首先加载数据:

    1.  
       
    2.  
       
    3.  
      # 设置开始结束日期和股票名称列表
    4.  
      begin_date <- "2016-10-01"
    5.  
      end_date <- "2017-06-30"
    6.  
       
    7.  
      # 从YahooFinance下载数据
    8.  
      data_set <- xts()
    9.  
      for (stock_index in 1:length(stock_namelist))
    10.  
      data_set <- cbind(data_set, Ad(getSymbols(stock_namelist[stock_index],
    11.  
       
    12.  
      head(data_set)
    13.  
      #> SPY XIVH SPHB SPLV USMV JKD
    14.  
      #> 2016-10-03 203.6610 29.400 31.38322 38.55683 42.88382 119.8765
    15.  
      #> 2016-10-04 202.6228 30.160 31.29729 38.10687 42.46553 119.4081
    16.  
      #> 2016-10-05 203.5195 30.160 31.89880 38.02249 42.37048 119.9421
    17.  
      #> 2016-10-06 203.6610 30.160 31.83196 38.08813 42.39899 120.0826
    18.  
      #> 2016-10-07 202.9626 30.670 31.58372 37.98500 42.35146 119.8296
    19.  
      #> 2016-10-10 204.0197 31.394 31.87970 38.18187 42.56060 120.5978
    20.  
       
    21.  
      head(SP500_index)
    22.  
      #> index
    23.  
      #> 2016-10-03 2161.20
    24.  
      #> 2016-10-04 2150.49
    25.  
      #> 2016-10-05 2159.73
    26.  
      #> 2016-10-06 2160.77
    27.  
      #> 2016-10-07 2153.74
    28.  
      #> 2016-10-10 2163.66
    29.  
       
    30.  
      # 计算股票和SP500指数的对数收益率作为显式因子
    31.  
      X <- diff(log(data_set), na.pad = FALSE)
    32.  
      N <- ncol(X) # 股票数量
    33.  
      T <- nrow(X) # 天数
    34.  
       
    35.  
       

    现在我们可以计算所有ETF的alpha和beta:

    1.  
       
    2.  
      #> alpha beta
    3.  
      #> SPY 7.142225e-05 1.0071424
    4.  
      #> XIVH 1.810392e-03 2.4971086
    5.  
      #> SPHB -2.422107e-04 1.5613533
    6.  
      #> SPLV 1.070918e-04 0.6777149
    7.  
      #> USMV 1.166177e-04 0.6511667
    8.  
      #> JKD 2.569578e-04 0.8883843

    现在可以进行一些观察:

    • SPY是S&P 500的ETF,如预期的那样,其alpha值几乎为零,beta值几乎为1: α= 7.142211×10-5和 β= 1.0071423。
    • XIVH是具有高alpha值的ETF,计算出的alpha值是ETF中最高的(高1-2个数量级): α= 1.810392×10-3。
    • SPHB是一种ETF,据推测具有很高的beta,而计算出的beta却是最高的,但不是最高的:β= 1.5613531。有趣的是,计算出的alpha为负,因此,该ETF应谨慎。
    • SPLV是降低波动性的ETF,实际上,计算得出的beta偏低:β= 0.6777072。
    • USMV还是降低波动性的ETF,实际上,计算出的beta是最低的:β= 0.6511671。
    • JKD显示出很好的折衷。

    我们可以使用一些可视化:

    1.  
       
    2.  
      barplot(rev(alpha), horiz = TRUE, main = "alph

    我们还可以使用例如Sharpe比率,以更系统的比较不同的ETF。回顾一种资产和一个因素的因子模型

    我们获得

    夏普比率如下:

    假设。因此,基于Sharpe比率对不同资产进行排名的一种方法是根据α/β比率对它们进行排名:

    1.  
       
    2.  
      print(ranking)
    3.  
      #> alpha/beta SR alpha beta
    4.  
      #> XIVH 7.249952e-04 0.13919483 1.810392e-03 2.4971086
    5.  
      #> JKD 2.892417e-04 0.17682677 2.569578e-04 0.8883843
    6.  
      #> USMV 1.790904e-04 0.12280053 1.166177e-04 0.6511667
    7.  
      #> SPLV 1.580189e-04 0.10887903 1.070918e-04 0.6777149
    8.  
      #> SPY 7.091574e-05 0.14170591 7.142225e-05 1.0071424
    9.  
      #> SPHB -1.551287e-04 0.07401566 -2.422107e-04 1.5613533

    可以看到:

    • 就α/β而言,XIVH最佳(α最大),而SPHB最差(α负)。
    • 就夏普比率(更确切地说,是信息比率,因为我们忽略了无风险利率)而言,JDK是最好的,其次是SPY。这证实了大多数投资基金的表现不超过市场的观点。
    • 显然,无论以哪种衡量标准,SPHB都是最差的:负α,负β比率和Sharpe比率。
    • JDK之所以能够取得最佳性能,是因为它的alpha值很好(尽管不是最好的),而同时具有0.88的中等beta值。
    • XIVH和SPHB有大量不同的beta,因此在市场上具有极端敞口。
    • USMV在市场上的曝光率最小,有可接受的alpha值,并且其Sharpe比率接近第二和第三高的位置。

    Fama-French三因子模型

    该示例将说明使用标准普尔500指数中的九种股票的Fama-French三因子模型。让我们从加载数据开始:

    1.  
       
    2.  
       
    3.  
      # 设置开始结束日期和股票名称列表
    4.  
      begin_date <- "2013-01-01"
    5.  
      end_date <- "2017-08-31"
    6.  
       
    7.  
      # 从YahooFinance下载数据
    8.  
      data_set <- xts()
    9.  
      for (stock_index in 1:length(stock_namelist))
    10.  
      data_set <- cbind(data_set, Ad(getSymbols(stock_namelist[stock_index],
    11.  
       
    12.  
      # 下载Fama-French因子
    13.  
       
    14.  
       
    15.  
      head(fama_lib)
    16.  
      #> Mkt.RF SMB HML
    17.  
      #> 1926-07-01 0.10 -0.24 -0.28
    18.  
      #> 1926-07-02 0.45 -0.32 -0.08
    19.  
      #> 1926-07-06 0.17 0.27 -0.35
    20.  
      #> 1926-07-07 0.09 -0.59 0.03
    21.  
      #> 1926-07-08 0.21 -0.36 0.15
    22.  
      #> 1926-07-09 -0.71 0.44 0.56
    23.  
      tail(fama_lib)
    24.  
      #> Mkt.RF SMB HML
    25.  
      #> 2017-11-22 -0.05 0.10 -0.04
    26.  
      #> 2017-11-24 0.21 0.02 -0.44
    27.  
      #> 2017-11-27 -0.06 -0.36 0.03
    28.  
      #> 2017-11-28 1.06 0.38 0.84
    29.  
      #> 2017-11-29 0.02 0.04 1.45
    30.  
      #> 2017-11-30 0.82 -0.56 -0.50
    31.  
       
    32.  
      # 计算股票的对数收益率和Fama-French因子
    33.  
      X <- diff(log(data_set), na.pad = FALSE)
    34.  
      N <- ncol(X) #股票数量
    35.  
       
    36.  
       

    现在我们在矩阵F中具有三个因子,并希望拟合模型,其中现在的载荷是一个beta矩阵:。我们可以做最小二乘拟合,最小化。更方便地,我们定义和扩展因子 。然后可以将LS公式写为最小化

    1.  
      print(Gamma)
    2.  
      #> alpha b1 b2 b3
    3.  
      #> AAPL 1.437845e-04 0.9657612 -0.23339130 -0.49806858
    4.  
      #> AMD 6.181760e-04 1.4062105 0.80738336 -0.07240117
    5.  
      #> ADI -2.285017e-05 1.2124008 0.09025928 -0.20739271
    6.  
      #> ABBV 1.621380e-04 1.0582340 0.02833584 -0.72152627
    7.  
      #> AEZS -4.513235e-03 0.6989534 1.31318108 -0.25160182
    8.  
      #> A 1.146100e-05 1.2181429 0.10370898 -0.20487290
    9.  
      #> APD 6.281504e-05 1.0222936 -0.04394061 0.11060938
    10.  
      #> AA -4.587722e-05 1.3391852 0.62590136 0.99858692
    11.  
      #> CF -5.777426e-04 1.0387867 0.48430007 0.82014523

    另外,我们可以使用R完成:

    1.  
      #> alpha Mkt.RF SMB HML
    2.  
      #> AAPL 1.437845e-04 0.9657612 -0.23339130 -0.49806858
    3.  
      #> AMD 6.181760e-04 1.4062105 0.80738336 -0.07240117
    4.  
      #> ADI -2.285017e-05 1.2124008 0.09025928 -0.20739271
    5.  
      #> ABBV 1.621380e-04 1.0582340 0.02833584 -0.72152627
    6.  
      #> AEZS -4.513235e-03 0.6989534 1.31318108 -0.25160182
    7.  
      #> A 1.146100e-05 1.2181429 0.10370898 -0.20487290
    8.  
      #> APD 6.281504e-05 1.0222936 -0.04394061 0.11060938
    9.  
      #> AA -4.587722e-05 1.3391852 0.62590136 0.99858692
    10.  
      #> CF -5.777426e-04 1.0387867 0.48430007 0.82014523

    统计因子模型

    现在让我们考虑统计因子模型或隐式因子模型,其中因子和载荷均不可用。调用具有 K因子的模型 XT =α1T+ BFT + ET的主成分方法:

    1. PCA:
      • 样本均值:
      • 矩阵:
      • 样本协方差矩阵:
      • 特征分解:
    2. 估计:
      •  
    3. 更新特征分解:
    4. 重复步骤2-3,直到收敛为止。
    1.  
      #> alpha
    2.  
      #> AAPL 0.0007074564 0.0002732114 -0.004631647 -0.0044814226
    3.  
      #> AMD 0.0013722468 0.0045782146 -0.035202146 0.0114549515
    4.  
      #> ADI 0.0006533116 0.0004151904 -0.007379066 -0.0053058139
    5.  
      #> ABBV 0.0007787929 0.0017513359 -0.003967816 -0.0056000810
    6.  
      #> AEZS -0.0041576357 0.0769496344 0.002935950 0.0006249473
    7.  
      #> A 0.0006902482 0.0012690079 -0.005680162 -0.0061507654
    8.  
      #> APD 0.0006236565 0.0005442926 -0.004229364 -0.0057976394
    9.  
      #> AA 0.0006277163 0.0027405024 -0.009796620 -0.0149177957
    10.  
      #> CF -0.0000573028 0.0023108605 -0.007409061 -0.0153425661

    同样,我们可以使用R完成工作:

    1.  
      #> alpha factor1 factor2 factor3
    2.  
      #> AAPL 0.0007074564 0.0002732114 -0.004631647 -0.0044814226
    3.  
      #> AMD 0.0013722468 0.0045782146 -0.035202146 0.0114549515
    4.  
      #> ADI 0.0006533116 0.0004151904 -0.007379066 -0.0053058139
    5.  
      #> ABBV 0.0007787929 0.0017513359 -0.003967816 -0.0056000810
    6.  
      #> AEZS -0.0041576357 0.0769496344 0.002935950 0.0006249473
    7.  
      #> A 0.0006902482 0.0012690079 -0.005680162 -0.0061507654
    8.  
      #> APD 0.0006236565 0.0005442926 -0.004229364 -0.0057976394
    9.  
      #> AA 0.0006277163 0.0027405024 -0.009796620 -0.0149177957
    10.  
      #> CF -0.0000573028 0.0023108605 -0.007409061 -0.0153425661

    通过不同因子模型进行协方差矩阵估计的最终比较

    我们最终将比较以下不同的因子模型:

    • 样本协方差矩阵
    • 宏观经济一因素模型
    • 基本的三因素Fama-French模型
    • 统计因素模型

    我们在训练阶段估计模型,然后将估计的协方差矩阵与测试阶段的样本协方差矩阵进行比较。估计误差将根据PRIAL(平均损失提高百分比)进行评估:

    加载训练和测试集:

    1.  
      # 设置开始结束日期和股票名称列表
    2.  
      begin_date <- "2013-01-01"
    3.  
      end_date <- "2015-12-31"
    4.  
       
    5.  
      # 准备股票数据
    6.  
      data_set <- xts()
    7.  
      for (stock_index in 1:length(stock_namelist))
    8.  
      data_set <- cbind(data_set, Ad(getSymbols(stock_namelist[stock_index],
    9.  
       
    10.  
       
    11.  
      # Fama-French 因子
    12.  
      mydata <- mydata[-nrow(mydata),
    13.  
       
    14.  
       
    15.  
      # 准备指数
    16.  
      f_SP500 <- diff(log(SP500_index), na.pad = FALSE)
    17.  
       
    18.  
      # 将数据拆分为训练数据和测试数据
    19.  
      T_trn <- round(0.45*T)
    20.  
      X_trn <- X[1:T_trn, ]
    21.  
      X_tst <- X[(T_trn+1):T, ]

     现在让我们用训练数据估算不同的因子模型:

    1.  
       
    2.  
      # 样本协方差矩阵
    3.  
      Sigma_SCM <- cov(X_trn)
    4.  
       
    5.  
      # 单因素模型
    6.  
      Gamma <- t(solve(t(F_) %*% F_, t(F_) %*% X_trn))
    7.  
       
    8.  
      E <- xts(t(t(X_trn) - Gamma %*% t(F_)), index(X_trn))
    9.  
       
    10.  
      # Fama-French三因子模型
    11.  
       
    12.  
      Sigma_FamaFrench <- B %*% cov(F_FamaFrench_trn) %*% t(B) + diag(diag(Psi))
    13.  
       
    14.  
      # 统计单因子模型
    15.  
       
    16.  
      while (norm(Sigma - Sigma_prev, "F")/norm(Sigma, "F") > 1e-3) {
    17.  
      B <- eigSigma$vectors[, 1:K, drop = FALSE] %*% diag(sqrt(eigSigma$values[1:K]), K, K)
    18.  
       
    19.  
       
    20.  
       
    21.  
      # 统计三因子模型
    22.  
      K <- 3
    23.  
       
    24.  
      while (norm(Sigma - Sigma_prev, "F")/norm(Sigma, "F") > 1e-3) {
    25.  
      B <- eigSigma$vectors[, 1:K] %*% diag(sqrt(eigSigma$values[1:K]), K, K)
    26.  
      Psi <- diag(diag(Sigma - B %*% t(B)))
    27.  
       
    28.  
      Sigma_PCA3 <- Sigma
    29.  
       
    30.  
      # 统计五因子模型
    31.  
      K <- 5
    32.  
       
    33.  
      eigSigma <- eigen(Sigma)
    34.  
      while (norm(Sigma - Sigma_prev, "F")/norm(Sigma, "F") > 1e-3) {
    35.  
      B <- eigSigma$vectors[, 1:K] %*% diag(sqrt(eigSigma$values[1:K]), K, K)
    36.  
      Psi <- diag(diag(Sigma - B %*% t(B)))

    最后,让我们比较测试数据中的不同估计:

    1.  
       
    2.  
      Sigma_true <- cov(X_tst)
    3.  
       
    4.  
      barplot(error, main = "协方差矩阵估计误差",

    
    
    1.  
       
    2.  
      PRIAL <- 100*(ref - error^2)/ref
    3.  
       
    4.  
      barplot(PRIAL, main = "协方差矩阵估计的先验方法",

    最终可以看到使用因子模型进行协方差矩阵估计会有所帮助。


    最受欢迎的见解

    1.用机器学习识别不断变化的股市状况—隐马尔科夫模型(HMM)的应用

    2.R语言GARCH-DCC模型和DCC(MVT)建模估计

    3.R语言实现 Copula 算法建模依赖性案例分析报告

    4.R语言COPULAS和金融时间序列数据VaR分析

    5.R语言多元COPULA GARCH 模型时间序列预测

    6.用R语言实现神经网络预测股票实例

    7.r语言预测波动率的实现:ARCH模型与HAR-RV模型

    8.R语言如何做马尔科夫转换模型markov switching model

    9.matlab使用Copula仿真优化市场风险

    ▍关注我们 【大数据部落】第三方数据服务提供商,提供全面的统计分析与数据挖掘咨询服务,为客户定制个性化的数据解决方案与行业报告等。 ▍咨询链接:http://y0.cn/teradat ▍联系邮箱:3025393450@qq.com
  • 相关阅读:
    使用批处理脚本在win10系统启动Redis 5.0.10
    异常分析 JedisConnectionException: java.net.SocketTimeoutException: Read timed out
    Spring Boot基于redis分布式锁模拟直播秒杀场景
    管理的经验二
    第三方api接口
    接口测试总结
    测试框架的基本能力
    接口测试的价值
    面试的经验
    管理的经验
  • 原文地址:https://www.cnblogs.com/tecdat/p/14418559.html
Copyright © 2011-2022 走看看