投资组合管理

本文通过对沪深300指数的正态性检验,发现其收益率并非正态分布,存在厚尾现象。进一步,运用描述性统计和J-B检验确认了这一结论。接着,文章探讨了均值-方差投资组合理论,计算了5只基金的收益率均值和协方差,并通过蒙特卡洛模拟找到最优投资组合,以最大化夏普比率和最小化方差,展示了有效边界和投资组合的优化结果。
摘要由CSDN通过智能技术生成

第一部分:沪深300指数正态性检验
正态分布是金融学中的最重要的分布,也是金融学理论的主要统计学基础之一。

a.投资组合理论:当股票收益率呈正态分布时,最优化投资组合可以在如下假设中选择:只有平均收益和收益的方差以及不同的股票之间的协方差与投资决策相关。
b.资本性资产定价模型:当股票收益呈现正态分布时,单独证券的价格可以很好地以某种大规模市场指数的关系表示。
c.有效市场假设:有效市场是指价格反映所有可用信息的市场,若假设成立,股票价格波动则是随机的,那么收益则呈现正态分布。
d.期权定价理论:著名的BSM期权定价模型中一个重要的假设为股票收益呈正态分布。

那么,在现实的资本市场中,正态性的假设不一定是成立的。
为了验证,从以下几个方面对沪深300指数数据进行分析,数据时间为2015年1月5日到2021年2月10日。

import math
import numpy as np
import pandas as pd
import scipy.stats as scs
import statsmodels.api as sm
import matplotlib as mpl
import matplotlib.pyplot as plt
mpl.rcParams['font.family'] = 'serif'

def dN(x, mu, sigma):
    ''' Probability density function of a normal random variable x.

    Parameters
    ==========
    mu : float
        expected value #平均值/期望值
    sigma : float
        standard deviation #标准差

    Returns
    =======
    pdf : float
        value of probability density function #概率密度函数
    '''
    z = (x - mu) / sigma #正态分布的标准化,z服从标准正态分布
    pdf = np.exp(-0.5 * z ** 2) / math.sqrt(2 * math.pi * sigma ** 2) #z的概率密度函数
    return pdf

#引入数据
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import pandas as pd 
import matplotlib.dates as mdates
fig=plt.figure(figsize=(12,6)) 
data = pd.read_csv('C:/Users/gws/Desktop/沪深300指数历史数据.csv')
data['returns'] = np.log(data['price'] / data['price'].shift(1))
times = pd.read_excel(r'C:/Users/gws/Desktop/time.xlsx')
# 指数日报价
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import pandas as pd 
import matplotlib.dates as mdates
data = pd.read_csv('C:/Users/gws/Desktop/沪深300指数历史数据.csv')


plt.figure(figsize=(9, 6)) 
x_time=times
y_index=data['price']
plt.plot(x_time,y_index)
plt.legend()
plt.xlabel('time')

ax=fig.add_subplot(111) 
ax.xaxis.set_major_formatter(mdates.DateFormatter("%Y-%m-%d"))
plt.ylabel('daily quotes')

# 指数日对数价格波动率
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import pandas as pd 
import matplotlib.dates as mdates

data = pd.read_csv('C:/Users/gws/Desktop/沪深300指数历史数据.csv')
data['returns'] = np.log(data['price'] / data['price'].shift(1))


plt.plot(times,data['returns'],color='b',linewidth=3)

plt.xlabel('TIME')
ax=fig.add_subplot(111) 
ax.xaxis.set_major_formatter(mdates.DateFormatter("%Y-%m-%d"))
plt.ylabel('Daily log returns')
plt.show()

以上分析得到沪深300指数的日报价波动率和日对数收益率波动率。
沪深
在这里插入图片描述

# 指数日对数收益率图
def return_histogram(data):
    ''' Plots a histogram of the returns. '''
    plt.figure(figsize=(9, 5))
    x = np.linspace(min(data['returns']), max(data['returns']), 100)
    plt.hist(np.array(data['returns']), bins=50, density=True) #normed改成density
    y = dN(x, np.mean(data['returns']), np.std(data['returns'])) #求收益率的均值和方差
    plt.plot(x, y, linewidth=2)
    plt.xlabel('log returns')
    plt.ylabel('frequency/probability')
    plt.grid(True)
return_histogram(data)

以上分析得到日对数收益率的直方图。
在这里插入图片描述

# QQ图
sm.qqplot(data['returns'].dropna(),line = 's')
plt.grid(True)
plt.xlabel('theoretical quantiles')
plt.ylabel('sample quantiles')

以上分析得到沪深300指数对数收益率的QQ图
在这里插入图片描述
以上的图形可以初步判断,沪深300指数的收益率不是正态分布的。

接下来通过描述性统计来继续证明。

# 描述性统计分析
import numpy as np
import matplotlib.pyplot as plt
import math
import numpy as np
import quandl
import scipy.stats as stats

# print(data['returns'])
print('均值:',np.mean(data['returns'])) #均值
print('最小值:',np.min(data['returns'])) #最小值
print('最大值:',np.max(data['returns'])) #最大值
print('标准差:',np.std(data['returns'])) #标准差
print('方差:',np.var(data['returns'])) #方差
print('偏度:',pd.Series(data['returns']).skew())#偏度
print('峰度:',pd.Series(data['returns']).kurt()) #峰度

# J_B检验
import numpy as np
import scipy.stats as stats
def self_JBtest(y):
    n = y.size
    y_ = y - y.mean()   
    """
    M2:二阶中心钜
    skew 偏度 = 三阶中心矩 与 M2^1.5的比
    krut 峰值 = 四阶中心钜 与 M2^2 的比
    """
    M2 = np.mean(y_**2)
    skew =  np.mean(y_**3)/M2**1.5
    krut = np.mean(y_**4)/M2**2
    """
    计算JB统计量,以及建立假设检验
    """
    JB = n*(skew**2/6 + (krut-3 )**2/24)
    pvalue = 1 - stats.chi2.cdf(JB,df=2)
    print("JB检验:",stats.jarque_bera(y))    
    return np.array([JB,pvalue])
print(self_JBtest(data['returns']))

以上的结果为:

均值: 0.0003134864995930646
最小值: -0.09154437253073909
最大值: 0.06498873052235105
标准差: 0.015329468087087158
方差: 0.00023499259183302362
偏度: -1.015554440888655
峰度: 6.3043654925582535
JB检验: Jarque_beraResult(statistic=nan, pvalue=nan)
[2703.43766602    0.        ]

以上数据中,样本峰度为6.304,可以看出样本分布存在厚尾现象。所以可以判断沪深300指数的收益率不呈现正态分布,所以市场收益率的正态假设不成立。

第二部分:均值-方差投资组合理论

a.马科维茨均值-方差模型为多目标优化问题,有效前沿即多目标优化问题的pareto解(风险一定,收益最大;收益一定,风险最小)
b.马科维茨模型以预期收益率期望度量收益,以收益率方差度量风险

一般用均值方差理论来研究股票投资组合,这里用来研究基金的投资组合。
选取5只基金数据,时间从20191月1日年到2021年2月10日。

1.5只基金的净值数据如图所示。
在这里插入图片描述

2.计算不同基金的均值、协方差

2.1 基金收益率的均值
每年252个交易日,用每日收益得到年化收益。

returns1 = np.log(p1 / p1.shift(1))
print('a005827的均值为:',returns1.mean()*252)
returns2 = np.log(p2 / p2.shift(1))
print('a118001的均值为:',returns2.mean()*252)
returns3 = np.log(p3 / p3.shift(1))
print('a003095的均值为:',returns3.mean()*252)
returns4 = np.log(p4 / p4.shift(1))
print('a002891的均值为:',returns4.mean()*252)
returns5 = np.log(p5 / p5.shift(1))
print('a260108的均值为:',returns5.mean()*252)

结果为

a005827的均值为: 0.6722697561451413
a118001的均值为: 0.39795665784070866
a003095的均值为: 0.6318566234567989
a002891的均值为: 0.6283258141278733
a260108的均值为: 0.6174217494140353

2.2 基金收益率的协方差

计算投资资产的协方差是构建资产组合过程的核心部分。运用pandas内置方法生产协方差矩阵。

import pandas as pd
df = pd.DataFrame({
    'returns1': list(returns1)[1:],
    'returns2': list(returns2)[1:],
    'returns3': list(returns3)[1:],
    'returns4':list(returns4)[1:],
    'returns5':list(returns5)[1:]})
df_corr = df.corr()
# 可视化
import matplotlib.pyplot as mp, seaborn
seaborn.heatmap(df_corr, center=0, annot=True, cmap='YlGnBu')
mp.show()

在这里插入图片描述

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

weights = np.random.random(5)
weights /= np.sum(weights)
weights

比重如下

array([0.19022422, 0.26289541, 0.2368989 , 0.1765832 , 0.13339827])

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

np.sum(returns.mean()*weights)*252
np.dot(weights.T, np.dot(df_corr,weights))
np.sqrt(np.dot(weights.T, np.dot(df_corr,weights)))

结果如下

0.5895661201969116
0.24679615559426255
0.4967858246712184

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

得到随机权重投资组合散点图如下:
在这里插入图片描述

2.6投资组合的优化

2.6.1 得到夏普比率最大时的期望收益

def statistics(weights):
    weights = np.array(weights)
    port_returns = np.sum(ret*weights)*252
    port_variance = np.sqrt(np.dot(weights.T, np.dot(df_corr,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

得到的结果如下:

fun: -1.3002339742302418
     jac: array([-6.55651093e-07,  6.04987144e-06,  8.98540020e-06, -1.29044056e-05,
       -1.11758709e-06])
 message: 'Optimization terminated successfully'
    nfev: 47
     nit: 7
    njev: 7
  status: 0
 success: True
       x: array([0.2446469 , 0.09458952, 0.24748957, 0.18258173, 0.23069229])

得到的最优权重组合为:

array([0.245, 0.095, 0.247, 0.183, 0.231])

使用最优化得到投资组合的权重,得到以下统计结果

array([0.616, 0.473, 1.3  ])

由此可知,预期收益率为61.6%,预期波动率为47.3%,得到的最优夏普指数为1.3

2.6.2 投资组合优化-方差最小

通过计算得到结果如下:

fun: 0.4661049635012212
     jac: array([0.46630891, 0.46531815, 0.46595777, 0.46669132, 0.46624486])
 message: 'Optimization terminated successfully'
    nfev: 22
     nit: 3
    njev: 3
  status: 0
 success: True
       x: array([0.21494791, 0.17201182, 0.23323061, 0.16222558, 0.21758409])

可以得到绝对方差最小投资组合

array([0.215, 0.172, 0.233, 0.162, 0.218])

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

array([0.597, 0.466, 1.28 ])

可知,预期收益率为59.7%,预期波动率为46.6%,预期夏普指数为1.28

2.7 组合的有效边界

所谓最优投资组合,即目标收益率水平下波动率最小。

下图是最优化结果的展示:

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

红星:sharpe最大的投资组合

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

在这里插入图片描述

有效边界由所有收益率高于绝对最小方差的投资组合的最优投资组合构成,这些投资组合在给定某一风险水平的预期收益率上优于其他投资组合。

2.8 投资组合回测

通过模拟得到组合投资权重为:
a005827的权重为: 0.245
a118001的权重为: 0.095
a003095的权重为: 0.247
a002891的权重为: 0.182
a260108的权重为: 0.231

回测结果为:

第一列为夏普比率,第二列为波动率,第三列为最大回撤。一般认为夏普比率越高挣钱效应越好,波动率和最大回测越大风险越大。
在这里插入图片描述
在这里插入图片描述

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

马尔可夫宽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值