当前位置: 首页 > article >正文

【MATLAB】绘制投资组合的有效前沿

文章目录

  • 一、数据准备
  • 二、有效前沿
  • 三、代码
    • 3.1 数据批量读取、预处理
    • 3.2 绘制可行集
    • 3.3 绘制有效前沿
    • 3.4 其它-最大夏普率

一、数据准备

准备多个股票的的历史数据,目的就是找到最优的投资组合。

下载几个标普500里面的公式的股票数据吧,下载方法也可以看我的上一篇文章:【MATLAB】股票(和指数)数据下载–雅虎财经
在这里插入图片描述

用你自己的数据也是一样的。

二、有效前沿

有效前沿(Efficient Frontier)是现代投资组合理论中的一个核心概念,最早由经济学家哈里·马科维茨(Harry Markowitz)于1952年提出。

它表示在给定的风险水平下,能够实现的最高预期收益,或者在给定的预期收益下,能够承担的最低风险。

有效前沿不仅是投资组合选择的理论基础,也广泛应用于其他领域,如资源优化、决策分析等。

在投资领域,有效前沿通常通过均值-方差优化模型进行描述。在该模型中,风险由资产收益的标准差(或方差)表示(也称为波动率)收益由资产的预期收益率表示

有效前沿上的每一个点都代表一个优化的投资组合,它在某个特定风险水平下提供最高的预期回报。


构建有效前沿的基本步骤包括:

  1. 确定投资资产集合:选择能够构成投资组合的资产。这些资产可以是股票、债券、房地产等。

  2. 估计资产的预期收益与风险:计算每个资产的预期收益(通常基于历史数据或市场预期)以及各个资产之间的相关性(即协方差矩阵)。

  3. 计算投资组合的收益与风险:对于不同的资产组合,可以通过加权平均计算组合的预期收益和组合的风险(标准差)。组合的风险不仅依赖于单个资产的风险,还受到各资产之间的相关性影响。

  4. 优化组合:通过数学优化方法(如线性规划、二次规划等),寻找在不同风险水平下提供最大收益的资产组合。这个过程可以利用均值-方差优化或其他先进算法。

  5. 绘制有效前沿:根据不同风险水平下优化出的资产组合,绘制收益-风险图,得到有效前沿曲线。


有效前沿可以通过以下数学公式来描述。假设有一个包含 n n n个资产的投资组合,其中每个资产的预期收益为 r i r_i ri,资产的权重为 x i x_i xi,且资产收益的协方差矩阵为 Σ \Sigma Σ,则投资组合的预期收益 R p R_p Rp和风险 σ p \sigma_p σp分别为:

  • 投资组合预期收益:

R p = ∑ i = 1 n x i r i R_p = \sum_{i=1}^{n} x_i r_i Rp=i=1nxiri

  • 投资组合风险(标准差、波动率):

    σ p = ∑ i = 1 n ∑ j = 1 n x i x j σ i j \sigma_p = \sqrt{\sum_{i=1}^{n} \sum_{j=1}^{n} x_i x_j \sigma_{ij}} σp=i=1nj=1nxixjσij

    其中, σ i j \sigma_{ij} σij是资产 i i i和资产 j j j的协方差。

通过调整资产的权重 x i x_i xi,可以得到一系列不同风险水平下的投资组合,最终形成有效前沿。

你可能看到的是下面的公式,它和前面的是一样的: σ p = w T Σ w \sigma_p = \sqrt{\mathbf{w}^T \Sigma \mathbf{w}} σp=wTΣw

其中:

  • σ p \sigma_p σp 是投资组合的波动率。
  • w \mathbf{w} w 是投资组合的权重向量(例如, w 1 , w 2 , … , w n w_1, w_2, \dots, w_n w1,w2,,wn,表示每个资产在组合中的比例)。
  • Σ \Sigma Σ 是资产收益率的协方差矩阵,描述了不同资产之间的相关性和波动性。

有效前沿的意义与应用:

  1. 优化投资组合:有效前沿帮助投资者在给定的风险承受能力下,选择最优的资产组合。在风险-收益权衡中,任何位于有效前沿上的投资组合都不能通过改变权重来提高收益而不增加风险。

  2. 风险管理:通过有效前沿,投资者可以直观地了解在不同风险水平下可获得的最大收益,从而做出更为理性的投资决策。

  3. 现代投资理论的基石:有效前沿是现代投资组合理论的核心,它推动了金融市场中基于数学优化的投资策略的广泛应用,如资本资产定价模型(CAPM)等。

  4. 跨领域应用:除了投资领域,有效前沿的思想也应用于多个领域,如供应链管理中的资源分配、生产管理中的成本控制、工程设计中的性能优化等。

尽管有效前沿是一个理论上非常优越的工具,但其也存在一定局限性:

  1. 依赖历史数据:有效前沿的构建依赖于对历史数据的估计,然而,历史收益并不一定能准确预测未来的表现,尤其是在市场波动剧烈时。

  2. 假设过于理想化:现代投资组合理论假设资产收益是正态分布的,而实际上,金融市场中的资产收益可能具有偏度和峰度,这使得均值-方差优化在实际应用中可能存在偏差。

  3. 忽略了投资者的其他需求:有效前沿关注的是收益和风险的权衡,而忽略了投资者的其他需求,如流动性、税务等。

为了克服这些问题,研究人员提出了多种改进方法,例如:

  • 引入更多的风险度量指标:如条件风险价值(CVaR)、最坏情况下的风险(worst-case risk)等。
  • 使用贝叶斯方法:利用贝叶斯推断来改进参数估计,减少数据不确定性对有效前沿的影响。
  • 引入行为金融学的视角:将投资者心理、行为偏差等因素纳入投资决策中,提供更为全面的投资建议。

三、代码

3.1 数据批量读取、预处理

7支股票数据放在一个文件夹里面:
在这里插入图片描述
直接读取该文件夹内所有excel文件,已经股票名称。

%% 读取股票数据,放到一个table里面,只要收盘价格

% 获取stock目录下所有Excel文件
files = dir('stock/*.xlsx');

% 初始化一个空数组,用来存储所有文件的收盘数据
allClosePrices = [];
% 股票名称
stock_name = {};

% 循环遍历每个Excel文件
for i = 1:length(files)
    % 获取当前文件的完整路径
    filePath = fullfile('stock', files(i).name);

    % 保存股票名称
    stock_name = [stock_name,strtok(files(i).name,'_')];

    % 读取Excel文件中的数据
    data = readtable(filePath, 'VariableNamingRule', 'preserve');
    
    % 检查该文件是否包含 '收盘' 列
    if ismember('收盘', data.Properties.VariableNames)
        % 提取 '收盘' 列数据
        closePrices = data.('收盘');
        
        % 将收盘数据合并到 allClosePrices 中
        allClosePrices = [allClosePrices, closePrices];
    else
        warning('文件 %s 不包含 "收盘" 列。', files(i).name);
    end
end

% 创建table
stock_data = table(data.("日期"));
stock_data = [stock_data,array2table(allClosePrices)];

% 列命名
stock_data.Properties.VariableNames = ['日期',stock_name];

结果:
在这里插入图片描述

如果你的数据有缺失值,比如某至股票某些交易日数据丢失了,可以选择删除这一天的所有数据,或者用均值填充,用临近的值填充等。

我使用的数据没有缺失值。

%% 数据预处理,缺失值处理

% 提取一下价格矩阵
price_data = table2array(stock_data(:,2:8));

% 用均值填补缺失值
for i = 1:size(price_data, 2)
    % 计算该列非缺失值的均值
    column_mean = nanmean(price_data(:, i));

    % 找到缺失值的位置并用均值填补
    price_data(isnan(price_data(:, i)), i) = column_mean;
end

% 删除缺失值
% price_data = rmmissing(price_data);

3.2 绘制可行集

随机生成2000个权重即投资组合,然后计算收益率、波动率,画出散点图,就做出了投资组合的可行集。

在这里插入图片描述

%% 收益率相关计算

% 计算每日收益率
daily_returns = diff(log(price_data)); 

% 求每支股票的年化平均收益率
mean_returns = mean(daily_returns)*252;

% 计算收益率的协方差矩阵
cov_matrix = cov(daily_returns)*252;

%% 模拟投资组合

% 设置模拟的投资组合数目
num_portfolios = 2000;
% 初始化权重矩阵为0矩阵
weights = zeros(num_portfolios, length(stock_name));

port_returns = zeros(num_portfolios, 1);
port_volatility = zeros(num_portfolios, 1);
port_sharpe = zeros(num_portfolios, 1);

% 随机生成投资组合权重
for i = 1:num_portfolios
    % 随机权重
    w = rand(1, length(stock_name));
    w = w / sum(w);  % 使权重总和为1
    
    % 计算组合的收益率和波动率
    portfolio_return = sum(w .* mean_returns);

    portfolio_volatility = sqrt(w * cov_matrix * w');
    
    % 存储结果
    weights(i, :) = w;
    port_returns(i) = portfolio_return;
    port_volatility(i) = portfolio_volatility;
    
    % 计算夏普比率,假设无风险利率为2%
    port_sharpe(i) = (portfolio_return -0.02)/ portfolio_volatility;
end

%% 绘制可行集

figure;
scatter(port_volatility, port_returns, 10, port_sharpe, 'filled');
title('有效前沿');
xlabel('波动率');
ylabel('收益率');
grid minor
hold on

3.3 绘制有效前沿

matlab的函数是:Portfolio

(旧版的叫啥我忘了,反正推荐用新的就行)

自己去看matlab的帮助文档就行,说的很清楚:

在这里插入图片描述

有哪些函数,都写的很清楚:

在这里插入图片描述


我的示例:
在这里插入图片描述

% 创建 Portfolio 对象
p = Portfolio;

% 设置资产回报率数据(均值和协方差矩阵)
p = Portfolio(p, 'assetmean', mean_returns, 'assetcovar',cov_matrix);
% 设置上、下限为 1,表示权重之和为 1
p = Portfolio(p, 'lowerbudget', 1, 'upperbudget', 1);
 % 设置下限为 0,表示不允许空头,最大收益率为xx
p = Portfolio(p, 'lowerbound', 0,'UpperBound',0.5);

plotFrontier(p);
title('可行集和有效前沿');
xlabel('波动率');
ylabel('收益率');
grid minor
hold on

3.4 其它-最大夏普率

夏普比率(Sharpe Ratio) 是衡量投资组合风险调整后收益的指标,通常用来比较不同投资的风险收益表现。夏普比率越高,表示单位风险下的回报越好,投资表现越优秀。

夏普比率的计算公式为:
S = R p − R f σ p S = \frac{R_p - R_f}{\sigma_p} S=σpRpRf

其中:

  • S S S 是夏普比率
  • R p R_p Rp 是投资组合的预期收益率
  • R f R_f Rf 是无风险利率(通常使用短期国债收益率或类似的低风险投资的回报率)
  • σ p \sigma_p σp 是投资组合的波动率(即标准差,表示投资组合的风险)

解释:

  • R p − R f R_p - R_f RpRf:投资组合的超额回报(即投资组合回报减去无风险利率)。这个部分衡量了投资组合的实际收益。
  • σ p \sigma_p σp:投资组合的风险(波动率)。它表示收益的波动程度。

夏普比率的应用:

  • 较高的夏普比率表示相对于承担的风险,投资组合的回报较高。换句话说,投资者用较少的风险获得较好的回报。
  • 较低的夏普比率意味着投资组合的回报相对于风险较低,或者相同风险下的回报较差。

夏普比率的改进:

  1. 年化夏普比率:如果收益率是日常或月度数据,通常将其年化以便比较:

    • 日常数据: S annual = S daily × 252 S_{\text{annual}} = S_{\text{daily}} \times \sqrt{252} Sannual=Sdaily×252 (通常一年252个交易日)
    • 月度数据: S annual = S monthly × 12 S_{\text{annual}} = S_{\text{monthly}} \times \sqrt{12} Sannual=Smonthly×12
  2. 针对不同时间频率的无风险利率:无风险利率的选择应与数据的时间频率一致,确保一致性。–


用的函数都是Portfolio对象的函数,自己去看具体说明。

%% 计算最大夏普率

% 估计有效投资组合以最大化 Portfolio 对象的夏
普比率
weights = estimateMaxSharpeRatio(p);

[risk, ret] = estimatePortMoments(p, weights);

plot(risk,ret,'*b');
grid minor

max_sharpe_ratio = (ret-0.02)/risk;
fprintf('最大夏普率为:%.4f,对应的波动率为:%.4f, 收益率为:%.4f\n',max_sharpe_ratio,risk,ret);

%% 估计有效边界上指定数量的最优投资组合

% 普比率是投资组合收益率均值与无风险利率之差除以投资组合收益标准差的比率。

% 估计有效边界上指定数量的最优投资组合
pwgt = estimateFrontier(p, 100); % 权重

% 估计投资组合收益波动率(标准差)和均值
[prsk, pret] = estimatePortMoments(p, pwgt);

% 计算它们的夏普率
sharpe_ratio = (pret-0.02)./prsk;


http://www.kler.cn/a/470572.html

相关文章:

  • 【信息系统项目管理师】第15章:项目风险管理过程详解
  • 标准IO
  • Backend - C# 操作数据库 DB(ADO.NET、LINQ to SQL、EF)
  • 西门子200smart存储卡作用
  • kafka使用以及基于zookeeper集群搭建集群环境
  • MOE怎样划分不同专家:K-Means聚类算法来实现将神经元特征聚类划分
  • 数据分析工作流
  • XXX公司面试真题
  • Selenium 八大元素定位方法及场景扩展
  • Hadoop、Flink、Spark和Kafka
  • Visual studio code编写简单记事本exe笔记
  • 【Uniapp-Vue3】image媒体组件属性
  • 【Logstash01】企业级日志分析系统ELK之Logstash 安装与介绍
  • 【通识安全】煤气中毒急救的处置
  • 数据库系统安全
  • 数据结构:时间复杂度和空间复杂度
  • 如何恢复依赖的go自定义SDK的GoZero项目
  • MCGS学习记录
  • JuiceFS 详解:一款为云原生设计的高性能分布式文件系统
  • @Cacheable 注解爆红(不兼容的类型。实际为 java. lang. String‘,需要 ‘boolean‘)
  • SQL Server 中 STRING_AGG 函数使用拼接字符串超长处理方法
  • JVM实战—10.MAT的使用和JVM优化总结
  • 机器学习周报-ModernTCN文献阅读
  • 回归预测 | MATLAB实现CNN-BiLSTM-Attention多输入单输出回归预测
  • 解决linux自启程序无法在终端输出问题
  • 低空经济应用探索,无人机个性需求组装技术详解