I have been struggling with solving the following problem: I have some values stored in variable returns, and I want to multiply them by a weight (x_vars)in order to make the sum of the products and obtain the value of the variable target_return. As the following equation:
I am struggling with the answer returned, as it saying x_13 = 1. But is not correct. I have tried to do it with normal constrains and eslastic but I get no correct answer. I have a tolerance of let's say 0.01% of error.
Any guess?
Thanks
import pulp as plp
# Name model
# set variables
target_return = 0.0204185791833761
returns = [0.025865338474480914,
0.031617753987556174,
0.017530329404997325,
-0.0008543358059154293,
0.010510143115372461,
0.012048338516174262,
0.04959181591738604,
0.06059545751936519,
0.05926623356137273,
0.058971753714631814,
0.03442022388647947,
0.013688974565667422,
0.02104075216985901,
-0.0021299262578251543,
0.017882182143459602,
0.018964184657020766,
0.005792320704504306,
0.018823216764509265,
-0.0015860431556348198,
0.008352716776521163,
0.030728674721250515,
0.016529301951210496,
0.0184734317514465,
-0.0008822232596910062,
0.010912806711330658,
0.023530497410194418,
0.0378090116601979,
0.009456335242604919,
0.005556382185357922,
0.020013334218681678,
0.05852489326632937,
0.047988175193893645,
0.016134386609760742,
0.014350880108888964,
0.006756782462879585]
# Initialize model
prob=plp.LpProblem("Find Weights Model", plp.LpMinimize)
x_vars=plp.LpVariable.dicts("x", range(0, len(returns)), 0, 1)
for index in range(len(returns)):
x_vars[index].setInitialValue(0.5)
#Set problem
prob += plp.lpSum([x_vars[i] for i in x_vars]) == 1
#Set constrain
constrain=plp.LpConstraint(plp.lpSum(
[returns[i]*x_vars[i] for i in range(0, len(returns))]), rhs=target_return)
# To use standard constrain uncomment following line
#prob.addConstraint(constrain)
# To use elastic constrain uncomment following line
elastic_constrain=constrain.makeElasticSubProblem(penalty = 500000,proportionFreeBoundList =[0.001,0.0001])
prob.extend(elastic_constrain)
prob.solve(plp.PULP_CBC_CMD(msg=True, warmStart=True))
final_weights={}
for v in prob.variables():
final_weights[v.name]=v.varValue
print("Status:", plp.LpStatus[prob.status])
final_weights
Possible solutions:
solution1 = [0.00962135141677065,
0.00962135141677065,
0.0277264834687149,
0.0297957188693739,
0.0324961558793471,
0.030826881062523,
0.0306009427392119,
0.0250863577897657,
0.0234700849350161,
0.0236653284777789,
0.0237085827820698,
0.0273148420035226,
0.0303599573647406,
0.0292800893464517,
0.0326835213770196,
0.0297440370126145,
0.0295851066643113,
0.0315198597719625,
0.0296058126214705,
0.0326036329340179,
0.0311437752841399,
0.0278570759221869,
0.0299427552142207,
0.0296571910611703,
0.0325002521378998,
0.0307677356659276,
0.0289143823239777,
0.0268170787933395,
0.0309816698637205,
0.0315545156635921,
0.0294310019878726,
0.023774220455596,
0.0253219090166822,
0.0300007623180508,
0.0302627332639599]
solution2 = [0.0291039150753347,
0.0291039150753347,
0.028739103831572,
0.0296325128619877,
0.0307984495156388,
0.0300777243941537,
0.0299801757193628,
0.027599206714805,
8.34695965451632E-05,
0.0269856659961344,
0.0270043421537945,
0.0285613748092319,
0.0298761263170002,
0.0294098868961038,
0.0308793458966854,
0.0296102001652331,
0.0295415791679557,
0.0303769265588311,
0.0295505206943934,
0.0308448536374279,
0.0302145485146196,
0.0287954885757358,
0.0296959977222549,
0.0295727013961937,
0.030800217918514,
0.0300521885203749,
0.0292519883685474,
0.0283464607865791,
0.0301445556616913,
0.030391887092054,
0.0294750434895131,
0.0270326804365011,
0.0277009088398652,
0.0297210421051448,
0.0298341506415484]
In excel, I've got the solutions using the following configuration: