This is a financial engineering problem for asset allocation. There are four asset class: stock, fixed income, CTA strategy and relative value strategy. Their return and covariance matrix are given. And for the result, it is expected to allocation more weight for fixed income asset and less weight for stock, not the initial weight.
The covariance matrix (4*4 matrix) is as follows(C in the code below):
sigma = [ [0.019828564,0.002498922,0.003100164,0.001272493],[0.002498922,0.005589884,0.000511829,0.000184773],[0.003100164,0.000511829,0.001559972,0.00019131],[0.001272493,0.000184773,0.00019131,0.0001306]]
sigma_p = np.matrix(sigma)
as 0,1,2,3 are 'stock_idx','CTA_idx','RelativeValue_idx','bond_idx' respectively
I am trying to find their optimal weight using the 'Risk - Parity' method, which is finally to solve the equation:
![The Risk Parity aim equation]https://i.stack.imgur.com/PdR73.png
I used the scipy.optimize in python, and the method "SLSQP" which is the only method that can apply the bounds and constraints in the solving progress. However, the mechanism did not work and always returned the initial guess, no matter how the initial guess were chosen. Codes are as follows:
def calculate_portfolio_var(W,C):
# function that calculates portfolio risk
sigma_p = np.sqrt(np.dot(np.dot(W.T,C),W))
return sigma_p
def calculate_risk_contribution(W,C):
MRC = np.dot(C,W)# Marginal Risk
RC = np.multiply(W,MRC)# Total Risk
return RC
def solve_weight(C,N): #C is the covariance matrix, and given as sigma_p before
def risk_budget_objective(W,C,N):
W = np.matrix(W).T
sig_p = calculate_portfolio_var(W,C) # portfolio sigma
total_RC = calculate_risk_contribution(W,C)
risk_target = sig_p / N
# sum of squared error
J = sum(np.square(total_RC / sig_p - risk_target))
print("SSE",J[0,0])
return J[0,0]
def total_weight_constraint(x):
return np.sum(x)-1.0
def long_only_constraint(x):
return
w0 = [0.1, 0.2, 0.3, 0.4]
w0 = np.matrix(w0).T
print('w0',w0,w0.shape)
b_ = [(0., 1.) for i in range(N)]
c_ = ({'type': 'eq', 'fun': lambda W: np.sum(W) - 1.})
optimized = scipy.optimize.minimize(risk_budget_objective, w0, (C,N), method='SLSQP', constraints=c_, bounds=b_)
if not optimized.success: raise BaseException(optimized.message)
w_rb = np.asmatrix(optimized.x)
return w_rb