一、 股票数据

1 股票选择

一共有十只股票,投资者购买目标指数中的资产,如果购买全部,从理论上讲能够完 美跟踪指数,但是当指数成分股较多时,购买所有资产的成本过于高昂,同时也 需要很高的管理成本,在实际中一般不可行,投资者购买成分股时,过多过少都不太合理。所以对十只股票数据选择。分别考虑风险最小和收益与风险平衡两种选择。此处不详细讨论股票的选择问题。

根据各股票所占投资权重选择股票。

1-1 风险最小时

十只股票所占权重:

[0.1753033 0.00369514 0.15429923 0.05403638 0.05760288 0.08978148 0.0404732 0.24393783 0.11091322 0.24791015]

权重大小代表在风险最小的情况下选择各支股票的概率,筛选出前五的股票:abc001,abc003,abc008,abc009,abc010作为成分股。

1-2 投资最优组合

收益和风险平衡时,各支股票的占比为:

[0.13995881 0.04174609 0.0744733 0.19486535 0.06728951 0.03574238 0.04879157 0.17721958 0.04126201 0.22572025]

根据模拟的结果,我们选取股票:abc001,abc004,abc007,abc008,abc010五支股票

首先导入将要用的Python包。

import pandas as pd

import matplotlib.pyplot as plt

from pandas import read_excel

import numpy as np

下面只展示1-1选择的股票组合(1-2选择的组合类似,只需要改变股票名)

2 获取每支股票的收盘价

将股票的每日的收盘价存入数据框 StockPrices 变量中。

# 创建空的DataFrame变量,用于存储股票数据

StockPrices = pd.DataFrame()

market_value_list=[] #存储每支股票的平均市值

# 创建股票代码的列表

ticker_list = ['abc001','abc003','abc008','abc009','abc010']

# 使用循环,挨个获取每只股票的数据,并存储每日收盘价

for ticker in ticker_list:

stock_data = pd.read_excel('C:/Users/asus/Desktop/zqb/data/'+ticker+ '.xlsx', parse_dates=['时间'], index_col='时间',encoding='utf-8')

stock_data=stock_data.loc['2019-01-29':'2020-03-25']

market_value_list.append(stock_data['成交量'].mean())

StockPrices.index.name = 'date' # 日期为索引列

# 输出数据的前5行

print(StockPrices.head())

3 计算股票的日收益率

计算股票每天的收益率,将数据存储在数据框 StockReturns 变量中。

# 计算每日收益率,并丢弃缺失值

StockReturns = StockPrices.pct_change().dropna()

# 打印前5行数据

print(StockReturns.head())

至此,我们已经准备好了用于分析的数据 StockReturns, 它记录了5支股票2019-01-29到2020-03-26每天的收益率。

二、投资组合的收益计算

我们选了5支股票,可资金怎么分配呢?这就需要对它们设置相应的权重,下面我们采用两种权重分配的方案,来计算不同组合下的投资收益。

1 给定权重的投资组合

第一种方案是预先设置一组权重(所有股票权重的和为1)。这5支股票:对应的权重如下:[0.35,0.25,0.17,0.1,0.13]。

我们将每支股票的收益,乘上其对应的权重,得到加权后的股票收益;再对所有股票加权后的收益求和,得到该组合投资的收益。

stock_return = StockReturns.copy()

# 绘制直方图

#给定权重的投资组合

# 设置组合权重,存储为numpy数组类型

portfolio_weights = np.array([0.35,0.25,0.17,0.1,0.13])

# 计算加权的股票收益

WeightedReturns = stock_return.mul(portfolio_weights, axis=1)

# 计算投资组合的收益

StockReturns['Portfolio'] = WeightedReturns.sum(axis=1)

# 打印前5行数据

print(StockReturns.head())

# 绘制组合收益随时间变化的图

StockReturns.Portfolio.plot()

plt.show()

最后一列为组合投资的收益。

回执该组合投资收益随时间变化的图如下:

定义累积收益曲线绘制函数cumulative_returns_plot(),并绘制给定权重投资组合的累积收益曲线

# 定义累积收益曲线绘制函数

def cumulative_returns_plot(name_list):

for name in name_list:

CumulativeReturns = ((1+StockReturns[name]).cumprod()-1)

CumulativeReturns.plot(label=name)

plt.legend()

plt.show()

2 等权重的投资组合

第二种方案是平均分配每支股票的权重,使它们都相等。这是最简单的投资方法,可作为其他投资组合的参考基准。计算方法和上面一致,只需更改存储权重的数组。

##平均分配每支股票的权重

# 设置投资组合中股票的数目

numstocks = 5

# 平均分配每一项的权重

portfolio_weights_ew = np.repeat(1/numstocks, numstocks)

# 计算等权重组合的收益

StockReturns['Portfolio_EW'] = stock_return.mul(portfolio_weights_ew, axis=1).sum(axis=1)

# 打印前5行数据

print(StockReturns.head())

# 绘制累积收益曲线

cumulative_returns_plot(['Portfolio', 'Portfolio_EW'])

三、投资组合的相关性分析

1 投资组合的相关矩阵

相关矩阵用于估算多支股票收益之间的线性关系,可使用pandas数据框内建的 .corr()方法来计算。

#投资组合的相关性分析

# 计算相关矩阵

correlation_matrix = stock_return.corr()

# 输出相关矩阵

print(correlation_matrix)

矩阵中每一个元素都是其对应股票的相关系数,取值从-1到1,正数代表正相关,负数代表负相关。我们观察到矩阵的对角线永远是1,因为自己和自己当然是完全相关的。另外相关矩阵也是对称的,即上三角和下三角呈镜像对称。

为了便于观察,可以将数值的相关矩阵用热图的形式展现出来。以下采用了 seaborn 包来绘制热图。

import seaborn as sns

#创建热图

sns.heatmap(correlation_matrix,annot=True,cmap='rainbow',linewidths=1.0,annot_kws={'size':8})

plt.xticks(rotation=0)

plt.yticks(rotation=75)

plt.show()

2 投资组合的协方差矩阵

相关系数只反应了股票之间的线性关系,但并不能告诉我们股票的波动情况,而协方差矩阵则包含这一信息。可使用pandas数据框内建的 .cov() 方法来计算协方差矩阵。

#投资组合的协方差矩阵

# 计算协方差矩阵

cov_mat = stock_return.cov()

# 年化协方差矩阵

cov_mat_annual = cov_mat * 252

# 输出协方差矩阵

print(cov_mat_annual)

3 投资组合的标准差

投资组合的风险可以用标准差来衡量,只要知道组合权重和协方差矩阵,就可以通过以下公式进行计算。

在NumPy中,使用.T属性对数组进行转置,np.dot()函数用于计算两个数组的点积。

#投资组合的标准差

# 计算投资组合的标准差

portfolio_volatility = np.sqrt(np.dot(portfolio_weights.T, np.dot(cov_mat_annual, portfolio_weights)))

print(portfolio_volatility)

计算的标准差为:0.2735217278102413

四、探索股票的最优投资组合

应该选择怎样的组合权重才是最好的呢?我们需要综合权衡风险和收益这两个因素。

诺贝尔经济学奖得主马科维茨(Markowitz)提出的投资组合理论被广泛用于组合选择和资产配置中。该理论中的均值-方差分析法和有效边界模型可用于寻找最优的投资组合。

1 使用蒙特卡洛模拟Markowitz模型

采用蒙特卡洛模拟来进行分析,也就是随机生成一组权重,计算该组合下的收益和标准差,重复这一过程许多次(比如1万次),将每一种组合的收益和标准差绘制成散点图。

#使用蒙特卡洛模拟Markowitz模型

# 设置模拟的次数

number = 10000

# 设置空的numpy数组,用于存储每次模拟得到的权重、收益率和标准差

random_p = np.empty((number, 7))

# 设置随机数种子,这里是为了结果可重复

np.random.seed(7)

#循环模拟10000次随机的投资组合

for i in range(number):

#生成10个随机数,并归一化,得到一组随机的权重数据

random5=np.random.random(5)

random_weight=random5/np.sum(random5)

#计算年平均收益率

mean_return=stock_return.mul(random_weight,axis=1).sum(axis=1).mean()

annual_return=(1+mean_return)**252-1

#计算年化标准差,也成为波动率

random_volatility=np.sqrt(np.dot(random_weight.T,np.dot(cov_mat_annual,random_weight)))

#将上面生成的权重,和计算得到的收益率、标准差存入数组random_p中

random_p[i][:5]=random_weight

random_p[i][6]=annual_return

random_p[i][6]=random_volatility

#将Numpy数组转化为DataF数据框

RandomPortfolios=pd.DataFrame(random_p)

#设置数据框RandomPortfolios每一列的名称

RandomPortfolios.columns=[ticker +'_weight' for ticker in ticker_list]+['Returns','Volatility']

#绘制散点图

RandomPortfolios.plot('Volatility','Returns',kind='scatter',alpha=0.3)

plt.show()

投资的本质是在风险和收益之间做出选择,上图正是刻画了这两个要素。其中每一个点都代表着一种投资组合的情况,横坐标是代表风险的标准差,纵坐标是收益率。

Markowitz投资组合理论认为,理性的投资者总是在给定风险水平下对期望收益进行最大化,或者是在给定收益水平下对期望风险做最小化。反映在图中所示的有效边界,只有在有效边界上的点才是最有效的投资组合。

现在我们知道,理性的投资者都会选择有效边界上的投资组合。可具体选择哪个点呢?

2 投资风险最小组合

一种策略是选择最低的风险,且在该风险水平下收益最高的组合,称为最小风险组合(GMV portfolio)。

让我们找到风险最小的组合,并绘制在代表收益-风险的散点图中。

# 找到标准差最小数据的索引值

min_index = RandomPortfolios.Volatility.idxmin()

# 在收益-风险散点图中突出风险最小的点

RandomPortfolios.plot('Volatility', 'Returns', kind='scatter', alpha=0.3)

x = RandomPortfolios.loc[min_index,'Volatility']

y = RandomPortfolios.loc[min_index,'Returns']

plt.scatter(x, y, color='red')

#将该点坐标显示在图中并保留四位小数

plt.text(np.round(x,4),np.round(y,4),(np.round(x,4),np.round(y,4)),ha='left',va='bottom',fontsize=10)

plt.show()

# 提取最小波动组合对应的权重, 并转换成Numpy数组

GMV_weights = np.array(RandomPortfolios.iloc[min_index, 0:numstocks])

# 计算GMV投资组合收益

StockReturns['Portfolio_GMV'] = stock_return.mul(GMV_weights, axis=1).sum(axis=1)

#输出风险最小投资组合的权重

print(GMV_weights)

收益-风险的散点图以及获取风险最小组合权重如下:

3 投资最优组合

1)夏普比率

理性的投资者一般都是固定所能承受的风险,追求最大的回报;或者在固定预期回报,追去最小的风险。夏普比率计算的是每承受一单位的总风险所产生的超额回报。计算公式如下:

分子计算了差值,说的是将某项投资与代表整个投资类别的基准进行比较,得到超额回报。分母标准差代表收益的波动率,对应着风险,因为波动越大预示着风险越高。

将超额回报的均值除以其标准差,即可得到衡量回报和风险的夏普比率。另外需再乘上sqrt(252) (一年有252个交易日),得到年化的夏普比率。

2)夏普最优组合的选择

在收益和风险之间找到平衡点,首先计算上述蒙特卡洛模拟的组合所对应的夏普比率,并将之作为第三个变量绘制在收益-风险的散点图中。

#投资最优组合

# 设置无风险回报率为0

risk_free = 0

# 计算每项资产的夏普比率

RandomPortfolios['Sharpe'] = (RandomPortfolios.Returns - risk_free) / RandomPortfolios.Volatility

# 绘制收益-标准差的散点图,并用颜色描绘夏普比率

plt.scatter(RandomPortfolios.Volatility, RandomPortfolios.Returns, c=RandomPortfolios.Sharpe)

plt.colorbar(label='Sharpe Ratio')

plt.show()

我们发现散点图上沿的组合具有较高的夏普比率。接着再找到夏普比率最大的组合,将其绘制在收益-风险的散点图中。

# 找到夏普比率最大数据对应的索引值

max_index = RandomPortfolios.Sharpe.idxmax()

# 在收益-风险散点图中突出夏普比率最大的点

RandomPortfolios.plot('Volatility', 'Returns', kind='scatter', alpha=0.3)

x = RandomPortfolios.loc[max_index,'Volatility']

y = RandomPortfolios.loc[max_index,'Returns']

plt.scatter(x, y, color='red')

#将该点坐标显示在图中并保留四位小数

plt.text(np.round(x,4),np.round(y,4),(np.round(x,4),np.round(y,4)),ha='left',va='bottom',fontsize=10)

plt.show()

# 提取最大夏普比率组合对应的权重,并转化为numpy数组

MSR_weights = np.array(RandomPortfolios.iloc[max_index, 0:numstocks])

# 计算MSR组合的收益

StockReturns['Portfolio_MSR'] = stock_return.mul(MSR_weights, axis=1).sum(axis=1)

#输出夏普比率最大的投资组合的权重

print(MSR_weights)

收益-风险的散点图以及夏普比率最大组合权重如下:

参考文章

Python3-对多股票的投资组合进行分析

(需要数据的话私信我)

python爬取股票平均成本怎么算_Python-多个股票的投资组合分析,对,进行相关推荐

  1. python爬取微博数据存入数据库_Python爬取新浪微博评论数据,写入csv文件中

    因为新浪微博网页版爬虫比较困难,故采取用手机网页端爬取的方式 操作步骤如下: 1. 网页版登陆新浪微博 2.打开m.weibo.cn 3.查找自己感兴趣的话题,获取对应的数据接口链接 4.获取cook ...

  2. python爬取新闻并归数据库_Python爬取数据并写入MySQL数据库操作示例

    Python爬取数据并写入MySQL数据库的实例 首先我们来爬取 http://html-color-codes.info/color-names/ 的一些数据. 按 F12 或 ctrl+u 审查元 ...

  3. python爬取网页书籍名称代码_python爬取亚马逊书籍信息代码分享

    我有个需求就是抓取一些简单的书籍信息存储到mysql数据库,例如,封面图片,书名,类型,作者,简历,出版社,语种. 我比较之后,决定在亚马逊来实现我的需求. 我分析网站后发现,亚马逊有个高级搜索的功能 ...

  4. python爬取岗位数据并分析_Python年薪最高有50w|探秘全国近1600个Python岗位数据分析...

    原创 xinxin 菜鸟学Python 阅读本文大概需要3分钟 Python学了这么久,相信很多小伙伴都想知道钱途如何,全国各大城市招聘Python的岗位有多少,都招哪些职位,年薪如何等等,我爬取了拉 ...

  5. python爬取app中的音频_Python爬取喜马拉雅音频数据详解

    码农公社  210.net.cn  210是何含义?10月24日是程序员节,1024 =210.210既 210 之意. Python爬取喜马拉雅音频数据详解 一.项目目标 爬取喜马拉雅音频数据 受害 ...

  6. python爬取百度贴吧图片库_python爬取百度贴吧的图片2

    今天看了一下beautifulsoup库的用法,把昨天的python爬取百度贴吧的图片1的代码更新成使用beautifulsoup库的函数来实现.用的还是不太熟练,但是感觉比正则表达式写起来容易了一些 ...

  7. python爬取饿了么评论_python爬取饿了么的实例

    python爬取饿了么的实例 发布时间:2020-11-17 10:55:40 来源:亿速云 阅读:85 作者:小新 小编给大家分享一下python爬取饿了么的实例,相信大部分人都还不怎么了解,因此分 ...

  8. python爬取一张图片并保存_python爬取网页图片并保存到本地

    先把原理梳理一下:首先我们要爬取网页的代码,然后从中提取图片的地址,通过获取到的地址来下载数据,并保存在文件中,完成. 下面是具体步骤: 先确定目标,我挑选的是国服守望先锋的官网的英雄页面,我的目标是 ...

  9. python爬取数据分析淘宝商品_python爬取并分析淘宝商品信息

    python爬取并分析淘宝商品信息 Tip:本文仅供学习与交流,切勿用于非法用途!!! 背景介绍 有个同学问我:"XXX,有没有办法搜集一下淘宝的商品信息啊,我想要做个统计".于是 ...

  10. python爬取高考各高校分数线_Python 爬取高校历年分数线

    最近一周一直在帮家里小弟看高考志愿,所以更新的没那么频繁了,请大家见谅. 在看各高校的往年分数时,忍不住手痒,想着能不能给它爬下来?哈哈,说干就干! 1 流程分析 之前无意中在这个网站发现有各个高校的 ...

最新文章

  1. 毕业生实名举报导师剽窃其论文发表:复制比达 90%,导师已道歉
  2. 在路由器上设置虚拟ftp服务器,怎么在路由器上开启ftp服务器配置
  3. IE6常见bug总结
  4. java iterator map_Java循环遍历输出map方法
  5. ESB文件调用,windows服务
  6. 秒杀场景_Sentinel在秒杀场景的应用_05
  7. devops 技术_在DevOps时代雇用技术作家
  8. BackgroundWorker学习笔记
  9. linux下的gdb调试
  10. 在同一个类中,一个方法调用另外一个有注解(比如@Async,@Transational)的方法,注解失效的原因和解决方法
  11. 【报告分享】2021H1电商发展分析报告.pdf(附下载链接)
  12. 服务器可以显示的血量显示,魔兽世界怀旧服怪物如何显示血量
  13. 《基于MFC的OpenGL编程》 13 part 创建2D 和 3D 文字
  14. 旋转倒立摆的起摆与稳摆---QYC
  15. 面试官的窒息逼问:2021最全的接口测试面试题及参考答案
  16. java gis 矢量数据结构_2.4. 矢量数据结构
  17. 算法可以申请专利么_华为突破封锁,对标谷歌Dropout专利,开源自研算法Disout...
  18. linux编译lame,lame mp3 源码 分析
  19. Cadence元器件封装库
  20. 当V4L2遇上Gstreamer

热门文章

  1. Js迷你图书管理系统
  2. 【Oracle EBS】解决大数据量Excel报表打开缓慢问题
  3. 物流基础知识(十七)
  4. 摄像头实时换脸,上网课老师都不认识我了,哈哈
  5. 使用Mybatis时, 在*Mapper.xml中出现大于号小于号的问题及两种解决方案
  6. 【力扣周赛】第345场周赛
  7. 网络通信上手项目(网络画图板)
  8. PDF转换器使用方法分享:Word文件怎么转换成PDF格式
  9. 一个问题,两人讨论,几行代码,一些启发
  10. vs2019 未知错误解决方法