0


投资组合--蒙特卡洛模拟(Python)

首先import需要用到的库

  1. from numpy import *
  2. from numpy.linalg import multi_dot
  3. import pandas as pd
  4. import matplotlib.pyplot as plt
  5. from tqdm import *

加载画图的库并忽略告警

  1. import cufflinks as cf
  2. cf.set_config_file(
  3. offline = True,
  4. dimensions = ((800, 600)),
  5. theme = 'ggplot')
  6. import plotly.express as px
  7. px.defaults.width = 800
  8. px.defaults.height = 600
  9. import warnings
  10. warnings.filterwarnings('ignore')
  11. # 解决中文和负号问题
  12. plt.rcParams['font.sans-serif'] = ['SimHei']
  13. plt.rcParams['axes.unicode_minus'] = False

导入外部数据(https://download.csdn.net/download/weixin_55618145/87666946)

  1. file_name = '2017_2021_daily.csv'
  2. data = pd.DataFrame(pd.read_csv(file_name, index_col=0, parse_dates=True)).dropna()
  3. data.head()

展示历史价格走势

  1. (data/data.iloc[0]).plot(figsize = (10,6))
  2. plt.xlabel('日期')
  3. plt.ylabel('价格走势(起始为1)')
  4. plt.title('6只股票历史价格走势')
  5. plt.show()

显示如下:

计算历史回报及波动

  1. returns = log(data/data.shift(1)).dropna()
  2. # 年化收益率及波动
  3. pd.DataFrame({
  4. '年化收益率(%)': round(returns.mean()*250*100, 2),
  5. '年化波动率(%)': round(returns.std()*sqrt(250)*100, 2),
  6. '夏普比率': round(returns.mean()/returns.std()*sqrt(250), 2)
  7. }).iplot(kind='bar', title='年化收益率(%)、年化波动率(%)及夏普比率', shared_xaxes=True, subplots=True)

结果如下

有效边界及市场组合——蒙特卡洛模拟

运行10000次随机构建的组合比例(不做空任何一只股票)

  1. # 组合的股票构成
  2. symbols = ['顺发恒业', '贵州茅台', '重庆啤酒', '中南传媒', '海天味业', '五粮液']
  3. numofasset = len(symbols)
  4. # 定义一个组合的函数
  5. def portfolio_simulation(returns):
  6. rets = []; vols=[]; wts=[]
  7. # 模拟10000次6只股票不同权重的组合
  8. for i in tqdm(range(10000)):
  9. # 产生随机权重
  10. weights = random.random(numofasset)[:, newaxis]
  11. weights = weights/weights.sum()
  12. # 记录组合的收益、波动、权重
  13. rets.append(weights.T @ array(returns.mean()*250)[:,newaxis])
  14. vols.append(sqrt(multi_dot([weights.T, returns.cov()*250, weights])))
  15. wts.append(weights.flatten())
  16. # 记录组合各数据
  17. portdf = 100 * pd.DataFrame({
  18. 'port_rets': array(rets).flatten(),
  19. 'port_vols': array(vols).flatten(),
  20. 'weights': list(array(wts))
  21. })
  22. portdf['Sharp_ratio']=portdf['port_rets']/portdf['port_vols'] #假设rf为0
  23. return round(portdf, 2)
  1. # 用6只股票组成投资组合并模拟
  2. temp = portfolio_simulation(returns)
  3. temp.head(10)

获取全部模拟中夏普比率最大值

  1. temp.iloc[temp.Sharp_ratio.idxmax()]

最后把结果可视化

  1. # 绘制模拟组合(每个组合一个点)
  2. fig = px.scatter(
  3. temp, x='port_vols', y='port_rets', color='Sharp_ratio',
  4. labels={'port_vols': '预期波动(%)','port_rets': '预期收益(%)', 'Sharp_ratio':
  5. '夏普比率'},
  6. title='投资组合蒙特卡洛模拟'
  7. ).update_traces(mode='markers', marker=dict(symbol='circle'))
  8. # 标记最大夏普比率的组合(市场组合)
  9. fig.add_scatter(mode='markers',
  10. x=[temp.iloc[temp.Sharp_ratio.idxmax()]['port_vols']],
  11. y=[temp.iloc[temp.Sharp_ratio.idxmax()]['port_rets']],
  12. marker=dict(color='Blue', size=14, symbol='square'),
  13. name = '市场组合'
  14. ).update(layout_showlegend=False)
  15. fig.update_xaxes(showspikes=True)
  16. fig.update_yaxes(showspikes=True)
  17. fig.show()

模拟结果如下(右上角蓝色方块对应夏普比率最大的组合)


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

“投资组合--蒙特卡洛模拟(Python)”的评论:

还没有评论