尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

MATLAB实战:均值-方差模型与投资组合优化,从理论到有效前沿绘制

MATLAB实战:均值-方差模型与投资组合优化,从理论到有效前沿绘制 1. 从一道经典赛题说起当收益与风险成为跷跷板如果你参加过数学建模竞赛或者接触过投资组合优化大概率见过这样一类问题给你一堆资产比如股票、基金告诉你它们的历史收益率和风险比如波动率然后让你决定怎么分配手里的钱才能在控制风险的前提下获得尽可能高的收益。这听起来像是一个金融问题但它的内核其实是一个经典的数学优化问题在物流调度、资源分配、工程设计里都能找到它的影子。我第一次被这个问题“折磨”是在准备一场建模比赛的时候。题目给了一组基金的历史数据要求我们构建一个投资方案。当时团队里三个人一个负责查文献一个负责写论文而我负责用MATLAB把模型“跑”出来。本以为有了数据和模型公式敲几行代码就能出结果结果却卡在了“怎么让MATLAB听懂我们的优化需求”上。是追求收益最大化不顾风险还是把风险压到最低但收益惨淡又或者在两者之间找一个平衡点这个寻找“平衡点”的过程就是数学建模的魅力也是MATLAB这类工具大显身手的地方。今天我们就来彻底拆解这个“收益与风险”问题。我不会只给你一个冰冷的公式或者一段看不懂的代码而是想和你分享如何像解一道复杂的工程应用题一样用MATLAB的思维一步步把实际问题转化为数学模型再让计算机为我们找出那个“最优解”。你会发现核心的算法可能就那几种但如何根据问题背景选择模型、处理数据、解读结果才是真正体现功力的地方。2. 问题本质与模型选择不只是“选哪个公式”面对收益和风险问题新手最容易犯的错误是直接上网搜“投资组合MATLAB代码”然后套用。这往往会导致模型与实际问题脱节结果看起来漂亮却无法解释。我们得先回到问题的本质。2.1 明确优化目标与约束我们要“优化”什么任何优化问题都离不开三要素决策变量、目标函数、约束条件。在我们这个场景下决策变量通常就是我们对各个资产的资金分配比例。假设有n个资产那么决策变量就是一个n维向量x [x1, x2, ..., xn]其中xi代表投资于第i个资产的比例且所有xi之和为1资金全部投出。目标函数这是我们想要最大化或最小化的东西。这里就出现了第一个分叉路口最大化收益目标函数 投资组合的期望收益率。这很简单但结果往往是把所有钱押注在历史收益最高的那个资产上风险极高。最小化风险目标函数 投资组合的方差或标准差。这很保守结果可能是一个极度分散的组合收益很低。多目标优化我们既想要高收益又想要低风险。这才是现实情况。但一个函数无法同时最大化又最小化两个东西这就需要引入新的建模思路。约束条件除了资金总和为1还可能包括不允许卖空即xi 0、对某个行业或资产有投资上限xi 0.1、要求最低收益水平等。2.2 核心模型均值-方差模型及其变体1952年马科维茨提出的均值-方差模型是处理这类问题的基石。它的聪明之处在于将多目标问题转化为了单目标优化问题。主要有两种转化方式给定风险水平最大化收益设定一个你所能承受的最大风险值比如组合方差不超过某个数sigma_max然后在这个约束下寻找期望收益最高的组合。max 期望收益 s.t. 组合方差 sigma_max 资金分配和为1 其他约束如非负给定收益水平最小化风险设定一个你期望的最低收益return_min然后寻找风险最小的组合来实现它。min 组合方差 s.t. 期望收益 return_min 资金分配和为1 其他约束如非负效用函数法/目标规划法这是更贴近我们“权衡”思维的方法。它引入一个风险厌恶系数lambdaλ将目标函数构建为收益 - λ * 风险。通过调节λ你就在调节心中那杆秤λ0时你只关心收益是极端冒险者λ很大时你极度厌恶风险是保守派。这个模型的形式是max 期望收益 - λ * 组合方差 s.t. 资金分配和为1 其他约束为什么我推荐初学者从这个模型入手因为它最直观。你可以通过改变一个参数λ生成一系列从激进到保守的投资组合从而清晰地看到收益与风险之间的“交换关系”。这条曲线就是著名的有效前沿。实操心得在比赛或实际分析中我通常会同时采用第2种给定收益求最小风险和第3种效用函数法来互相验证。先用效用函数法扫描不同的λ画出有效前沿的大致形状。然后针对几个关键的收益目标点例如年化5%8%10%使用第2种模型精确计算其对应的最小风险组合。这样既能全局把握又能对关键点进行精准分析。3. MATLAB实战从数据到有效前沿理论说得再多不如一行代码。我们假设已经有了10个资产过去60个月的月度收益率数据存储在一个60×10的矩阵returns中。现在我们用MATLAB来找到它的有效前沿。3.1 数据准备与基础计算这是所有分析的地基务必扎实。% 假设 returns 是一个 60x10 的矩阵每一列代表一个资产的时间序列收益率 % 计算每个资产的期望收益率均值 expectedReturns mean(returns); % 计算资产之间的协方差矩阵 covarianceMatrix cov(returns); % 资产数量 numAssets size(returns, 2);关键点解释mean(returns)计算每列每个资产的均值加转置是为了将其变成列向量方便后续计算。cov(returns)是核心。这个10×10的协方差矩阵对角线上的值是每个资产的方差自身风险非对角线上的值是资产两两之间的协方差衡量它们的联动性。分散化投资降低风险靠的就是利用资产间非完全正相关的协方差。3.2 构建并求解优化问题以效用函数法为例我们将使用MATLAB强大的优化工具箱。这里以fmincon这个求解器为例它用于求解有约束的非线性优化问题。% 定义风险厌恶系数的范围生成一组λ值 lambdaValues logspace(-3, 3, 50); % 从10^-3到10^3生成50个对数间隔的值 % 初始化存储结果的矩阵 portfolioWeights zeros(numAssets, length(lambdaValues)); portfolioReturn zeros(1, length(lambdaValues)); portfolioRisk zeros(1, length(lambdaValues)); % 定义优化问题的约束权重之和为1且非负不允许卖空 Aeq ones(1, numAssets); % 等式约束的系数矩阵所有权重和为1 beq 1; % 等式约束的右侧值1 lb zeros(numAssets, 1); % 权重的下界0 ub []; % 权重的上界无或可根据需要设置如 ub ones(numAssets, 1)*0.3 % 初始猜测解均匀分布 x0 ones(numAssets, 1) / numAssets; % 遍历每一个风险厌恶系数λ for i 1:length(lambdaValues) lambda lambdaValues(i); % 定义目标函数负的效用函数因为fmincon默认求最小值 % 效用 收益 - λ * 风险求最大等价于求负效用的最小 objectiveFunc (x) -(x * expectedReturns - lambda * (x * covarianceMatrix * x)); % 调用fmincon求解器 options optimoptions(fmincon, Display, off, Algorithm, interior-point); [x_opt, ~] fmincon(objectiveFunc, x0, [], [], Aeq, beq, lb, ub, [], options); % 存储结果 portfolioWeights(:, i) x_opt; portfolioReturn(i) x_opt * expectedReturns; portfolioRisk(i) sqrt(x_opt * covarianceMatrix * x_opt); % 标准差作为风险度量 end代码逐段解读logspace生成λ值因为风险厌恶系数的影响范围可能很大用对数间隔采样更合理能更好地捕捉有效前沿的细节。约束定义Aeq*x beq定义了sum(x) 1。lb定义了x 0。目标函数句柄(x) ...这是MATLAB中定义匿名函数的方式。x是决策变量。注意我们求的是-效用的最小值等价于求效用的最大值。optimoptions设置优化选项。Display, off关闭迭代信息让输出更干净。Algorithm, interior-point指定使用内点法对于这类中等规模的凸优化问题通常很有效。结果计算portfolioReturn是组合期望收益x * expectedReturns。portfolioRisk是组合标准差sqrt(x * covarianceMatrix * x)它比方差更直观与收益率单位匹配。3.3 可视化绘制有效前沿结果出来了但一堆数字不直观。让我们把它画出来。% 绘制有效前沿 figure(Position, [100, 100, 800, 600]) plot(portfolioRisk, portfolioReturn, b-, LineWidth, 2); hold on; scatter(portfolioRisk, portfolioReturn, 30, lambdaValues, filled); xlabel(投资组合风险标准差); ylabel(投资组合期望收益); title(有效前沿曲线); colorbar; ylabel(colorbar, 风险厌恶系数 \lambda); grid on; hold off; % 单独绘制每个资产的风险收益散点图作为对比 figure(Position, [100, 100, 800, 600]) scatter(sqrt(diag(covarianceMatrix)), expectedReturns, 100, r, filled); hold on; plot(portfolioRisk, portfolioReturn, b-, LineWidth, 1.5); xlabel(风险标准差); ylabel(期望收益); title(资产分布与有效前沿); legend(单个资产, 有效前沿, Location, best); grid on;图表解读 第一张图是纯粹的有效前沿颜色代表了λ的大小从蓝到黄λ增大。你可以清晰地看到随着风险厌恶程度增加λ变大我们沿着曲线向左下方移动选择更低风险和更低收益的组合。第二张图将单个资产红色圆点和有效前沿蓝色曲线放在一起。这是整个分析最精华的部分。你会发现所有单个资产都位于有效前沿的右下方。这意味着通过优化配置分散投资我们可以在同等风险下获得比任何单一资产更高的收益或者在同等收益下承担比任何单一资产更低的风险。这就是资产配置的价值有效前沿的左端点是全局最小方差组合这是所有可行组合中风险最低的那个点。有效前沿的右上部分通常比较陡峭意味着增加一点风险可以换来较多的收益提升而右下部分变得平坦意味着为了再降低一点点风险需要牺牲大量的收益。这个形状能帮你做出更理性的权衡。4. 进阶讨论与常见陷阱模型跑通了图也画出来了是不是就大功告成了远不止。在实际应用和数学建模竞赛中下面这些才是区分水平的关键。4.1 输入数据的“垃圾进垃圾出”模型结果严重依赖于输入的期望收益和协方差矩阵。而用历史数据的样本均值和样本协方差来估计未来存在巨大问题估计误差特别是对于期望收益历史均值是非常不稳定的估计量。一个资产过去三年涨得好不代表未来也好。极端值影响一次“黑天鹅”事件会导致协方差矩阵估计失真。怎么办收缩估计将样本协方差矩阵向一个结构更简单的矩阵如常数相关系数矩阵、单位矩阵进行收缩以降低估计误差。MATLAB的金融工具箱里有相关函数。因子模型用更少的几个宏观经济因子如市场因子、规模因子、价值因子来解释资产收益从而估计协方差矩阵。这能大幅降低待估参数的数量。稳健统计使用中位数、MCD估计量等对异常值不敏感的方法来计算位置和散度。明确说明假设在建模论文中必须明确指出“本模型基于历史数据估计未来可能失效”这是严谨性的体现。4.2 模型本身的局限性均值-方差模型假设收益服从正态分布且投资者只关心收益的均值和方差即风险。但现实世界收益分布非正态经常出现“尖峰厚尾”即极端涨跌的概率比正态分布预测的要高。投资者可能关心下行风险比起整体的波动方差投资者更讨厌亏损下行半方差。替代或补充模型CVaR条件风险价值模型优化组合使得在最坏的α%情况下的平均损失最小。这更关注“尾部风险”。Black-Litterman模型将投资者对某些资产的主动观点与市场均衡收益先验结合起来得到更合理的收益估计。这在一定程度上缓解了对期望收益估计不准的问题。在MATLAB中金融工具箱和优化工具箱提供了对这些高级模型的支持。例如可以使用portopt函数族来简化有效前沿的计算使用Portfolio对象来管理更复杂的约束和模型。4.3 MATLAB求解中的数值与实操陷阱即使模型正确在MATLAB里也可能“翻车”。协方差矩阵不正定如果资产数量多于观测数据点或者资产间存在完全线性关系样本协方差矩阵可能是奇异的或半正定的这会导致优化问题无解或求解不稳定。MATLAB会报错“Matrix must be positive definite”。解决方法检查数据确保观测数远大于资产数对协方差矩阵进行正则化处理如加上一个很小的单位矩阵倍数。局部最优与初始值虽然均值-方差模型是凸优化问题理论上只有一个全局最优。但对于更复杂的非凸模型比如加入整数约束fmincon可能陷入局部最优。解决方法尝试多个不同的初始点x0比较结果。约束太多导致无可行解如果你同时设置了“每个资产权重不超过10%”和“组合收益不低于15%”在资产池本身收益不高的情况下可能没有任何分配方案能满足所有条件。解决方法先用宽松的约束求解逐步收紧观察可行域的变化。使用fmincon的输出参数exitflag来判断求解状态exitflag 0通常表示成功。踩坑实录在一次比赛中我们使用了20个资产但只有24个月的数据导致协方差矩阵病态优化结果极度不稳定权重集中在一两个资产上且每次运行结果差异很大。后来我们采用了指数加权移动平均的方法计算协方差给近期的数据更高权重同时使用了Ledoit-Wolf收缩估计才得到了稳定、合理的分散化组合。这个教训让我深刻理解到对于金融时间序列数据处理和估计方法的重要性有时甚至超过优化算法本身。5. 从模型到方案结果解读与报告撰写算出权重画出曲线工作只完成了一半。如何把数学结果翻译成业务语言或竞赛论文中的“解决方案”是最后也是最关键的一步。5.1 如何解读有效前沿上的点不要只说“当λ0.5时最优组合是...”。要赋予其业务含义。最小方差组合这是风险厌恶者的“安全港”。在论文中可以描述为“保守型投资基准”。最大夏普比率组合夏普比率 (组合收益 - 无风险利率) / 组合风险。这个点代表了每承担一单位风险所获得的超额收益最高是风险调整后收益最优的点。你需要先设定一个无风险利率如国债收益率。特定目标点例如“为了达到8%的年化收益目标我们模型给出的最优组合风险为12%具体配置为...”。这直接回应了问题需求。在MATLAB中计算夏普比率和找到最大夏普比率组合点可以这样实现% 假设无风险利率年化为2%转换为与数据周期匹配的利率例如月度 riskFreeRate 0.02 / 12; % 月度无风险利率 % 计算每个组合的夏普比率 sharpeRatios (portfolioReturn - riskFreeRate) ./ portfolioRisk; % 找到最大夏普比率对应的索引 [~, idxMaxSharpe] max(sharpeRatios); % 获取该组合的权重、收益和风险 optimalWeights portfolioWeights(:, idxMaxSharpe); optimalReturn portfolioReturn(idxMaxSharpe); optimalRisk portfolioRisk(idxMaxSharpe); fprintf(最大夏普比率组合信息\n); fprintf(夏普比率%.4f\n, sharpeRatios(idxMaxSharpe)); fprintf(期望收益%.4f\n, optimalReturn); fprintf(风险标准差%.4f\n, optimalRisk); fprintf(资产权重\n); disp(optimalWeights);5.2 撰写建模报告的核心要点如果是为了比赛或项目报告你的行文逻辑应该是问题重述与分析用你自己的话说明这是一个多目标优化问题核心矛盾是收益与风险的权衡。模型假设清晰列出。例如“假设资产收益率服从多元正态分布”、“投资者仅关注收益的均值和方差”、“不考虑交易成本和税收”等。这是模型的边界非常重要。符号说明用表格列出所有模型中用到的变量、符号及其含义。模型建立推导目标函数和约束条件。给出均值-方差模型的两种等价形式并说明你为何选择效用函数法因其可调节风险偏好。求解方法说明你使用了MATLAB的fmincon优化求解器并简要说明其原理如处理非线性约束的内点法。结果分析展示有效前沿图并解释其经济学含义为什么曲线向左上方凸为什么单个资产在曲线右下方。展示关键组合用表格列出最小方差组合、最大夏普比率组合以及符合题目要求如特定收益目标的组合的权重、收益和风险。敏感性分析改变关键参数如风险厌恶系数λ的范围、无风险利率观察有效前沿和最优组合的变化。这能体现模型的稳健性和你的思考深度。模型评价与推广优点模型清晰数学工具成熟能直观展示风险收益权衡。缺点明确指出对输入数据敏感、假设收益正态分布等局限性。改进方向提出可以尝试CVaR模型、引入Black-Litterman框架、使用更稳健的估计方法等。我个人在多次建模和实际分析中的体会是一个漂亮的MATLAB图表和一段简洁的代码远不如一份逻辑清晰、对模型局限性有清醒认识、并能将数学结果转化为 actionable insights可执行的见解的报告来得有价值。模型永远是对现实的简化一个好的建模者不仅要会使用工具简化现实更要能理解这种简化的边界在哪里并诚实地将它呈现出来。当你能够向一个不懂数学的客户或评委用有效前沿图讲明白“为什么不要把所有鸡蛋放在一个篮子里”以及“如何在你的风险承受范围内找到那个最好的篮子组合”时你才真正掌握了这个工具的精髓。
返回列表