Python金融大数据分析——第11章 统计学(2)投资组合优化 笔记
- 第11章 统计学
- 11.2 投资组合优化
- 11.2.1 数据
- 11.2.2 基本理论
- 11.2.3 投资组合优化
- 11.2.4 有效边界
- 11.2.5 资本市场线
- 11.2 投资组合优化
第11章 统计学
11.2 投资组合优化
现代 / 均值-方差投资组合理论(MPT)是金融理论的重要基础。正态分布收益率假设是该理论的基础:
只观察均值和方差, 我们必然假定没有必要用其他统计数字描述期末财富的分布。除非投资者有特殊的效用函数(二次效用函数), 否则有必要假设收益率呈正态分布, 用均值和方差就可以完整地描述。
11.2.1 数据
我们选择 5 种不同资产以提供分析:军工类股票 中国卫星 (600118)、中兵红箭 (000519) 、航天动力 (600343) ,以及浦发银行(600000 )和 中证500指数基金 500ETF (510500 )。
import numpy as np
import pandas as pd
import tushare as ts
import matplotlib.pyplot as plt# 军工类股票 中国卫星 (600118)、中兵红箭 (000519) 、航天动力 (600343) ,
# 以及浦发银行(600000 )和 中证500指数基金 500ETF (510500 )
symbols = ['600118', '000519', '600343', '600000', '510500']indexes = pd.date_range('2014-01-01', '2018-07-06')
# 为了保持和从toshare获取的时间序列类型一致,这里把时间类型转为字符串
indexes = indexes.map(lambda x: datetime.datetime.strftime(x, '%Y-%m-%d'))data = pd.DataFrame(index=indexes)
for sym in symbols:k_d = ts.get_k_data(sym, '2014-01-01', ktype='D')# 如果上面的时间序列不转成字符串,这里就要转成时间序列,以保持index类型一致# k_d['date'] = k_d['date'].astype('datetime64[ns]')k_d.set_index('date', inplace=True)data[sym] = k_d['close']
data = data.dropna()(data / data.ix[0] * 100).plot(figsize=(8, 5))
一段时间的股票价格走势
# 均值-方差指的是不同证券(对数)收益的均值和方差, 可以这样计算:
rets = np.log(data / data.shift(1))
# 在这些时间序列数据中, 可以看到年化收益表现的显著差异。
# 我们使用 252 个交易日,从每日收益得出年化收益:
rets.mean() * 252
# 600118 0.006067
# 000519 -0.038631
# 600343 0.068651
# 600000 0.140085
# 510500 0.428569
# dtype: float64# 投资资产的协方差矩阵是整个投资组合选择过程的核心部分
rets.cov()*252
# 600118 000519 600343 600000 510500
# 600118 0.237557 0.107797 0.177612 0.017609 0.102007
# 000519 0.107797 0.209140 0.123730 0.012978 0.062838
# 600343 0.177612 0.123730 0.238805 0.013859 0.095337
# 600000 0.017609 0.012978 0.013859 0.064694 0.022098
# 510500 0.102007 0.062838 0.095337 0.022098 0.510833
11.2.2 基本理论
下面,我们假定投资者不允许在某种证券上建立空头头寸。 只允许多头头寸意味着投资者的财富将在可用资产中分配。所有头寸均为多头(正)头寸,且头寸的总和为 100%。例如, 可以在 5 种证券中投入相同的资金量(每种 20%)。
# 生成 5 个 0 到 1之间的随机数,
# 然后对这些数值进行规范化,使所有值的总和为1
noa = 5
weights = np.random.random(noa)
weights /= np.sum(weights)
weights
# array([ 0.21076189, 0.23917961, 0.1825734 , 0.03619006, 0.33129504])
现在可以检查资产权重综合确实为1 ;也就是说∑Iwi=1∑Iwi=1\sum_I w_i=1 , 其中 I 是资产的数量,wi≥0wi≥0 w_i\geq 0 是资产的权重。 下面公式提供在给定单一证券权重情况下的预期投资组合收益。 这是假定历史平均表现是未来(预期)表现的最佳预测因素时的预期投资收益公式。公式中,riri r_i 是状态相关未来收益(由假定为正态分布的收益值组成的向量), 而 μiμi\mu_i 是证券i的预期收益。 最后, WTWTW^T 是权重向量的转置,μμ\mu是预期证券收益的向量。
公式 预期收益一般公式
\begin{aligned} \mu_p &=E\left ( \sum_I w_i r_i \right) \\ &= \sum_I w_iE(r_i) \\ &=\sum_I w_i \mu_i \\ &=w^T \mu \end{aligned}
MPT中选择的第二个对象是预期投资组合方差。 两种证券之间的协方经定义为σij=σji=E(ri−μi)(rj−μj)σij=σji=E(ri−μi)(rj−μj)\sigma_{ij}=\sigma_{ji}=E(r_i-\mu_i)(r_j-\mu_j)。证券的方差是与自身的协方差的特例:σ2i=E((ri−μi)2)σi2=E((ri−μi)2)\sigma_i^2=E((ri-\mu_i)^2)。下面公式提供了一个证券投资组合的协方差矩阵(假定每种证券的权重均为1 )。
公式 投资组合协方差矩阵
\sum= \begin{bmatrix} \sigma_1^2 & \sigma_{12} & \cdots &\sigma_{1I} \\ \sigma_{21} & \sigma_2^2 & \cdots &\sigma_{2I} \\ \vdots & \vdots & \ddots & \vdots \\ \sigma_{I1} & \sigma_{I2} & \cdots & \sigma_I^2 \\ \end{bmatrix}
公式 预期投资组合方差一般公式
\begin{aligned} \sigma_p^2 &=E((r-\mu)^2) \\ &=\sum_{i \in I}\sum_{j \in I} w_i w_j \sigma_{ij} \\ &= w^T \sum w \end{aligned}
# 预期投资组合方差
np.dot(weights.T, np.dot(rets.cov() * 252, weights))
# 0.14184053722017648# 预期投资组合标准差
#(预期)投资组合标准差(波动率)只需要计算一次平方根即可得到
np.sqrt(np.dot(weights.T, np.dot(rets.cov() * 252, weights)))
# 0.37661722905381861
投资者最感兴趣的是给定证券组合的风险-收益均衡性及其统计学特性。为此.我们实施一次蒙特卡洛模拟,生成较大规模的随机投资组合权重向量。对于每一种模拟的分配,我们记录得出的预期投资组合收益和方差:
prets = []
pvols = []
for p in range(2500):weights = np.random.random(noa)weights /= np.sum(weights)prets.append(np.sum(rets.mean() * weights) * 252)pvols.append(np.sqrt(np.dot(weights.T, np.dot(rets.cov() * 252, weights))))prets = np.array(prets)
pvols = np.array(pvols)plt.figure(figsize=(8, 4))
plt.scatter(pvols, prets, c=prets / pvols, marker='o')
plt.grid(True)
plt.xlabel('expected volatility')
plt.ylabel('expected return')
plt.colorbar(label='Sharpe ratio')
不同/随机投资组合极重的预期收益和波动率
上图展示了蒙特卡洛模拟的结果。还提供了定义为 SR≡μp−rfσpSR≡μp−rfσp SR \equiv \frac{\mu_p-r_f}{\sigma_p} 的夏普指数(即预期投资组合超额收益)。也就是投资收益率超过无风险利率 rfrfr_f 的部分除以预期投资组合标准差。为了简单起见,我们假定 rf=0rf=0r_f=0。
从均值和方差考量, 并不是所有权重分布都表现良好。例如, 对于固定风险水平(如30%), 多种组合都表现出不同的收益。作为投资者, 人们通常对周定风险水平的最大收益率或者固定收益率预期下的最小风险感兴趣。 这两种投资组合组成所谓的有效边界, 这是本节后面所要得到的结果。
11.2.3 投资组合优化
# 生成 5 个 0 到 1之间的随机数,
# 然后对这些数值进行规范化,使所有值的总和为1
noa = 5
weights = np.random.random(noa)
weights /= np.sum(weights)
weights
# array([ 0.21076189, 0.23917961, 0.1825734 , 0.03619006, 0.33129504])# 预期投资组合方差
np.dot(weights.T, np.dot(rets.cov() * 252, weights))
# 0.14184053722017648# 预期投资组合标准差
# (预期)投资组合标准差(波动率)只需要计算一次平方根即可得到
np.sqrt(np.dot(weights.T, np.dot(rets.cov() * 252, weights)))
# 0.37661722905381861prets = []
pvols = []
for p in range(2500):weights = np.random.random(noa)weights /= np.sum(weights)prets.append(np.sum(rets.mean() * weights) * 252)pvols.append(np.sqrt(np.dot(weights.T, np.dot(rets.cov() * 252, weights))))prets = np.array(prets)
pvols = np.array(pvols)plt.figure(figsize=(8, 4))
plt.scatter(pvols, prets, c=prets / pvols, marker='o')
plt.grid(True)
plt.xlabel('expected volatility')
plt.ylabel('expected return')
plt.colorbar(label='Sharpe ratio')# 11.2.3 投资组合优化
# 首先建立一个方便的函数,为输入的权重向量 / 数组给出重要的投资组合统计数字:
def statistics(weights):"""Return portfolio statistics:param weights: weights for different securities in portfolio:return:pret:floatexpected portfolio returnpvol:floatexpected portfolio volatilitypret/pvol:floatSharpe ratio for rf=0"""weights = np.array(weights)pret = np.sum(rets.mean() * weights) * 252pvol = np.sqrt(np.dot(weights.T, np.dot(rets.cov() * 252, weights)))return np.array([pret, pvol, pret / pvol])# 最优化投资组合的推导是一个约束最优化问题
import scipy.optimize as sco# 最小化函数minimize很通用,考虑了参数的(不)等式约束和参数的范围。
# 我们从夏普指数的最大化开始。 正式地说,最小化夏普指数的负值:
def min_func_sharpe(weights):return -statistics(weights)[2]# 约束是所有参数(权重)的总和为1。 这可以用minimize函数的约定表达如下
cons = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1})# 我们还将参数值(权重)限制在0和l之间。 这些值以多个元组组成的一个元组形式提供给最小化函数:
bnds = tuple((0, 1) for x in range(noa))# 优化函数调用中忽略的唯一输入是起始参数列表(对权重的初始猜测)。我们简单地使用平均分布:
noa * [1. / noa, ]
# [0.2, 0.2, 0.2, 0.2, 0.2]%%time
opts = sco.minimize(min_func_sharpe, noa * [1. / noa, ], method='SLSQP', bounds=bnds, constraints=cons)
# Wall time: 1.2 sopts
# fun: -0.7689821435140733
# jac: array([3.62539694e-01, 3.84121098e-01, 1.03567891e-01,
# -1.06185675e-04, 2.67580152e-04])
# message: 'Optimization terminated successfully.'
# nfev: 59
# nit: 8
# njev: 8
# status: 0
# success: True
# x: array([2.69140628e-17, 5.93820112e-17, 0.00000000e+00,
# 7.15876612e-01, 2.84123388e-01])opts['x'].round(3)
# array([ 0. , 0. , 0. , 0.716, 0.284])# 最优化工作得出 一个投资组合,仅由5种资产中的2种组成# 使用优化中得到的投资组合权重, 得出如下统计数字
statistics(opts['x'].round(3))
# array([ 0.22201418, 0.28871174, 0.76898216])
# 预期收益率约为22.2%. 预期被动率约为28.9%, 得到的最优夏普指数为0.77# 接下来, 我们最小化投资组合的方差。
# 这与被动率的最小化相同,我们定义一个函数对方差进行最小化:
def min_func_variance(weights):return statistics(weights)[1]**2optv = sco.minimize(min_func_variance, noa * [1. / noa, ], method='SLSQP', bounds=bnds, constraints=cons)
optv
# fun: 0.05137907199877911
# jac: array([0.10326265, 0.10273764, 0.10269385, 0.10276436, 0.102121])
# message: 'Optimization terminated successfully.'
# nfev: 71
# nit: 10
# njev: 10
# status: 0
# success: True
# x: array([0.04526382, 0.1335909, 0.05702634, 0.73177776, 0.03234118])optv['x'].round(3)
# array([ 0.045, 0.134, 0.057, 0.732, 0.032])
# 投资组合中加入了全部资产。 这种组合可以得到绝对值最小方差投资组合
# 得到的预期收益率、波动率和夏普指数如下:
statistics(optv['x']).round(3)
# array([ 0.115, 0.227, 0.509])
11.2.4 有效边界
所有最优化投资组合——即目标收益率水平下波动率最小的所有投资者(或者给定风险水平下收益率最大的所有投资组合)——的求取都和上述最优化过程类似。 唯一的区别是我们必须循环使用多种起始条件。 最优化采用两种条件: 一是目标收益率水平tret , 另一个和以前一样是投资组合权重的总和。每个参数的边界值保持不变:
def min_func_port(weights):return statistics(weights)[1]# 在不同目标收益率水平( trets )中循环时。 最小化的一个条件会变化。
# 这就是每次循环中更新条件字典对象的原因:trets = np.linspace(0.0, 0.25, 50)
tvols = []
bnds = tuple((0, 1) for x in weights)
for tret in trets:cons = ({'type': 'eq', 'fun': lambda x: statistics(x)[0] - tret},{'type': 'eq', 'fun': lambda x: np.sum(x) - 1})res = sco.minimize(min_func_port, noa * [1. / noa, ], method='SLSQP', bounds=bnds, constraints=cons)tvols.append(res['fun'])
tvols = np.array(tvols)plt.figure(figsize=(8,4))
# random portfolio composition
plt.scatter(pvols,prets,c=prets/pvols,marker='o')
# efficient frontier
plt.scatter(tvols,trets,c=trets/tvols,marker='x')
# portfolio with highest Sharpe ratio
plt.plot(statistics(opts['x'])[1],statistics(opts['x'])[0],'r*',markersize=15.0)
# minimum variance portfolio
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')
给定收益率水平的最小凤险投资组合(变叉)
上图展示了最优化的结果。交叉表示给定某个目标收益率的最优投资组合:小点和以前一样表示随机组合。此外, 该图还展示了两个较大的星号: 一个表示最小波动率 / 方差投资组合(最左侧的组合), 另一个表示具有最大夏普指数的投资组合。
有效边界由所有收益率高于绝对最小方差投资组合的最优投资组合构成。 这些投资组合在给定某一风险水平的预期收益率上优于其他所有投资组合。
11.2.5 资本市场线
除了股票等高风险证券或者商品(如黄金)之外, 通常有一种普遍的无风险投资机会:现金或者现金账户。在理想化的世界中, 保存在大银行现金账户中的资金可以认为是无风险的(例如, 通过公共存款保险计划)。这种无风险投资的缺点是通常只能得到很低的收益。有时接近于0。
然而, 考虑这些无风险资产, 可以显著加强投资者的有效投资机会。 基本思路是, 投资者首先确定高风险资产的一个有效组合, 然后在组合中加人无风险资产。 通过调整投资于无风险资产中的财富比例,有可能实现任何风险-收益均衡性,这些配置位于(风
险-收益空间中)无风险资产和有效投资组合之间的直线上。
(在许多选项中)使用哪一个有效投资组合进行最优化风格的投资?这是有效边界切线恰好通过无风险投资组合风险-收益点的投资组合。 例如, 考虑无风险利率rf=0.01rf=0.01 r_f =0.01 的情况。我们寻找有效边界上切线穿过风险-收益空间上的点(σf,rf)=(0,1)(σf,rf)=(0,1)(\sigma_f,r_f)=(0,1) 的投资组合。
import scipy.interpolate as sciind = np.argmin(tvols)
evols = tvols[ind:]
erets = trets[ind:]tck = sci.splrep(evols, erets)# 通过这条数值化路径,最终可以为有效边界定义一个连续可微函数
# 和对应的一阶导数函数df(x):def f(x):"""Efficient frontier function (splines approximation):param x::return:"""return sci.splev(x, tck, der=0)def df(x):"""First derivative of efficient frontier function.:param x::return:"""return sci.splev(x, tck, der=1)
我们所寻求的是函数 t(x) = a+b*x , 描述穿过风险-收益空间中无风险资产、与有效边界相切的一条直线。
公式 资本市场线的数学条件
\begin{aligned} t(x) &= a+b\cdot x \\ t(0) &=r_f &\Leftrightarrow &\quad a=r_f \\ t(x) &=f(x) &\Leftrightarrow &\quad a+b\cdot x = f(x) \\ t^\prime (x) & =f^\prime (x) &\Leftrightarrow &\quad b=f^\prime(x) \end{aligned}
# 定义一个函数,返回给定参数集p=(a,b,x)
def equations(p, rf=0.01):eq1 = rf - p[0]eq2 = rf + p[1] * p[2] - f(p[2])eq3 = p[1]-df(p[2])return eq1,eq2,eq3# 数值优化得到如下的值
opt=sco.fsolve(equations,[0.01,0.5,0.15])
opt
# array([ 0.01 , 0.73464122, 0.29383737])
正如预期,有 a=rf=0.01a=rf=0.01a=r_f=0.01
优化的成败可能取决于初始参数化, 因此必须小心选择这些参数——常需要组合合理的猜测, 并反复尝试。
plt.figure(figsize=(8, 4))
# random portfolio composition
plt.scatter(pvols, prets, c=(prets - 0.01) / pvols, marker="o")
# efficient frontier
plt.plot(evols, erets, 'g', lw=4.0)
cx = np.linspace(0.0, 0.3)
plt.plot(cx, opt[0] + opt[1] * cx, lw=1.5)
# capital market line
plt.plot(opt[2], f(opt[2]), 'r*', markersize=15.0)
plt.grid(True)
plt.axhline(0, color='k', ls='-', lw=2.0)
plt.axvline(0, color='k', ls='-', lw=2.0)
plt.xlabel('expected volatility')
plt.ylabel('expected return')
plt.colorbar(label='Sharp ratio')
无风险利率为 1%时的资本市场线和相切的投资组合(星号)
星号代表有效边界中切线穿过无风险资产点(0, 0.01)的最优化投资组合。这个最优化组合的预期波动率为29.4% (opt[2]), 预期收益率为22.6% (f(opt[2]))
最优投资组合的权重如下,只包含5种资产中的 3 种:
cons = ({'type': 'eq', 'fun': lambda x: statistics(x)[0] - f(opt[2])},{'type': 'eq', 'fun': lambda x: np.sum(x) - 1})
res = sco.minimize(min_func_port, noa * [1. / noa, ],method='SLSQP', bounds=bnds, constraints=cons)
res['x'].round(3)
# array([ 0. , 0. , 0. , 0.703, 0.297])
未完待续 ……
Python金融大数据分析——第11章 统计学(2)投资组合优化 笔记相关推荐
- Python金融大数据分析——第11章 统计学(1)正态性检验 笔记
第11章 统计学 11.1 正态性检验 11.1.1 基准案例 11.1.2 现实世界的数据 第11章 统计学 11.1 正态性检验 可以说 , 正态分布是金融学中最重要的分布 , 也是金融理论的主要 ...
- Python金融大数据分析——第四章数据类型和结构
目录 数据类型和结构 4.1.1 整数 4.1.2 浮点数 4.1.3 字符串 4.1.4元祖 4.1.5 列表 4.1.6 控制结构 4.1.7 函数式编程 4.1.8 字典 4.1.9 集合 4. ...
- Python金融大数据分析——第五章数据可视化(2)金融学图表
5.2 金融学图表 5.2.1 mplfinance matplotlib的finance库包含不少可视化的金融图表,由于几代更新迭代,finance库也发生了变化. 从2.2.0版本前调用: imp ...
- Python金融大数据分析——第五章数据可视化(1)二维绘图
目录 第五章 数据可视化 5.1 二维绘图 5.1.1 一维数据集 5.1.2 二维数据集 5.1.3绘制其他图表 5.1.3.1绘制散点图 5.1.3.2 直方图 5.1.3.3 箱型图 第五章 数 ...
- Python金融大数据分析——第9章 数学工具 笔记
第9章 数学工具 9.1 逼近法 9.1.1 回归 9.1.2 插值 9.2 凸优化 9.2.1 全局优化 9.2.2 局部优化 9.2.3 有约束优化 9.3 积分 9.3.1 数值积分 9.3.2 ...
- python金融大数据分析笔记----第十章 2(风险测量)
10.4 风险测量 VaR CVaR 10.4.1. 风险价值(Var) VaR(Value at Risk,风险价值或风险溢价)是度量一项投资或投资组合可能产生的下跌风险的方法,它描述的是在一定的概 ...
- python金融大数据分析视频_Python金融大数据分析 PDF 全书超清版
给大家带来的一篇关于Python相关的电子书资源,介绍了关于Python金融.大数据分析方面的内容,本书是由人民邮电出版社出版,格式为PDF,资源大小47.8 MB,希尔皮斯科编写,目前豆瓣.亚马逊. ...
- 金融科技、算法交易、量化金融必读书:Python金融大数据分析第2版
银行本质上是技术公司. --胡戈•班齐格 近来,Python无疑是金融业的重要策略性技术平台之一.到2018年底,这已经不再是个问题:全世界的金融机构现在都尽最大努力利用Python及其强大的数据分析 ...
- Python金融大数据分析:用pandas处理金融时间序列数据的基础知识
时间是阻止所有事情同时发生的力量.--雷•卡明斯 本节使用的是以CSV文件形式在本地存储的金融数据集形式为本地存储的CSV文件.从技术上讲,CSV文件是包含数据行结构的文本文件,其特征是以逗号分隔单个 ...
- 计算机编程书籍-Python金融大数据分析
Python金融大数据分析 [德] 伊夫·希尔皮斯科(Yves Hilpisch) 著,姚军 译 ISBN:9787115521330 包装:平装 开本:16开 正文语种:中文 出版社:人民邮电出版社 ...
最新文章
- 考研英语作文:一封欢迎词
- Groovy里的绕过getter方法直接访问类属性的办法
- 关于memcached的收集
- 重写setTimeout扩展参数
- python选择某一行_Python常用语法有哪些 如何快速入门Python开发
- pip install mysqlclient报错fails with EnvironmentError: mysql_config not found
- ES6/07/Array的扩展方法,...扩展运算符,Array.from(),(arr.find(),arr.findIndex()和arr.includes())模板字符串,Set数据结构
- Alamofire4.x开源代码分析(三)文件上传下载
- 营销心理学:如何挣女人的钱?
- Nginx反向代理服务器获取不到端口的问题的解决办法
- 分布式文件存储FastDFS之安装Nginx实现文件访问
- 计算机实用基础试题答案,《计算机实用基础》试题卷(b).doc
- unity三维地球实现方法
- echarts瀑布图_Echarts自定义瀑布图开发
- mysql用其他用户登录报错_mysql如何登录创建的用户
- 有他人的梦想,才会让人觉得更有意义!
- 优秀的产品,离不开这4个 层面
- 25岁同济硕士生斩获中国首个CVPR最佳学生论文奖,他还是个「赛车发烧友」
- VMware虚拟化技术简介
- 计算机网络安全的目标,网络安全工作目标有哪些
热门文章
- 如何在虚拟机VMware安装配置功能强大爱快软路由
- 这个好像、也许、或许、大概、应该、Maybe真的可以算是传说中的Spring.Net了吧...
- Adobe Experience Cloud落地中国,Adobe、微软与世纪互联共庆三方合作
- 李广难封–有感于团队建设
- Dell台式计算机BIOS放电,戴尔bios设置电池修复 笔记本电脑电池bios设置图解方法...
- 随手笔记 -- 时间搜索框,默认搜索4天前至今天
- vant附带样式去除
- apkg格式怎么打开_jpg怎么转换成pdf?再不学就晚了
- Stream系列(六)Match方法使用
- JavaScript基础教程之flag的用法