0


使用python绘制有效性前沿

有效性前沿
在无数风险资产投资组合中,只要给出既定风险水平,我们总是可以找到收益最高的一个组合。当投资者可承受的风险水平变化时,与该风险水平相对应的最优投资组合A点也一直存在,并且随着风险水平变化不断的移动。这条由不同风险水平下最优投资组合A点构成的曲线,我们称之为有效曲线,又叫有效前沿。

有效性前沿python计算
输入项:
1、资产收益率irr
2、资产相关性矩阵(协方差):cov
3、随机种子:seed。随机生成的配置比例数量,随机种子越大计算越精确
4、目标收益:r_return。投资者期望获得的收益率。
5、无风险利率:rf。指的是10年期国债收益率或者同业拆借利率。

计算步骤:
1、首先随机生成配置比例,个数为随机种子(seed)。
对应的代码为def random_weight
2、依据随机生成的配置比例,计算目标收益(r_return)下的最优配置比例
对应的代码为def cal_random_weight
3、依据随机生成的配置比例,求有效性前沿最左侧的点,即为有效性前沿的起点。
对应的代码为 self.cal_left_point
4、依据所有的最优点,绘制有效性前沿
对应的代码为 self.cal_ff
5、计算市场组合的预期收益率,预期波动率
对应的代码为 self.cal_market_weight
6、依据无风险利率,及市场组合两点连线,求出资本市场线

python代码:

  1. import numpy as np
  2. import pandas as pd
  3. import matplotlib.pyplot as plt
  4. import scipy.optimize as sco
  5. plt.rcParams['font.sans-serif']=['SimHei']# 中文显示问题
  6. plt.rcParams['axes.unicode_minus']=False# 负数显示问题classEffectiveForefront(object):"""
  7. 有效性前沿类
  8. """def__init__(self, irr, cov, seed, r_return, rf):"""
  9. 有效性前沿初始化
  10. :param irr: 收益率
  11. :param cov: 协方差
  12. :param seed: 随机种子数
  13. :param r_return: 目标收益率
  14. :param rf: 无风险利率
  15. """
  16. self.irr = irr
  17. self.rf = rf
  18. self.cov = cov
  19. self.seed = seed
  20. self.r_return = r_return
  21. self.plt =None
  22. self.cons =({'type':'eq','fun':lambda x: np.sum(x)-1},{'type':'eq','fun':lambda x: self.opt_return_vol(x)[0]- r_return})# 输入最优解条件
  23. self.bnds =tuple((0,1)for x inrange(len(irr)))# 输入边界条件
  24. self.frist_weight =len(irr)*[1/len(irr)]# 生成初始权重defeff_handler(self):"""
  25. 有效性前沿计算流程
  26. :return: self.plt 有效性前沿及资本市场线
  27. :return: opt_w 目标收益率下资产配置比例
  28. """
  29. self.plt = self.random_weight()
  30. opt_w = self.cal_random_weight()
  31. left_point_return, left_point_vol = self.cal_left_point()
  32. self.plt.plot(left_point_vol, left_point_return,'y*', markersize=14)
  33. self.cal_ff(left_point_return)
  34. rm, vm, slope = self.cal_market_weight()
  35. rp_cml, vp_cml = self.cal_cml(slope)
  36. self.plt.plot(vp_cml, rp_cml,'b--')
  37. self.plt.plot(vm, rm,'g*', markersize=14)
  38. self.plt.show()return self.plt, opt_w
  39. defcal_cml(self, slope):"""
  40. 计算资本市场线
  41. :param slope: 计算资本市场线斜率
  42. :return:
  43. """
  44. rp_cml = np.linspace(0.02,0.25)
  45. vp_cml =(rp_cml - self.rf)/ slope
  46. return rp_cml, vp_cml
  47. defcal_market_weight(self):"""
  48. 市场组合的预期收益率,预期波动率
  49. :return:
  50. """# 仅设定权重之和为1的约束条件
  51. cons_sr =({'type':'eq','fun':lambda x: np.sum(x)-1})# 求解最优权重
  52. result_sr = sco.minimize(self.srmin_f, self.frist_weight, method='SLSQP', bounds=self.bnds, constraints=cons_sr)
  53. slope =-result_sr['fun']# 即资本市场线斜率# 市场组合的预期收益率
  54. rm = np.sum(irr * result_sr['x'])# 市场组合的收益率# 市场组合的波动率
  55. vm =(rm - self.rf)/ slope # 市场组合的波动率return rm, vm, slope
  56. defcal_ff(self, left_point_return):"""
  57. 求解有效前沿
  58. :param left_point_return: 最左侧点收益率
  59. :param left_point_vol: 最左侧点波动率
  60. :return:
  61. """
  62. rp_target = np.linspace(left_point_return,0.25,100)# 设定波动率列表
  63. vp_target =[]for r in rp_target:
  64. cons_new =({'type':'eq','fun':lambda x: np.sum(x)-1},{'type':'eq','fun':lambda x: self.opt_return_vol(x)[0]- r})
  65. result_new = sco.minimize(self.vmin_f, self.frist_weight, method='SLSQP',
  66. bounds=self.bnds, constraints=cons_new)
  67. vp_target.append(result_new['fun'])
  68. self.plt.plot(vp_target, rp_target,'r-')defcal_random_weight(self):"""
  69. 计算最有结果权重
  70. :return:
  71. """# 求最值
  72. result = sco.minimize(self.vmin_f, self.frist_weight, method='SLSQP', bounds=self.bnds, constraints=self.cons)# 获取最优化结果的权重
  73. result['x'].round(4)
  74. w_df = pd.DataFrame()
  75. w_df['asset']=list(self.cov)
  76. w_df['weight']= result['x']return w_df
  77. defrandom_weight(self):"""
  78. 随机生成配置比例
  79. :return:
  80. """
  81. rp_list =[]
  82. vp_list =[]# 设定投资组合各产品的均值for i in np.arange(self.seed):
  83. x = np.random.random(5)
  84. weights = x /sum(x)
  85. rp_list.append(np.sum(weights * self.irr))
  86. vp_list.append(np.sqrt(np.dot(weights, np.dot(self.cov, weights.T))))
  87. plt.figure(figsize=(8,6))
  88. plt.scatter(vp_list, rp_list)
  89. plt.xlim(0.12,0.28)
  90. plt.ylim(-0.1,0.2)
  91. plt.xlabel('波动率')
  92. plt.ylabel('预期收益率')
  93. plt.grid('True')return plt
  94. defopt_return_vol(self, w):"""
  95. 计算最优组合的预期收益率、收益波动率
  96. :param w: 资产配置权重
  97. :return:
  98. """
  99. w = np.array(w)
  100. rp_opt = np.sum(w * self.irr)# 计算最优投资组合的预期收益率
  101. vp_opt = np.sqrt(np.dot(w, np.dot(self.cov, w.T)))# 计算最优投资组合的收益波动率return np.array([rp_opt, vp_opt])defvmin_f(self, w):return self.opt_return_vol(w)[1]defcal_left_point(self):"""
  102. 求解有效前沿最左侧的点
  103. :return:
  104. """
  105. cons_vmin =({'type':'eq','fun':lambda x: np.sum(x)-1})
  106. result_vmin = sco.minimize(self.vmin_f, self.frist_weight, method='SLSQP',
  107. bounds=self.bnds, constraints=cons_vmin)# 求解投资组合的最左侧点的收益率
  108. rp_vmin = np.sum(irr * result_vmin['x'])# 求解投资组合的最左侧点的波动率
  109. vp_vmin = result_vmin['fun']return rp_vmin, vp_vmin
  110. defsrmin_f(self, w):"""
  111. 最优投资组合夏普比率
  112. :param w:
  113. :return:
  114. """
  115. w = np.array(w)
  116. rp_opt = np.sum(w * irr)
  117. vp_opt = np.sqrt(np.dot(w, np.dot(cov, w.T)))
  118. SR =(rp_opt - self.rf)/ vp_opt
  119. return-np.array([rp_opt, vp_opt, SR])[2]# 求解最大的夏普比率就是求解负的最小值if __name__ =='__main__':
  120. irr = np.array([0.20,0.08,-0.17,0.06,-0.04])
  121. cov = pd.DataFrame({'A':[0.09,0.02,0.02,0.01,0.02],'B':[0.02,0.12,0.04,0.02,0.03],'C':[0.02,0.04,0.07,0.02,0.03],'D':[0.01,0.02,0.02,0.04,0.02],'E':[0.02,0.03,0.03,0.02,0.04]})
  122. seed =10000
  123. r_return =0.1
  124. rf =0.02
  125. ef = EffectiveForefront(irr, cov, seed, r_return, rf)
  126. plt, opt_w = ef.eff_handler()print('目标收益率下的配置比例为')print(opt_w)
  127. plt.show()

该算法的优点:
1、无需用到复杂的tensorflow模型,比较好调试参数
2、资产数较少的时候,计算非常准确。

缺点:
1、资产数较大的时候,要满足相同的精度,需要的随机种子数会指数级增加。在本案例中,五个资产用了一万随机种子。如果资产数增加为六,随机种子数要达到十万个。如果50个资产,随机种子数要达到10^50。不适合资产配置较多的投资组合。
2、大量随机生成的配置点离最优点非常远,浪费掉了。

附上python结果:

目标收益率下的配置比例为:
asset weight
0 A 0.310922
1 B 0.085937
2 C 0.000000
3 D 0.550663
4 E 0.052478

在这里插入图片描述


本文转载自: https://blog.csdn.net/tingyuanyuan/article/details/125428127
版权归原作者 GOGOTYY 所有, 如有侵权,请联系我们删除。

“使用python绘制有效性前沿”的评论:

还没有评论