【FM】Portfolio Optimization Using Factor Models

实验环境

操作系统:Win 10 64bit
软件:Matlab 2019b (academic use)

模型

在Mean-Variance框架下使用因子模型,多因子模型可以降低计算的矩阵的维度,并且可以解释大部分市场上的随机性信息,这些因子可以是统计意义上,或者是宏观因子或者是基本面因子.

数据预处理

%% 数据预处理
load('asset_return_100_simulated.mat');
[nObs, p]=size(stockReturns);

% 划分训练集和测试集
sp=ceil(nObs*0.6);
train=1:sp;
test=sp+1: nObs;
trainN=numel(train); % 统计训练集中元素的数量

可视化收益曲线

%% 绘制收益率曲线
hold on;
plot(ret2tick(stockReturns{train, 1:5}, 'method', 'simple')*100); %5只资产训练期间的价格
xlabel('Timestep');
ylabel('Value');
title('Equity Curve');
% 设置图例
legend(stockReturns.Properties.VariableNames(1:5), 'Location', 'bestoutside', 'Interpreter', 'none');
hold off;

可视化图像如下
asset

因子模型中计算资产最优化配置

可以直接从资产收益序列中提取统计因子,考虑使用主成分分析(PCA)方法提取统计因子. 在因子模型中, p p p项资产可以用 k k k个因子收益线性组合得到,且 k ≪ p k\ll p kp.
r a = μ a + F r f + ε a r_a=\mu_a+Fr_f+\varepsilon_a ra=μa+Frf+εa
mean-variance模型中,组合风险为
V ( R p ) = V ( r a T w a ) = V ( ( μ a + F r f + ε a ) T w a ) = w a T ( F Σ f F T + D ) w a = w f T Σ f w f + w a T D w a \begin{aligned} \mathbb{V}(R_p)&=\mathbb{V}(r_a^Tw_a)=\mathbb{V}((\mu_a+Fr_f+\varepsilon_a)^Tw_a)\\ &=w_a^T(F\Sigma_f F^T+D)w_a\\ &=w_f^T\Sigma_f w_f+w_a^T Dw_a \end{aligned} V(Rp)=V(raTwa)=V((μa+Frf+εa)Twa)=waT(FΣfFT+D)wa=wfTΣfwf+waTDwa
方程的符号表如下

符号含义
R p R_p Rp组合收益(标量)
r a r_a ra资产收益列向量, p × 1 p\times 1 p×1
μ a \mu_a μa资产收益的均值, p × 1 p\times 1 p×1列向量
F F F因子载荷矩阵, p × k p\times k p×k
r f r_f rf因子收益, k × 1 k\times 1 k×1列向量
ε a \varepsilon_a εa各资产收益中不可被因子解释的部分(idiosyncratic return related to each asset), p × 1 p\times 1 p×1列向量
w a w_a wa资产权重, p × 1 p\times 1 p×1列向量
w f w_f wf因子权重, w f = w a T F w_f=w_a^TF wf=waTF k × 1 k\times 1 k×1列向量
Σ f \Sigma_f Σf因子协方差矩阵, k × k k\times k k×k矩阵
D D D不可解释部分方差(variance of idioisyncratic returns), p × p p\times p p×p对角矩阵

所以可以得到优化问题如下,设置风险上限为 t t t.
max ⁡ μ a T w a s . t . { F T w a = w f w f T Σ f w f + w a T D w a ≤ t 0 ≤ w ≤ 1 e T w a = 1 (1) \begin{aligned} &\max \mu_a^Tw_a\\ &s.t. \begin{cases} F^Tw_a=w_f\\ w_f^T\Sigma_fw_f+w_a^TDw_a\leq t\\ 0\leq w\leq 1\\ e^Tw_a=1 \end{cases} \end{aligned}\tag{1} maxμaTwas.t.FTwa=wfwfTΣfwf+waTDwat0w1eTwa=1(1)

主成分信息提取

p p p项资产形成的 p p p维空间中,PCA算法可以找出其中最重要的 k k k个可以捕获 p p p项资产变化的信息的方向,并且 k < p k<p k<p. 通过PCA算法可以将 p p p项资产的收益分解到 k k k个因子上,这样可以明显地降低问题的维度. k k k个主方向就是因子载荷(factor loadings),回归得到的分数(scores)为因子收益,在本例中令 k = 10 k=10 k=10,也可以通过设置解释阈值来找到合适的 k k k值,一般设置主成分解释95%的方差.

%% pca
k=10; % 设置主方向为10[factor_loading, factor_ret, latent, tsq, explained, mu]=pca(stockReturns{train, :}, 'NumComponents', k);
disp(size(factor_loading));
disp(size(factor_ret));

输出得到 p × k p\times k p×k的因子载荷矩阵factor_loading,每一列是一个主成分(pricinpal component),每个时间戳的资产收益向量被分解到这 k k k维空间中,输出 trainN × k \text{trainN}\times k trainN×kfactor_ret矩阵.
估计因子方差-协方差矩阵

covarFactor=cov(factor_ret);

根据公式 r a = μ a + F r f + ε a r_a=\mu_a+Fr_f+\varepsilon_a ra=μa+Frf+εa重构训练集样本点收益序列

recon_ret=factor_ret*factor_loading'+mu; % 收益序列重构
unexplained_ret=stockReturns{train, :}-recon_ret; % 因子模型不可解释部分

产生因子模型不可解释部分收益 ε a \varepsilon_a εa因为pca算法舍弃了 p − k p-k pk个成分,这一部分信息可以用矩阵 D D D表示

unexplained_covar=diag(cov(unexplained_ret));
D=diag(unexplained_covar);

最优模型建模计算

根据方程组 ( 1 ) (1) (1)建立最优化模型

%% optimization model
t_std=0.007; % 组合标准差
t_risk=t_std*t_std; % 组合方差
mean_ret = mean(stockReturns{train, :}); % 训练期均值

% 定义最优化问题
% 目标函数为求最大化
optimProb=optimproblem('Description', 'Portfolio with factor covariance matrix', 'ObjectiveSense', 'max');
% 变量:资产权重(p * 1)向量和因子权重(k*1)向量
wgtAsset=optimvar('asset_weight', p, 1, 'Type', 'continuous', 'LowerBound', 0, 'UpperBound', 1);
wgtFactor=optimvar('factor_weight', k, 1, 'Type', 'continuous');
% 优化目标为组合收益
optimProb.Objective=sum(mean_ret' .*wgtAsset);
% 约束
% w_f和w_a之间的关系
optimProb.Constraints.asset_factor_weight=factor_loading'*wgtAsset-wgtFactor==0;
% 风险约束
optimProb.Constraints.risk=wgtFactor'*covarFactor*wgtFactor+wgtAsset'*D*wgtAsset<=t_risk;
% budget
optimProb.Constraints.budget=sum(wgtAsset)==1;

% 初始值
x0.asset_weight=ones(p, 1)/p;
x0.factor_weight=zeros(k, 1);
% 优化算法设置
opt=optimoptions("fmincon", "Algorithm", "sqp", "Display", "off", 'ConstraintTolerance', 1.0e-8, 'OptimalityTolerance', 1.0e-8, ...
    'StepTolerance', 1.0e-8);
% 求解
x=solve(optimProb, x0, "Options", opt);
assetWgt1=x.asset_weight;

对投资比重大于5%的资产进行列表显示

%% check portfolio
tol = 0.05;
asset_names=stockReturns.Properties.VariableNames(assetWgt1>=tol)';
weights = assetWgt1(assetWgt1>=tol);
T1=table(asset_names, weights)

t1

使用portfolio类进行计算

如果已经得到因子载荷矩阵( F F F)和因子方差-协方差矩阵 Σ f \Sigma_f Σf,可以直接使用这些信息调用Portfolio Classmean-variance框架下进行计算.

%%  optimize by Portfolio class with Factor information
covarAsset=factor_loading*covarFactor*factor_loading'+D;
port=Portfolio('AssetMean', mean_ret, 'AssetCovar', covarAsset, 'lowerbound', 0, 'upperbound', 1, 'budget', 1);
assetWgt2=estimateFrontierByRisk(port, t_risk);
asset_names_2=stockReturns.Properties.VariableNames(assetWgt2>=tol)';
weights_2=assetWgt2(assetWgt2>=tol);
T2=table(asset_names_2, weights_2)

得到组合权重分布如下表所示
vt

测试集表现

将得到的组合权重在测试期数据进行回测

%% test period data
t_ret_1=stockReturns{test, :}*assetWgt1;
t_ret_2=stockReturns{test, :}*assetWgt2;
hold on;
t1=plot(ret2tick(t_ret_1, 'method', 'simple')*100);
t2=plot(ret2tick(t_ret_2, 'method', 'simple')*100);
xlabel('TimeStep');
ylabel('Value');
legend([t1, t2], "factor model 1", "factor model 2");
title('Portfolio Equity Curve');
hold off;

回测结果如图所示
port_test

后记

本实验的因子载荷矩阵由PCA算法直接得到,如果需要显式计算需要线性回归的方法.

代码下载

pca_factor_model

参考资料

Portfolio Optimization Using Factor Models
sklearn中的pca算法库函数
matlab中的pca算法包
First Choose Problem-Based or Solver-Based Approach
Portfolio set for optimizaiton using portfolio object

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Quant0xff

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值