I'm solving a portfolio optimization problem where I need to allocate weights (capital) in such way that the end portfolio would have the lowest historical volatility possible. Currently I have two constraints on the total sum of weights of each stock and on their squared weights. Bounds for allocation in to each stock are (0.00, 0,02).
Currently my code looks like this:
def portfolio_vol(w):
#compute porfolio volatility
portfolio_volatility = np.sqrt(w.T.dot(cov_matrix).dot(w))
return portfolio_volatility
w
is a vector of equal weights calculated as w = 1.0/len(composition)
def find_optimal_allocations():
bnds = tuple((0.00, 0.02) for x in weights)
cons = ({'type': 'eq', 'fun': lambda x: 1 - sum(x)}, {'type': 'ineq', 'fun': lambda x: -sum(x**2) + 0.02})
result = spo.minimize(portfolio_vol, weights, method='SLSQP', bounds = bnds, constraints = cons)
return result.x
I store my weights in a MultIndex pandas Series where stocks are grouped by countries and initially are equal weighted:
Country Ticker
AS OMV AV Equity 0.020000
BE SOLB BB Equity 0.020000
FI NESTE FH Equity 0.020000
FR FP FP Equity 0.020000
GB LAND LN Equity 0.020000
GE BAS GR Equity 0.020000
HEI GR Equity 0.020000
GR TITK GA Equity 0.020000
IR CRH ID Equity 0.020000
RYA ID Equity 0.020000
...
US AMAT US Equity 0.020000
AMGN US Equity 0.020000
APA US Equity 0.020000
I would like to include additional constraint in to find_optimal_allocations()
so I could set limits for each country maximum weight: s.groupby(level=0,axis=0).sum()
Country
AS 0.020000
BE 0.020000
FI 0.020000
FR 0.020000
GB 0.020000
GE 0.040000
GR 0.020000
IR 0.040000
US 0.400000
For example withing the these bounds:
[(.05,.10), (.05,.10), (.05,.10), (.05,.10), (.05,.10), (.05,.10), (.05,.10), (.05,.10), (.05,.20)]
How can I include these bounds in to my optimization function so it would account for country weight constraints and individual stock constraints at the same time?