Constrain
I use the python version.
There are some problems when I use gurobi to sovle protfolio optimization. My purpose is to choose 100 tickers from a stock pool which has about 3000 tickers to form a best portfolio. The objective is to MAXIMIZE the return of portfolio considering some exposure constraint.
Below is my code:
model = Model('portOpt')
stkwt = pd.Series(model.addVars(tickers), index = tickers)
stksel = pd.Series(model.addVars(tickers, vtype = GRB.BINARY), index = tickers) #
selwt = stkwt * stksel
forecast = sig
port_ret = forecast.dot(selwt) #forecast return of portfolio
risk_ret = port_ret
model.setObjective(risk_ret, GRB.MAXIMIZE) #maximize forecast return
model.addConstr(selwt.sum() == 1) #sum of weights of selected tickers equals 1.0
model.addConstr(stksel.sum() == 100) #select 100 tickers
for v in stkwt:
model.addConstr(v == [0.001, 0.03]) #weight constrained to [0.001,0.03]
benchmarkWt = self.index_wt / 100 #benchmark weights
for i in range(len(fac_names)):
facExpo = X.iloc[:,i]
idxExpo = benchmarkWt.dot(facExpo)
if idxExpo != 0:
model.addConstr((selwt.dot(facExpo) - idxExpo) / idxExpo == [-0.5, 0.5]) #factors exposure constraint
model.optimize()
Program runs well and constraints looks good except the factors exposure constraint. The factor exposure calculated by the optimized result(weights) listed below. The diff_ratio is expected to be in the range [-0.5,0.5].
FAC1 idxexp: 0.5667 portexp: 0.5526 diff_ratio:-0.0248
FAC2 idxexp:-0.2839 portexp:-0.2109 diff_ratio:-0.2573
FAC3 idxexp:-0.6437 portexp:-0.9656 diff_ratio: 0.5000
FAC4 idxexp:-0.2880 portexp: 0.0910 diff_ratio:-1.3158
FAC5 idxexp: 0.0778 portexp:-0.0475 diff_ratio:-1.6107
FAC6 idxexp: 0.2093 portexp:-0.0412 diff_ratio:-1.1968
FAC7 idxexp:-0.0357 portexp: 0.2357 diff_ratio:-7.6022
FAC8 idxexp:-0.0595 portexp: 0.1994 diff_ratio:-4.3511
FAC9 idxexp: 0.4788 portexp: 0.1135 diff_ratio:-0.7629
FAC0 idxexp: 0.7875 portexp: 0.7225 diff_ratio:-0.0826
I'm not sure if I'm writing the right code for my purpose. Any advice will be great appreciated! Thanks.
-
Official comment
This post is more than three years old. Some information may not be up to date. For current information, please check the Gurobi Documentation or Knowledge Base. If you need more help, please create a new post in the community forum. Or why not try our AI Gurobot?. -
If I use stkwt instead of selwt in exposure constraint and set min weight of stkwt to 0.0(represent that no constraint of select 100 tickers), exposure constraint works well. I wonder how should I write the exposure contraint in my case to select 100 tickers and limit the min weight to 0.001.
------------------------------- code ---------------------------------
model.setObjective(risk_ret, GRB.MAXIMIZE) #maximize forecast return
model.addConstr(stkwt.sum() == 1) #sum of weights of selected tickers equals 1.0
for v in stkwt:
model.addConstr(v == [0.0, 0.03]) #weight constrained to [0.0,0.03]
benchmarkWt = self.index_wt / 100 #benchmark weights
for i in range(len(fac_names)):
facExpo = X.iloc[:,i]
idxExpo = benchmarkWt.dot(facExpo)
if idxExpo != 0:
model.addConstr((stkwt.dot(facExpo) - idxExpo) / idxExpo == [-0.5, 0.5]) #factors exposure constraint
model.optimize()0
Post is closed for comments.
Comments
2 comments