python优化函数包 python优化算法包( 六 )


进行到此,我们最想知道的是给定的一个股票池(证券组合)如何找到风险和收益平衡的位置 。
下面通过一次蒙特卡洛模拟,产生大量随机的权重向量 , 并记录随机组合的预期收益和方差 。
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]:

推荐阅读