如何在R中实现带系数约束的OLS多元回归(有效资产混合分析)
方法背景
该方法最早由Sharpe(1988、1992)提出,最初命名为有效资产混合分析(Effective Asset Mix Analysis),核心应用场景为:给定单只基金的收益率时间序列,求解与基金收益率拟合度最高的市场指数配置权重组合。
模型定义
数学表达式
$$R_t = \sum_{j=1}^N W_j * R_{jt} + \varepsilon_t$$
参数说明
- $R_t$:基金在第t期的收益率
- $W_j$:第j个市场指数的配置权重
- $R_{jt}$:第j个市场指数在第t期的收益率
- $N$:纳入模型的市场指数总数量
- $\varepsilon_t$:第t期的模型残差项
硬约束条件
模型需要满足两类强制约束:
- 权重和约束:所有指数权重之和$\sum W_j = 1$
- 权重区间约束:单个指数权重满足取值范围$0 < W_j < 1$
本次建模需求
本次待构建的是带约束的多元线性回归,无约束版本的R代码形式为:lm(Return~RMRF+SMB+HML+RMW+CMA+WML)
对应6个因子的权重$W_1$到$W_6$需要满足:
- 权重和约束:$W_1+W_2+W_3+W_4+W_5+W_6 = 1$
- 区间约束:$0<W_1<1、0<W_2<1、0<W_3<1、0<W_4<1、0<W_5<1、0<W_6<1$
测试数据集
已构造完成的测试数据集R代码如下:
RMRF<-seq(0.1, 0.38, 0.01) SMB<-seq(0.567, 3.43, 0.1) HML<-c(0.2779847, 8.0264832, 5.3220615, 6.0018334, -1.6453088, 0.8797469, -11.7401832, 6.6918100, 13.4933761, 29.4326627, 15.4784988, 12.7620389, 8.6609398, 13.5182957, 10.5642555, 16.2769744, 10.5017521, 6.8056429, 4.2213311, 3.9782718, 3.0807381, -1.1463134, -1.6779659, 2.1594784, 0.3175780, -1.3537170, -6.0749482, -14.1179519, -7.1843946) CMA<-c(4.4861560, 5.2225740, 5.0143182, 4.3095509, -4.6995774, -5.9131464 ,-18.6426615, -8.4720251 , -8.8441047, 7.9143735, 4.7228250, 2.3323631, 0.7291851, 0.2228563, 4.5186684, 15.2056919, 8.6473266, 6.9853941, -3.5298969, 2.9377347, 1.0234615, 1.2489909, 0.4876903, 0.2682861, 0.4223881, -1.2420955, -2.7008911, -8.7600239, -4.3200991) WML<-c(1.2652667, -4.9939866, -9.3409655, -7.8398924, 7.5834817, 5.2052111, 26.1681918, -0.7340554, 14.2993323, -4.7537949, -0.6015832, -5.6729850, 1.0444217, 7.7401486, 8.1841650, 8.3217436, -4.9279098, -8.8318481, -13.0344319, 1.1946743, 7.6068103, 4.7373327, 4.3619793, -5.6985077, -1.1614607, -2.7103998, -0.6407941, -1.7205889, -3.5596958) Return<-c(0.254833800, 0.529037900, 0.515281900, -0.051242010, -1.086244000, -0.244727100, 0.011298250, -0.006221349, -0.624509200, -0.816637000, 0.292818100, 0.813584700, 0.279639600, -0.325332300, -0.427709900, -0.486177300, 0.156662800, 0.834633400, 0.710158400, 0.502986200, -0.066646120, -0.581395500, -0.511287100, 0.335159300, 0.661496000, 0.439663200, 0.489402600, 0.053834020, 0.079386050) RMW<-seq(0.06, 0.34, 0.01) library(data.table) table<-data.table(Return, RMRF, HML, CMA, SMB, WML, RMW)
R实现方案
基础lm()函数不支持同时带线性等式约束和变量区间约束的回归,Sharpe风格分析的标准实现是将问题转化为二次规划求解,这里用quadprog包完成计算。
实现步骤
- 安装并加载依赖包
# 首次运行先执行安装 install.packages("quadprog") library(quadprog)
- 构造二次规划输入矩阵
带约束最小二乘的目标是最小化残差平方和$||Y - X\beta||^2$,可以转化为标准二次规划形式:$\min_\beta \frac{1}{2}\beta^T D \beta - d^T \beta$,其中$D = 2XTX$,$d=2XTY$。
# 提取自变量矩阵,风格分析默认不带截距项 X <- as.matrix(table[, .(RMRF, SMB, HML, RMW, CMA, WML)]) # 提取因变量(基金收益率) Y <- table$Return # 生成二次规划核心矩阵 Dmat <- 2 * t(X) %*% X dvec <- 2 * t(X) %*% Y
- 配置约束条件
所有约束统一整理为$Amat^T \beta \geq bvec$的形式:
- 权重和为1的等式约束:拆成$\sum W_j \geq1$和$-\sum W_j \geq -1$两个不等式实现
- 权重开区间约束:用极小偏移量
1e-8避开边界值,满足$0<W_j<1$的要求
# 构造约束矩阵 Amat <- cbind( # 权重和等于1的两个方向约束 rep(1, 6), rep(-1, 6), # 所有权重大于0的约束 diag(6), # 所有权重小于1的约束 -diag(6) ) # 构造约束阈值向量 bvec <- c(1, -1, rep(1e-8, 6), rep(-1 + 1e-8, 6))
- 求解并提取结果
# 求解二次规划问题 sol <- solve.QP(Dmat = Dmat, dvec = dvec, Amat = Amat, bvec = bvec, meq=0) # 提取各因子权重 weights <- setNames(sol$solution, c("RMRF", "SMB", "HML", "RMW", "CMA", "WML")) # 计算模型拟合优度R² y_pred <- X %*% weights r2 <- 1 - sum((Y - y_pred)^2)/sum((Y - mean(Y))^2)
注意事项
- 输出的
weights就是满足所有约束的因子权重,权重和严格等于1,所有权重落在(0,1)开区间内 r2是模型拟合优度,代表所选因子组合对基金收益率的解释比例- 如果运行提示约束不可行,说明当前因子池无法在要求的权重区间内满足权重和为1的约束,需要调整因子范围或者适当放宽约束条件。
内容的提问来源于stack exchange,提问作者Christina
相关产品推荐
相关产品推荐

