如何用python实现Markowitz投资组合优化

Python013

如何用python实现Markowitz投资组合优化,第1张

0.导入需要的包import pandas as pd

import numpy as np

import statsmodels.api as sm #统计运算

import scipy.stats as scs #科学计算

import matplotlib.pyplot as plt #绘图

1.选取几只感兴趣的股票

000413 东旭光电,000063 中兴通讯,002007 华兰生物,000001 平安银行,000002 万科A

并比较一下数据(2015-01-01至2015-12-31)

In[1]:

stock_set = ['000413.XSHE','000063.XSHE','002007.XSHE','000001.XSHE','000002.XSHE']

noa = len(stock_set)

df = get_price(stock_set, start_date = '2015-01-01', end_date ='2015-12-31', 'daily', ['close'])

data = df['close']

#规范化后时序数据

(data/data.ix[0]*100).plot(figsize = (8,5))

Out[1]:

2.计算不同证券的均值、协方差

每年252个交易日,用每日收益得到年化收益。计算投资资产的协方差是构建资产组合过程的核心部分。运用pandas内置方法生产协方差矩阵。

In [2]:

returns = np.log(data / data.shift(1))

returns.mean()*252

Out[2]:

000413.XSHE0.184516

000063.XSHE0.176790

002007.XSHE0.309077

000001.XSHE -0.102059

000002.XSHE0.547441

In [3]:

returns.cov()*252

Out[3]:

3.给不同资产随机分配初始权重

由于A股不允许建立空头头寸,所有的权重系数均在0-1之间

In [4]:

weights = np.random.random(noa)

weights /= np.sum(weights)

weights

Out[4]:

array([ 0.37505798, 0.21652754, 0.31590981, 0.06087709, 0.03162758])

4.计算预期组合年化收益、组合方差和组合标准差

In [5]:

np.sum(returns.mean()*weights)*252

Out[5]:

0.21622558669017816

In [6]:

np.dot(weights.T, np.dot(returns.cov()*252,weights))

Out[6]:

0.23595133640121463

In [7]:

np.sqrt(np.dot(weights.T, np.dot(returns.cov()* 252,weights)))

Out[7]:

0.4857482232609962

5.用蒙特卡洛模拟产生大量随机组合

进行到此,我们最想知道的是给定的一个股票池(证券组合)如何找到风险和收益平衡的位置。

下面通过一次蒙特卡洛模拟,产生大量随机的权重向量,并记录随机组合的预期收益和方差。

In [8]:

port_returns = []

port_variance = []

for p in range(4000):

weights = np.random.random(noa)

weights /=np.sum(weights)

port_returns.append(np.sum(returns.mean()*252*weights))

port_variance.append(np.sqrt(np.dot(weights.T, np.dot(returns.cov()*252, weights))))

port_returns = np.array(port_returns)

port_variance = np.array(port_variance)

#无风险利率设定为4%

risk_free = 0.04

plt.figure(figsize = (8,4))

plt.scatter(port_variance, port_returns, c=(port_returns-risk_free)/port_variance, marker = 'o')

plt.grid(True)

plt.xlabel('excepted volatility')

plt.ylabel('expected return')

plt.colorbar(label = 'Sharpe ratio')

Out[8]:

6.投资组合优化1——sharpe最大

建立statistics函数来记录重要的投资组合统计数据(收益,方差和夏普比)

通过对约束最优问题的求解,得到最优解。其中约束是权重总和为1。

In [9]:

def statistics(weights):

weights = np.array(weights)

port_returns = np.sum(returns.mean()*weights)*252

port_variance = np.sqrt(np.dot(weights.T, np.dot(returns.cov()*252,weights)))

return np.array([port_returns, port_variance, port_returns/port_variance])

#最优化投资组合的推导是一个约束最优化问题

import scipy.optimize as sco

#最小化夏普指数的负值

def min_sharpe(weights):

return -statistics(weights)[2]

#约束是所有参数(权重)的总和为1。这可以用minimize函数的约定表达如下

cons = ({'type':'eq', 'fun':lambda x: np.sum(x)-1})

#我们还将参数值(权重)限制在0和1之间。这些值以多个元组组成的一个元组形式提供给最小化函数

bnds = tuple((0,1) for x in range(noa))

#优化函数调用中忽略的唯一输入是起始参数列表(对权重的初始猜测)。我们简单的使用平均分布。

opts = sco.minimize(min_sharpe, noa*[1./noa,], method = 'SLSQP', bounds = bnds, constraints = cons)

opts

Out[9]:

status: 0

success: True

njev: 4

nfev: 28

fun: -1.1623048291871221

x: array([ -3.60840218e-16, 2.24626781e-16, 1.63619563e-01,-2.27085639e-16, 8.36380437e-01])

message: 'Optimization terminated successfully.'

jac: array([ 1.81575805e-01, 5.40387481e-01, 8.18073750e-05, 1.03137662e+00, -1.60038471e-05, 0.00000000e+00])

nit: 4

得到的最优组合权重向量为:

In [10]:

opts['x'].round(3)

Out[10]:

array([-0. , 0. , 0.164, -0. , 0.836])

sharpe最大的组合3个统计数据分别为:

In [11]:

#预期收益率、预期波动率、最优夏普指数

statistics(opts['x']).round(3)

Out[11]:

array([ 0.508, 0.437, 1.162])

7.投资组合优化2——方差最小

接下来,我们通过方差最小来选出最优投资组合。

In [12]:

#但是我们定义一个函数对 方差进行最小化

def min_variance(weights):

return statistics(weights)[1]

optv = sco.minimize(min_variance, noa*[1./noa,],method = 'SLSQP', bounds = bnds, constraints = cons)

optv

Out[12]:

status: 0

success: True

njev: 7

nfev: 50

fun: 0.38542969450547221

x: array([ 1.14787640e-01, 3.28089742e-17, 2.09584008e-01, 3.53487044e-01, 3.22141307e-01])

message: 'Optimization terminated successfully.'

jac: array([ 0.3851725 , 0.43591119, 0.3861807 , 0.3849672 , 0.38553924, 0.])

nit: 7

方差最小的最优组合权重向量及组合的统计数据分别为:

In [13]:

optv['x'].round(3)

Out[13]:

array([ 0.115, 0. , 0.21 , 0.353, 0.322])

In [14]:

#得到的预期收益率、波动率和夏普指数

statistics(optv['x']).round(3)

Out[14]:

array([ 0.226, 0.385, 0.587])

8.组合的有效前沿

有效前沿有既定的目标收益率下方差最小的投资组合构成。

在最优化时采用两个约束,1.给定目标收益率,2.投资组合权重和为1。

In [15]:

def min_variance(weights):

return statistics(weights)[1]

#在不同目标收益率水平(target_returns)循环时,最小化的一个约束条件会变化。

target_returns = np.linspace(0.0,0.5,50)

target_variance = []

for tar in target_returns:

cons = ({'type':'eq','fun':lambda x:statistics(x)[0]-tar},{'type':'eq','fun':lambda x:np.sum(x)-1})

res = sco.minimize(min_variance, noa*[1./noa,],method = 'SLSQP', bounds = bnds, constraints = cons)

target_variance.append(res['fun'])

target_variance = np.array(target_variance)

下面是最优化结果的展示。

叉号:构成的曲线是有效前沿(目标收益率下最优的投资组合)

红星:sharpe最大的投资组合

黄星:方差最小的投资组合

In [16]:

plt.figure(figsize = (8,4))

#圆圈:蒙特卡洛随机产生的组合分布

plt.scatter(port_variance, port_returns, c = port_returns/port_variance,marker = 'o')

#叉号:有效前沿

plt.scatter(target_variance,target_returns, c = target_returns/target_variance, marker = 'x')

#红星:标记最高sharpe组合

plt.plot(statistics(opts['x'])[1], statistics(opts['x'])[0], 'r*', markersize = 15.0)

#黄星:标记最小方差组合

plt.plot(statistics(optv['x'])[1], statistics(optv['x'])[0], 'y*', markersize = 15.0)

plt.grid(True)

plt.xlabel('expected volatility')

plt.ylabel('expected return')

plt.colorbar(label = 'Sharpe ratio')

1、权重函数weight:用于为组合中的股票随机分配权重

2、投资组合函数portfolio:计算不同权重组合下的期望收益率、方差以及Sharpe比率

# 1、定义随机权重函数 def weight(n): w=np.random.random(n) return w/sum(w)weight(5)

下面,求Sharpe Ratio最大时的资产比例。

首先,我们选取股票组合。

#取上证50年化收益排名前五的证券作为投资组合 stock=w.wset("sectorconstituent", "date=2017-01-01sectorId=1000000087000000").Data[1]startdate='2020-03-01'enddate='2020-11-15' #定义收益率计算函数def ret(stock): error_code,data=w.wsd(stock, "close",startdate, enddate, "",usedf=True) return np.log(data/data.shift(1)) #采用对数收益率计算方法ret(stock).head()

# 对上证50所有股票的年化收益率进行排名r=ret(stock).mean()*252 #求年化收益率 r=pd.DataFrame(r,columns=['returns']) r=r.sort_index(axis = 0,ascending = False,by = 'returns') r.head(10)

#取出收益率最高的前5名股票建立投资组合 p_stock=list(r[0:5].index.values)p_stock # 绘制股票收盘价走势图 error_code,data=w.wsd(p_stock, "close",startdate, enddate, "",usedf=True) (data/data.ix[0]-1).plot(figsize=(14,7.5)) plt.grid()

# 3、optimize是寻找最小值,这里我们求夏普负值的最小值即为夏普最大值 def min_sharpe(w): return -portfolio(returns,w)[2]cons = ({'type':'eq','fun':lambda w:np.sum(w)-1}) res = minimize(min_sharpe,weight(5),bounds=((0,1),(0,1),(0,1),(0,1),(0,1)),constraints = cons) res #最优组合权重,取小数点后三位 weight=res['x'].round(3)weight

array([0.193, 0.803, 0.004, 0. , 0. ])

#sharpe 最大时的组合收益、方差以及sharpe p_opt=portfolio(returns,res['x']) p_opt

输出结果为:

(0.6678337301412707, 0.28040534834834024, 2.2789641278432953)

print("可以看出Sharpe最大时的组合最优解是:")print("组合收益:",'%.2f%%' % (p_opt[0] * 100))print("组合标准差(波动率):",'%.2f%%' % (p_opt[1] * 100) )print("组合sharpe:",'%.2f' % (p_opt[2] ) )

输出结果为:

可以看出Sharpe最大时的组合最优解是;

组合收益:66.78%

组合标准差(波动率):28.04%

组合sharpe: 2.28

# 星号构成的曲线是有效前沿(目标收益率下最优的投资组合) plt.figure(figsize = (14,8)) #圆圈:蒙特卡洛随机产生的组合分布 plt.scatter(p_std, p_mean, c=p_sharpe, marker = 'o') #最小方差组合 plt.scatter(t_std,t_returns, c = (np.array(t_returns)-r_f)/t_std,marker = '*') #有效前沿 plt.plot(e_std,e_returns,'r.',markersize=5) #画出Sharpe最大时的点 plt.plot(portfolio(returns,res['x'])[1],portfolio(returns,res['x'])[0],'r*',markersize=20) plt.grid(True) plt.xlabel('std') plt.ylabel('mean') plt.colorbar(label = 'Sharpe') plt.title('Mean and Std of Returns')

1952年,马科维茨在《金融杂志》上发表了一篇题为“资产组合的选择”的文章,首次提出了均值方差模型,该模型解决了投资收益率与风险的度量问题,把投资风险分解为系统风险和非系统风险,通过持有多种类型的证券来分散非系统风险,从而降低整个投资组合的风险。但是这一模型也有一定的局限性,它没有进一步说明如何为证券估值和定价,也不能说明投资组合期望回报率与风险的关系,其理论难以付诸实际应用。

随后夏普、林特耐、莫辛三人分别于1964年、1965年和1966年独立研究出著名的资本资产定价模型,从而解决了马科维茨投资模型的局限问题,使得在大型证券组合应用中的计算大大减少,从而提高了投资组合理论的指导作用和实际应用价值。下面对投资组合的理论模型及运用予以介绍:

一、 什么是均值方差模型

均值方差模型是用收益率的期望值来度量收益,用收益率的标准差来度量风险,从而推导出现代投资组合理论基础,即投资者应该通过购买多种证券而不是一种证券进行分散化投资。这一理论假设投资者都是厌恶风险的,在风险确定的情况下,会选择期望收益最大的投资组合,在收益确定的情况下,会选择风险最小化的投资组合,通过对每种证券的期望收益率、收益率的方差和每一种证券与其他证券之间的相互关系,这三类信息的适当分析,可以从理论上识别出有效投资组合。

1、单个资产均值方差模型

单个资产方差均值计算公式为:

该公式表示:方差=(实际收益率-期望收益率)的平方*发生的概率的累加和。

单个资产的期望收益率是资产的各种可能的收益率加权后的平均值,又叫做平均收益率,如果以r代表收益率,那么r的期望表示为E(r):

标准差是方差的平方根,计算公式为:

2、 两个资产均值方差模型

对于两个资产i、j组成的投资组合,其收益率方差的计算公式为:

Cov(ri,rj)是资产i和资产j的协方差。它是指两个资产之间的相关性,计算公式为:

如果使用历史上m期样本计算资产i和j的收益率的协方差,公式为:

两个资产收益率的相关性系数是协方差除以两个证券各自标准差的乘积,公式为:

相关系数取值范围为[-1,+1],当大于0时,表示两变量正线性相关,小于0时,表示负线性相关,等于1时为完全正相关,等于-1时为完全负相关,等于0时无相关性

2、 投资组合的均值方差模型

投资组合收益率的方差和标准差,取决于单个资产的方差、权重和互相之间的相关系数,方差计算公式为:

投资组合的标准差的计算公式为:

以上公式中,w代表资产的权重,由公式可知,资产组合的方差是单一资产的方差与资产相关系数的组合。单一资产的方差不变,相关系数越小,资产组合的方差也越小。

4、投资最优组合

如果把所有的投资组合都描述在收益率和标准差的坐标图中,这是一条凸向纵轴的曲线,曲线最左边存在一个拐点,此处的标准差是所有组合中最小的,叫做全局最小方差组合,也是投资最优组合。此点也是曲线上半部分和下半部分的交界处,上半部分的点在风险水平一定的情况下,具有更高的收益率,因此,上半部分也叫做马科维茨有效前沿,简称有效前沿。

二、什么是资本配置模型

资本配置模型也叫资本配置方程,它是威廉.夏普在马科维茨的有效前沿的基础上,引入无风险资产,形成风险资产和无风险资产的投资组合,这一组合的期望收益率就是风险资产和无风险资产的加权平均值。

1、 资本配置模型的推导过程

对于一个由风险资产x和无风险资产组成的投资组合,其中风险资产x的权重为Wx,收益率为Rx,标准差为Sx,无风险资产的权重为(1-Wx),收益率为Rf,标准差为0,那么投资组合的期望收益率为:

E(Rp)=(1-Wx)Rf+WxE(Rx)=Rf+Wx(E(Rx)-Rf)

根据投资组合的方差公式,得出标准差为:

Sp=Wx*Sx,Wx=Sp/Sx,带入期望收益率的计算公式里得到资本配置方程:

E(Rp)=Rf+[(E(Rx)-Rf)/Sx]*Sp

资本配置方程线上的点,表示无风险资产与风险资产的线性组合,其截距是无风险收益率Rf,斜率是 (E(Rx)-Rf)/Sx ,称为夏普比率,表示每一风险单位的超额收益率。

2、 资本市场线

资本市场线是资本配置线与马科维茨有效前沿相切的一条直线,它取代了马科维茨有效前沿,称为新的有效前沿。当市场达到均衡时,切点M即为市场投资组合,因为资本市场线上的所有点的斜率是一样的,所以得出资本市场线的公式为:

E(Rp)=Rf+[(E(Rm)-Rf)/Sm]*Sp

这表明,投资者是用无风险资产和市场组合M来构造一个适合自己需求的最优投资组合。

3、 资本市场线的意义

资本市场线实际上说明了有效投资组合风险与预期收益率之间的关系,提供了衡量有效投资组合风险的方法,用标准差来度量风险,预期收益率是标准差的线性函数。对于每一个有效投资组合,给定其风险的大小,就可以根据资本市场线知道其预期收益率的大小。

三、资本资产定价模型

资本资产定价模型是以马科维茨证券组合理论为基础,研究如果投资者都按照分散化的理念去投资,最终证券市场达到均衡时,价格和收益率如何决定的问题。

1、 CAPM的主要事项

CAPM使用贝塔系数来描述资产或资产组合的系统风险的大小。贝塔系数表示资产对市场收益变动的敏感性。在充分分散化的投资组合中,单个证券对组合风险的贡献取决于该证券的系统风险,证券的系统风险是用贝塔系数来衡量的。由此可以得出资本资产定价的模型公式:

E(Ri)=Rf+Bi[E(Rm)-Rf],E(Ri)-Rf=Bi[E(Rm)-Rf]

式中,E(Ri)为资产的期望收益率,Bi为资产贝塔系数,E(Rm)为市场组合的期望收益率,Rf是无风险收益率,

CAPM说明了资产的期望收益率与系统风险之间的正向关系,即任何资产的市场风险溢价,等于资产的系统性风险乘以市场组合的风险溢价。

2、 证券市场线SML

预期收益与贝塔系数的关系式可以表示成证券市场线,证券市场线的斜率是市场组合的风险溢价。它是在资本市场线的基础上发展起来的,资本市场线给出了所有有效投资组合风险与预期收益率之间的关系。证券市场线给出了每一个风险资产的风险与预期收益的关系,因此,证券市场线能为每一个风险资产进行定价,这就是CAPM的核心。

3、 证券市场线与资本市场线的区别

它们的区别提现在一下四个方面:

(1)风险的衡量:证券市场线是用系统性风险贝塔系数来衡量,资本市场线是用组合的标准差来衡量。

(2)作用不同:证券市场线是决定资产最合理的预期收益率,即给证券定价,资本市场线是决定最合适的资产配置点,即资产配置。

(3)斜率不同:证券市场线的斜率是市场组合的风险溢价,资本市场线的斜率是市场组合的夏普比率。

(4)适用范围不同:证券市场线即适用于单个资产,又适合于投资组合,资本市场线只适用于有效投资组合。

4、 CAPM的应用

证券市场线可以用来判断一项资产的定价是否合理。如果一项资产的定价合理,那么其就应该在SML线上,如果一个资产的价格被高估,其应当位于SML线下方,如果一个资产的价格被低估,其应当位于SML线上方。对于价格被高估的资产我们应该卖出,价格被低估的资产我们应该买入。

四、资产配置与投资组合的构建

资产配置是投资组合管理过程中的重要环节之一,也是决定投资组合相对业绩的主要因数,最重要的作用是帮助投资者降低单一资产的非系统性风险,其目标是协调提高收益和降低风险的关系,这与投资者的特征和需求密切相关,短期投资者与长期投资者、个人投资者和机构投资者对资产配置会有不同的选择。

1、 资产配置

资产配置是根据投资者需求将投资资金在不同资产类别之间分配,是在投资者可承受的风险水平上构造能够提供最高预期收益的资金配置方案的过程,包括战略配置、战术配置以及影响资产配置的主要因素。

(1)战略配置:是为了满足投资者风险与收益目标所做的长期资产配比;是根据投资者的风险承受能力,对资产做出一种事前的、整体性的、最能满足投资者需求的规划和安排;是反映投资者的长期投资目标和策略,确定各主要大类资产的投资比例,建立最佳长期资产组合结构。

(2)战术配置:是一种根据对短期资本市场环境及经济条件的预测,积极、主动地对资产配置状态进行动态调整,从而增强投资组合价值的积极战略。战术配置更多地关注市场的短期波动,强调根据市场的变化,运用金融工具,通过择时调节各大类资产之间的分配比例,来管理短期的投资收益和风险。战术配置的周期一般在一年以内,如月度、季度。

(3)影响资产配置的因素

影响投资者风险承受能力和收益要求的因素是投资者的年龄、投资周期、资产负债状况、财务变动状况与趋势、财富净值和风险偏好等。

影响各类资产的风险、收益状况以及相关关系的资本市场环境因素包括国际经济形势、国内经济状况与发展动力、通货膨胀、利率变化、经济周期波动和监管等。

影响资产配置的因素还包括资产的流动性、投资期限和税收考虑等。

2、 股票投资组合构建

股票投资构建通常由自上而下、自下而上两种策略。自上而下策略可以通过研究和预测决定经济形势的几个核心变量,如消费者信心、商品价格、利率、通货膨胀、GDP等宏观形势、行业和板块特征来决定大类资产配置。自下而上策略是依赖个股筛选的投资策略,关注的是各家公司的表现,而非经济或市场整体趋势,因而自下而上策略并不重视行业配置。实际应用中,可采取两种策略相结合的方式。无论哪种方式都受到投资合同、投资政策、管理能力等方面的约束。

3、 债券投资组合构建

债券投资主要分析指标有到期收益率、利率期限结构、久期、凸性等。自上而下的债券配置从宏观上把握债券投资的总体风险开始,分析包括市场风险和信用风险,进而决定在不同的信用等级、行业类别上的配置比例,通过大类资产配置、类属资产配置和个券选择三个层次自上而下地决策,最终实现投资目标。

以上介绍了均值方差模型、资本配置模型和资本资产定价模型,以及上述理论在构建投资组合中的实际应用。

o