CVaR optimization
AnsweredI am trying to perform a scenario-based stochastic optimization using a utility objective function consisting of the average profit and the CVaR. The first part is working fine, so everything except for the CVaR is working the way it is supposed to.
Now, to include the CVaR the objective will look like this: B*avg_profit - (1-B)*cvar
The problem is that in order to calculate the cvar, (I think) I need to sort the profits of the different scenarios to find the worst performing ones. However, this results in NotImplemented errors because I'm trying to sort lists of LinExprs.
In the following code I have implemented a 'dirty fix', because the calculation is based on the average profit instead of the VaR as it should be.
cvar = m.addVar(lb=0, name='cvar')
for s in range(price_scenarios):
price = prices[:, s]
for c in costs:
profit = sum( "some calculation for the profit" for t in times)
m.addConstr(profit - avg_profit <= cvar)
This fix somewhat ressembles the behaviour that I am trying to model, but is ofcourse not how it is supposed to be. I tried it a few different ways, but the problem is always that I am trying to find define the worst scenarios before the model is solved. Therefore, usually I am trying to sort a list of LinExprs which is not possible.
Hopefully anyone has some experience with this and is able to help me. Thanks in advance!
-
Hi Sander,
Could you not sort the coefficients before forming the expression?
As long as the variables are also ordered in the same way, this would be equivalent to sorting a LinExpr.
I am not sure this will be enough, I am not an expert in this, and CVar seems pretty complicated: https://quant.stackexchange.com/a/3939Cheers,
David0 -
Hi Sander and David,
the conditional value at risk (CVaR) is actually super easy to implement :)
You need the following data:- A Set S of scenario objects (which are a discrete representation of a stochastic distribution). Each object needs a function or property "profit", which is a single scenarios' return - you might want to maximize that on another part of the model
- Alpha, which says how much of the "tail" you want to define as risk
alpha = 0.05
VarDev = m.addVars(S, vtype=GRB.CONTINUOUS, lb=0)
VaR = m.addVar(vtype=GRB.CONTINUOUS, lb=0)
CVaR = m.addVar(vtype=GRB.CONTINUOUS, lb=0)
m.addConstrs(s.profit - VaR <= VarDev[s] for s in S)
m.addConstr(VaR + 1 / (len(S) * alpha) * quicksum(VarDev[s] for s in S) == CVaR)
m.SetObjective(CVar)
Also check out Daniel's Webinar.
Solving Simple Stochastic Optimization Problems with Gurobi - Gurobi Optimization
Feel free to contact me for further questions
Mathias2
Please sign in to leave a comment.
Comments
2 comments