共计 9301 个字符,预计需要花费 24 分钟才能阅读完成。
原文链接:http://tecdat.cn/?p=20360
本文将阐明金融数学中的 R 语言优化投资组合,因子模型的实现和应用。
具备繁多市场因素的宏观经济因素模型
咱们将从一个蕴含单个已知因子(即市场指数)的简略示例开始。该模型为
其中显式因子 ft 为 S&P 500 指数。咱们将做一个简略的最小二乘(LS)回归来预计截距 α 和加载 β:
大多数代码行用于筹备数据,而不是执行因子建模。让咱们开始筹备数据:
# 设置开始完结日期和股票名称列表
begin_date <- "2016-01-01"
end_date <- "2017-12-31"
# 从 YahooFinance 下载数据
data_set <- xts()
for (stock_index in 1:length(stock_namelist))
data_set <- cbind(data_set, Ad(getSymbols(stock_namelist[stock_index],
from = begin_date, to = end_date,
head(data_set)
#> AAPL AMD ADI ABBV AEZS A APD AA CF
#> 2016-01-04 98.74225 2.77 49.99239 49.46063 4.40 39.35598 107.89010 23.00764 35.13227
#> 2016-01-05 96.26781 2.75 49.62508 49.25457 4.21 39.22057 105.96097 21.96506 34.03059
#> 2016-01-06 94.38389 2.51 47.51298 49.26315 3.64 39.39467 103.38042 20.40121 31.08988
#> 2016-01-07 90.40047 2.28 46.30082 49.11721 3.29 37.72138 99.91463 19.59558 29.61520
#> 2016-01-08 90.87848 2.14 45.89677 47.77789 3.29 37.32482 99.39687 19.12169 29.33761
#> 2016-01-11 92.35001 2.34 46.98954 46.25827 3.13 36.69613 99.78938 18.95583 28.14919
head(SP500_index)
#> index
#> 2016-01-04 2012.66
#> 2016-01-05 2016.71
#> 2016-01-06 1990.26
#> 2016-01-07 1943.09
#> 2016-01-08 1922.03
#> 2016-01-11 1923.67
plot(SP500_index)
# 计算股票和 SP500 指数的对数收益率作为显式因子
X <- diff(log(data_set), na.pad = FALSE)
N <- ncol(X) # 股票数量
T <- nrow(X) # 天数
当初咱们筹备进行因子模型拟合。LS 拟合很容易在 R 中实现,如下所示:
beta <- cov(X,f)/as.numeric(var(f))
alpha <- colMeans(X) - beta*colMeans(f)
sigma2 <- rep(NA, N)
print(alpha)
#> index
#> AAPL 0.0003999086
#> AMD 0.0013825599
#> ADI 0.0003609968
#> ABBV 0.0006684632
#> AEZS -0.0022091301
#> A 0.0002810616
#> APD 0.0001786375
#> AA 0.0006429140
#> CF -0.0006029705
print(beta)
#> index
#> AAPL 1.0957919
#> AMD 2.1738304
#> ADI 1.2683047
#> ABBV 0.9022748
#> AEZS 1.7115761
#> A 1.3277212
#> APD 1.0239453
#> AA 1.8593524
#> CF 1.5702493
或者,咱们能够应用矩阵表示法进行拟合 ,咱们定义 和扩大因子 。而后最小化
t(X) %*% F_ %*% solve(t(F_) %*% F_)
#> alpha beta
#> AAPL 0.0003999086 1.0957919
#> AMD 0.0013825599 2.1738304
#> ADI 0.0003609968 1.2683047
#> ABBV 0.0006684632 0.9022748
#> AEZS -0.0022091301 1.7115761
#> A 0.0002810616 1.3277212
#> APD 0.0001786375 1.0239453
#> AA 0.0006429140 1.8593524
#> CF -0.0006029705 1.5702493
E <- xts(t(t(X) - Gamma %*% t(F_)), index(X)) # 残差
另外,咱们能够简略地应用 R 为咱们实现工作:
cbind(alpha = factor_model$alpha, beta = factor_model$beta)
#> alpha index
#> AAPL 0.0003999086 1.0957919
#> AMD 0.0013825599 2.1738304
#> ADI 0.0003609968 1.2683047
#> ABBV 0.0006684632 0.9022748
#> AEZS -0.0022091301 1.7115761
#> A 0.0002810616 1.3277212
#> APD 0.0001786375 1.0239453
#> AA 0.0006429140 1.8593524
#> CF -0.0006029705 1.5702493
可视化协方差矩阵
乏味的是,可视化对数收益率 [算术解决误差]以及残差 Ψ 的预计协方差矩阵。让咱们从对数收益率的协方差矩阵开始:
main = "单因子模型对数收益的协方差矩阵")
咱们能够察看到所有股票都是高度相干的,这是市场因素的影响。为了查看股票相干关系,咱们绘制相干图:
plot(cov2cor(Psi),
main = "残差协方差矩阵")
cbind(stock_namelist, sector_namelist) # 股票的行业
#> stock_namelist sector_namelist
#> [1,] "AAPL" "Information Technology"
#> [2,] "AMD" "Information Technology"
#> [3,] "ADI" "Information Technology"
#> [4,] "ABBV" "Health Care"
#> [5,] "AEZS" "Health Care"
#> [6,] "A" "Health Care"
#> [7,] "APD" "Materials"
#> [8,] "AA" "Materials"
#> [9,] "CF" "Materials"
乏味的是,咱们能够察看到对 Ψ 执行的主动聚类能够正确辨认股票的行业。
评估投资资金
在此示例中,咱们将基于因子模型评估几种投资基金的绩效。咱们将规范普尔 500 指数作为明确的市场因素,并假如无风险收益为零 rf = 0。特地是,咱们思考六种交易所交易基金(ETF):
咱们首先加载数据:
# 设置开始完结日期和股票名称列表
begin_date <- "2016-10-01"
end_date <- "2017-06-30"
# 从 YahooFinance 下载数据
data_set <- xts()
for (stock_index in 1:length(stock_namelist))
data_set <- cbind(data_set, Ad(getSymbols(stock_namelist[stock_index],
head(data_set)
#> SPY XIVH SPHB SPLV USMV JKD
#> 2016-10-03 203.6610 29.400 31.38322 38.55683 42.88382 119.8765
#> 2016-10-04 202.6228 30.160 31.29729 38.10687 42.46553 119.4081
#> 2016-10-05 203.5195 30.160 31.89880 38.02249 42.37048 119.9421
#> 2016-10-06 203.6610 30.160 31.83196 38.08813 42.39899 120.0826
#> 2016-10-07 202.9626 30.670 31.58372 37.98500 42.35146 119.8296
#> 2016-10-10 204.0197 31.394 31.87970 38.18187 42.56060 120.5978
head(SP500_index)
#> index
#> 2016-10-03 2161.20
#> 2016-10-04 2150.49
#> 2016-10-05 2159.73
#> 2016-10-06 2160.77
#> 2016-10-07 2153.74
#> 2016-10-10 2163.66
# 计算股票和 SP500 指数的对数收益率作为显式因子
X <- diff(log(data_set), na.pad = FALSE)
N <- ncol(X) # 股票数量
T <- nrow(X) # 天数
当初咱们能够计算所有 ETF 的 alpha 和 beta:
#> alpha beta
#> SPY 7.142225e-05 1.0071424
#> XIVH 1.810392e-03 2.4971086
#> SPHB -2.422107e-04 1.5613533
#> SPLV 1.070918e-04 0.6777149
#> USMV 1.166177e-04 0.6511667
#> 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 显示出很好的折衷。
咱们能够应用一些可视化:
barplot(rev(alpha), horiz = TRUE, main = "alph
咱们还能够应用例如 Sharpe 比率,以更零碎的比拟不同的 ETF。回顾一种资产和一个因素的因子模型
咱们取得
夏普比率如下:
假如 。因而,基于 Sharpe 比率对不同资产进行排名的一种办法是依据 α / β 比率对它们进行排名:
print(ranking)
#> alpha/beta SR alpha beta
#> XIVH 7.249952e-04 0.13919483 1.810392e-03 2.4971086
#> JKD 2.892417e-04 0.17682677 2.569578e-04 0.8883843
#> USMV 1.790904e-04 0.12280053 1.166177e-04 0.6511667
#> SPLV 1.580189e-04 0.10887903 1.070918e-04 0.6777149
#> SPY 7.091574e-05 0.14170591 7.142225e-05 1.0071424
#> 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 三因子模型。让咱们从加载数据开始:
# 设置开始完结日期和股票名称列表
begin_date <- "2013-01-01"
end_date <- "2017-08-31"
# 从 YahooFinance 下载数据
data_set <- xts()
for (stock_index in 1:length(stock_namelist))
data_set <- cbind(data_set, Ad(getSymbols(stock_namelist[stock_index],
# 下载 Fama-French 因子
head(fama_lib)
#> Mkt.RF SMB HML
#> 1926-07-01 0.10 -0.24 -0.28
#> 1926-07-02 0.45 -0.32 -0.08
#> 1926-07-06 0.17 0.27 -0.35
#> 1926-07-07 0.09 -0.59 0.03
#> 1926-07-08 0.21 -0.36 0.15
#> 1926-07-09 -0.71 0.44 0.56
tail(fama_lib)
#> Mkt.RF SMB HML
#> 2017-11-22 -0.05 0.10 -0.04
#> 2017-11-24 0.21 0.02 -0.44
#> 2017-11-27 -0.06 -0.36 0.03
#> 2017-11-28 1.06 0.38 0.84
#> 2017-11-29 0.02 0.04 1.45
#> 2017-11-30 0.82 -0.56 -0.50
# 计算股票的对数收益率和 Fama-French 因子
X <- diff(log(data_set), na.pad = FALSE)
N <- ncol(X) #股票数量
当初咱们在矩阵 F 中具备三个因子,并心愿拟合模型 ,其中当初的载荷是一个 beta 矩阵:。咱们能够做最小二乘拟合,最小化 。更不便地,咱们定义 和扩大因子 。而后能够将 LS 公式写为最小化
print(Gamma)
#> alpha b1 b2 b3
#> AAPL 1.437845e-04 0.9657612 -0.23339130 -0.49806858
#> AMD 6.181760e-04 1.4062105 0.80738336 -0.07240117
#> ADI -2.285017e-05 1.2124008 0.09025928 -0.20739271
#> ABBV 1.621380e-04 1.0582340 0.02833584 -0.72152627
#> AEZS -4.513235e-03 0.6989534 1.31318108 -0.25160182
#> A 1.146100e-05 1.2181429 0.10370898 -0.20487290
#> APD 6.281504e-05 1.0222936 -0.04394061 0.11060938
#> AA -4.587722e-05 1.3391852 0.62590136 0.99858692
#> CF -5.777426e-04 1.0387867 0.48430007 0.82014523
另外,咱们能够应用 R 实现:
#> alpha Mkt.RF SMB HML
#> AAPL 1.437845e-04 0.9657612 -0.23339130 -0.49806858
#> AMD 6.181760e-04 1.4062105 0.80738336 -0.07240117
#> ADI -2.285017e-05 1.2124008 0.09025928 -0.20739271
#> ABBV 1.621380e-04 1.0582340 0.02833584 -0.72152627
#> AEZS -4.513235e-03 0.6989534 1.31318108 -0.25160182
#> A 1.146100e-05 1.2181429 0.10370898 -0.20487290
#> APD 6.281504e-05 1.0222936 -0.04394061 0.11060938
#> AA -4.587722e-05 1.3391852 0.62590136 0.99858692
#> CF -5.777426e-04 1.0387867 0.48430007 0.82014523
统计因子模型
当初让咱们思考统计因子模型或隐式因子模型,其中因子和载荷均不可用。调用具备 K 因子的模型 XT =α1T+ BFT + ET 的主成分办法:
-
PCA:
- 样本均值:
- 矩阵:
- 样本协方差矩阵:
- 特色合成:
-
预计:
-
-
-
- 更新特色合成:
- 反复步骤 2 -3,直到收敛为止。
#> alpha
#> AAPL 0.0007074564 0.0002732114 -0.004631647 -0.0044814226
#> AMD 0.0013722468 0.0045782146 -0.035202146 0.0114549515
#> ADI 0.0006533116 0.0004151904 -0.007379066 -0.0053058139
#> ABBV 0.0007787929 0.0017513359 -0.003967816 -0.0056000810
#> AEZS -0.0041576357 0.0769496344 0.002935950 0.0006249473
#> A 0.0006902482 0.0012690079 -0.005680162 -0.0061507654
#> APD 0.0006236565 0.0005442926 -0.004229364 -0.0057976394
#> AA 0.0006277163 0.0027405024 -0.009796620 -0.0149177957
#> CF -0.0000573028 0.0023108605 -0.007409061 -0.0153425661
同样,咱们能够应用 R 实现工作:
#> alpha factor1 factor2 factor3
#> AAPL 0.0007074564 0.0002732114 -0.004631647 -0.0044814226
#> AMD 0.0013722468 0.0045782146 -0.035202146 0.0114549515
#> ADI 0.0006533116 0.0004151904 -0.007379066 -0.0053058139
#> ABBV 0.0007787929 0.0017513359 -0.003967816 -0.0056000810
#> AEZS -0.0041576357 0.0769496344 0.002935950 0.0006249473
#> A 0.0006902482 0.0012690079 -0.005680162 -0.0061507654
#> APD 0.0006236565 0.0005442926 -0.004229364 -0.0057976394
#> AA 0.0006277163 0.0027405024 -0.009796620 -0.0149177957
#> CF -0.0000573028 0.0023108605 -0.007409061 -0.0153425661
通过不同因子模型进行协方差矩阵预计的最终比拟
咱们最终将比拟以下不同的因子模型:
- 样本协方差矩阵
- 宏观经济一因素模型
- 根本的三因素 Fama-French 模型
- 统计因素模型
咱们在训练阶段预计模型,而后将预计的协方差矩阵与测试阶段的样本协方差矩阵进行比拟。预计误差将依据 PRIAL(均匀损失进步百分比)进行评估:
加载训练和测试集:
# 设置开始完结日期和股票名称列表
begin_date <- "2013-01-01"
end_date <- "2015-12-31"
# 筹备股票数据
data_set <- xts()
for (stock_index in 1:length(stock_namelist))
data_set <- cbind(data_set, Ad(getSymbols(stock_namelist[stock_index],
# Fama-French 因子
mydata <- mydata[-nrow(mydata),
# 筹备指数
f_SP500 <- diff(log(SP500_index), na.pad = FALSE)
# 将数据拆分为训练数据和测试数据
T_trn <- round(0.45*T)
X_trn <- X[1:T_trn,]
X_tst <- X[(T_trn+1):T, ]
当初让咱们用训练数据估算不同的因子模型:
# 样本协方差矩阵
Sigma_SCM <- cov(X_trn)
# 单因素模型
Gamma <- t(solve(t(F_) %*% F_, t(F_) %*% X_trn))
E <- xts(t(t(X_trn) - Gamma %*% t(F_)), index(X_trn))
# Fama-French 三因子模型
Sigma_FamaFrench <- B %*% cov(F_FamaFrench_trn) %*% t(B) + diag(diag(Psi))
# 统计单因子模型
while (norm(Sigma - Sigma_prev, "F")/norm(Sigma, "F") > 1e-3) {B <- eigSigma$vectors[, 1:K, drop = FALSE] %*% diag(sqrt(eigSigma$values[1:K]), K, K)
# 统计三因子模型
K <- 3
while (norm(Sigma - Sigma_prev, "F")/norm(Sigma, "F") > 1e-3) {B <- eigSigma$vectors[, 1:K] %*% diag(sqrt(eigSigma$values[1:K]), K, K)
Psi <- diag(diag(Sigma - B %*% t(B)))
Sigma_PCA3 <- Sigma
# 统计五因子模型
K <- 5
eigSigma <- eigen(Sigma)
while (norm(Sigma - Sigma_prev, "F")/norm(Sigma, "F") > 1e-3) {B <- eigSigma$vectors[, 1:K] %*% diag(sqrt(eigSigma$values[1:K]), K, K)
Psi <- diag(diag(Sigma - B %*% t(B)))
最初,让咱们比拟测试数据中的不同预计:
Sigma_true <- cov(X_tst)
barplot(error, main = "协方差矩阵预计误差",
PRIAL <- 100*(ref - error^2)/ref
barplot(PRIAL, main = "协方差矩阵预计的先验办法",
最终能够看到应用因子模型进行协方差矩阵预计会有所帮忙。