尝试优化投资组合权重分配,通过限制风险最大化我的回报函数。我没有任何问题可以通过简单的约束条件找到最优化的权重给我的收益函数,即所有权重之和等于1,并且使我的总风险低于目标风险的其他约束。 我的问题是,如何为每个组添加行业权重界限? 我的代码如下:SciPy产品组合优化与行业界限分组
# -*- coding: utf-8 -*-
import pandas as pd
import numpy as np
import scipy.optimize as sco
dates = pd.date_range('1/1/2000', periods=8)
industry = ['industry', 'industry', 'utility', 'utility', 'consumer']
symbols = ['A', 'B', 'C', 'D', 'E']
zipped = list(zip(industry, symbols))
index = pd.MultiIndex.from_tuples(zipped)
noa = len(symbols)
data = np.array([[10, 9, 10, 11, 12, 13, 14, 13],
[11, 11, 10, 11, 11, 12, 11, 10],
[10, 11, 10, 11, 12, 13, 14, 13],
[11, 11, 10, 11, 11, 12, 11, 11],
[10, 11, 10, 11, 12, 13, 14, 13]])
market_to_market_price = pd.DataFrame(data.T, index=dates, columns=index)
rets = market_to_market_price/market_to_market_price.shift(1) - 1.0
rets = rets.dropna(axis=0, how='all')
expo_factor = np.ones((5,5))
factor_covariance = market_to_market_price.cov()
delta = np.diagflat([0.088024, 0.082614, 0.084237, 0.074648,
0.084237])
cov_matrix = np.dot(np.dot(expo_factor, factor_covariance),
expo_factor.T) + delta
def calculate_total_risk(weights, cov_matrix):
port_var = np.dot(np.dot(weights.T, cov_matrix), weights)
return port_var
def max_func_return(weights):
return -np.sum(rets.mean() * weights)
# optimized return with given risk
tolerance_risk = 27
noa = market_to_market_price.shape[1]
cons = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1},
{'type': 'eq', 'fun': lambda x: calculate_total_risk(x, cov_matrix) - tolerance_risk})
bnds = tuple((0, 1) for x in range(noa))
init_guess = noa * [1./noa,]
opts_mean = sco.minimize(max_func_return, init_guess, method='SLSQP',
bounds=bnds, constraints=cons)
In [88]: rets
Out[88]:
industry utility consumer
A B C D E
2000-01-02 -0.100000 0.000000 0.100000 0.000000 0.100000
2000-01-03 0.111111 -0.090909 -0.090909 -0.090909 -0.090909
2000-01-04 0.100000 0.100000 0.100000 0.100000 0.100000
2000-01-05 0.090909 0.000000 0.090909 0.000000 0.090909
2000-01-06 0.083333 0.090909 0.083333 0.090909 0.083333
2000-01-07 0.076923 -0.083333 0.076923 -0.083333 0.076923
2000-01-08 -0.071429 -0.090909 -0.071429 0.000000 -0.071429
In[89]: opts_mean['x'].round(3)
Out[89]: array([ 0.233, 0.117, 0.243, 0.165, 0.243])
我怎么可以添加这样的基团与5个资产下降,使得总和为下面的约束?
model = pd.DataFrame(np.array([.08,.12,.05]), index= set(industry), columns = ['strategic'])
model['tactical'] = [(.05,.41), (.2,.66), (0,.16)]
In [85]: model
Out[85]:
strategic tactical
industry 0.08 (0.05, 0.41)
consumer 0.12 (0.2, 0.66)
utility 0.05 (0, 0.16)
我已阅读本类似的帖子SciPy optimization with grouped bounds但仍不能得到任何线索,任何机构可以帮助? 谢谢。
感谢您的回复。对mapto_constraints函数稍作修改:lbdict = {'type':'ineq', 'fun':lambda x:np.sum(x [pos [0] :(pos [-1] + 1)]) - lb } ubdict = {'type':'ineq', 'fun':lambda x:ub - np.sum(x [pos [0] :(pos [-1] + 1)])} –