# Adding argument to ERC function in Python makes it break down

I am using xlwings to implement Python code in Excel. I put the following code in Spyder and imported it into Excel to arrive at equal risk contribution weights for a 7-asset portfolio.

@xw.func
def risk_budget_objective_error(weights,*args):

#Covariance table occupies the first position in args variable
covariances = args[0]

#State risk budgets
assets_risk_budget = args[1]

weights = np.matrix(weights)

#Calculate portfolio st_dev
portfolio_stdev = calculate_portfolio_risk(weights,covariances)

#Calculate risk contributions
assets_risk_contribution = calculate_risk_contribution(weights,covariances)

#Calculate desired risk contribution of each asset
assets_risk_target = np.multiply(portfolio_stdev,assets_risk_budget).astype(float)

#Calculate error between desired contribution and calculated distribution of each asset
squared_error = np.square(assets_risk_contribution-assets_risk_target.T)
sse = sum(squared_error)

return sse

@xw.func
def erc_weights(covariances,assets_risk_budget, num_assets):

#Constraints to optimization

cons = ({'type':'eq','fun':lambda x: np.sum(x) - 1.5},
{'type':'ineq','fun':lambda x: x})

bounds = ((0,.50),(0,None),(0,None),(0,None),(0,None),(0,.50),(0,None),(0,.10),(0,.25))

init_weights = [.5]*num_assets

#Optimization in scipy
optimize_result = minimize(risk_budget_objective_error,
x0 = init_weights,
method = 'SLSQP',
args = (covariances, assets_risk_budget),
constraints = cons,
options = {'disp':True,'ftol':1e-50}
)

#Get optimized weights
weights = optimize_result.x

return weights


My issue is with the erc_weights function. I am trying to make it so that the number of strategies is one of the arguments in the function, and num_assets is the number of assets in the portfolio (edited code shown below) but every time I add it as an argument, the function breaks down and produces an error.

The same occurs when I try to make other parameters endogenous. eg: total weight cap, bounds etc, so any solution to this problem will definitely be of use in those areas as well. Thank you

@xw.func
def erc_weights(covariances,assets_risk_budget, num_assets):

#Constraints to optimization

cons = ({'type':'eq','fun':lambda x: np.sum(x) - 1.5},
{'type':'ineq','fun':lambda x: x})

bounds = ((0,.50),(0,None),(0,None),(0,None),(0,None),(0,.50),(0,None),(0,.10),(0,.25))

init_weights = [.5]*num_assets

#Optimization in scipy
optimize_result = minimize(risk_budget_objective_error,
x0 = init_weights,
method = 'SLSQP',
args = (covariances, assets_risk_budget),
constraints = cons,
options = {'disp':True,'ftol':1e-50}
)

#Get optimized weights
weights = optimize_result.x

return weights

• Could you make an MCVE and explain which error you're seeing. As is, I'm not even sure whether this question belongs here or on StackOverflow. – Bob Jansen Mar 22 at 20:58