起因
之前的文章:马科维茨模型下的投资组合优化:编程实现与实践问题-CSDN博客
对于使用的蒙特卡洛模拟的效果很不满意
多次模拟都不能非常接近有效边沿,并且比较费时。
随机的方法会发生大量无效测试。
测试数从10000加到100000的时候还出现了运行缓慢的情况,原因不明。
于是,决定改进方法。
先直接贴个结果图
处理思路
-
数据收集:
- 首先,收集所选股票在一定时间内的每日收盘价数据。
- 使用这些数据计算每只股票的日收益率。日收益率的计算公式为:(当日收盘价 - 前一日收盘价) / 前一日收盘价。
-
计算统计量:
- 对于每只股票,计算其日收益率的均值(即期望收益率)和标准差(即波动率,代表风险)。
- 计算每对股票日收益率之间的协方差,以了解它们之间的关联性。
-
构建协方差矩阵:
- 使用股票之间的协方差数据,构建一个协方差矩阵。这个矩阵将用于后续的组合风险计算。
-
确定权重:
- 马科维茨模型的目标是在给定预期收益率下最小化风险,或在给定风险水平下最大化预期收益率。
- 通过优化方法(如二次规划)来找到最优的股票权重组合。这些权重表示在投资组合中每只股票所占的比例。
-
绘制有效前沿:
- 通过选择不同的预期收益率水平,并计算对应的最小风险组合,可以绘制出有效前沿。
- 有效前沿是所有可能的投资组合中,在给定的风险水平下提供最高预期收益率的组合的集合。
-
选择最优组合:
- 根据投资者的风险偏好和效用函数,在有效前沿上选择最优的投资组合。
- 最优组合是在投资者可接受的风险水平下,提供最高预期收益率的组合。
-
验证和调整:
- 使用历史数据或其他测试集来验证所选投资组合的性能。
- 根据市场条件的变化和新的数据,定期调整投资组合的权重。
-
改进点:
取消蒙特卡洛模拟,改为scipy库中的minimize函数
from scipy.optimize import minimize # 定义约束条件:权重和为1,且每个权重非负 def portfolio_constraints(num_assets_def, target_return=None): constraints_def = [{'type': 'eq', 'fun': lambda x: np.sum(x) - 1}] constraints_def += [{'type': 'ineq', 'fun': lambda x: x[i_def]} for i_def in range(num_assets_def)] # 如果提供了目标收益,则添加对应的等式约束 if target_return is not None: constraints_def.append({'type': 'eq', 'fun': lambda x: portfolio_return(x, expected_returns) - target_return}) return constraints_def
- 再用循环获得每个目标收益下波动率最小的组合
继续思考:
如何应用这个模型调仓
认为先用趋势性指标选股然后根据趋势线指标的参数选择合适的模型计算时间段,用来调整仓位。具体参数的匹配和回测还得慢慢磨。因为这个模型给出的前沿组合都是历史数据,如果你选择某一段时间的数据来做仓位调整,那就隐含了你认为未来(下一次调仓前)各股票的收益率和风险特征接近测试时间段。
需要调整的参数有测试时间段,调仓的间隔,这里还要引入主要策略对个股买卖的信号,要创建起始资金进行模拟,最终结果还要和平均分配进行对比。是一个比较复杂的工程。