Issues modeling portfolio optimization with rebalancing in gurobipy - optimization

I want to solve the following portfolio optimization problem by means of the Python API of Gurobi:
enter image description here
I have implemented the problem in the following code:
subassets = ptf_optimization.ptf.index
max_rebalancing = 0.50
max_number_rebalancing = 10
rebalancing_threshold = 0.02
J = np.array(Chosen_new.tolist())
# Define model and set parameters
m2 = gp.Model('eff_ret_portfolio')
m2.setParam("NonConvex", 2)
m2.setParam("MIPGapAbs", 5e-3)
m2.setParam("TimeLimit", 100.0)
# Define variables
vars = pd.Series(m2.addVars(subassets), index=subassets)
vars_diff = pd.Series(m2.addVars(subassets, lb=(-1)*np.ones(len(subassets)), ub=2*np.ones(len(subassets))), index=subassets)
vars_abs = pd.Series(m2.addVars(subassets, lb=np.zeros(len(subassets)), ub=2*np.ones(len(subassets))), index=subassets)
vars_ind = pd.Series(m2.addVars(subassets, vtype=GRB.BINARY), index=subassets)
m2.update()
# Set objective
m2.setObjective(vars.T.dot(BL_returns), GRB.MAXIMIZE)
## Set constraints
portfolio_variance = vars.T.dot(ptf_optimization.cov.dot(vars))
m2.addConstr(portfolio_variance == target_std**2)
m2.addConstr(vars.sum() == 1-cash, 'budget')
m2.addConstrs((vars[j] == 0 for j in range(len(J)) if J[j] == True), name='c1') #J defined in min vol optimization
m2.addConstrs((vars_diff[item] == vars[item]-w_start[item] for item in subassets), name='diff')
m2.addConstrs((vars_abs[item] == gp.abs_(vars_diff[item]) for item in subassets), name='abs')
for item in subassets:
m2.addConstr((vars_ind[item]==1) >> (vars_abs[item] >= 1e-5))
m2.addConstr((vars_ind[item]==0) >> (vars_abs[item] <= 1e-5))
m2.addConstr(quicksum(vars_ind) <= max_number_rebalancing, 'max_number_rebalancing')
m2.addConstrs((vars_abs[item]*vars_ind[item] >= rebalancing_threshold for item in subassets), name='rebalancing_threshold')
m2.addConstr(quicksum(vars_abs) <= max_rebalancing, 'max_rebalancing')
# Add absolute constraints
for item in subassets:
l = ptf_optimization.absolute_constraints[item]['Min']
u = ptf_optimization.absolute_constraints[item]['Max']
m2.addConstr(l <= vars[item], f'constraint_abs_{item}_lower')
m2.addConstr(vars[item] <= u, f'constraint_abs_{item}_upper')
# Add group constraints
for j, item in enumerate(ptf_optimization.group_constraints):
constraint = ptf_optimization.group_constraints[item]
l = constraint['Min']
u = constraint['Max']
vars_list = (vars[item] for item in constraint['Group'])
m2.addConstr(l <= quicksum(vars_list), f'constraint_group_{j}_lower')
m2.addConstr(quicksum(vars_list) <= u, f'constraint_group_{j}_upper')
m2.setParam('OutputFlag', 1)
m2.optimize()
However, by inserting the constraint that rebalancing must be above a certain threshold, I obtained that the problem becomes infeasible. I computed an IIS and obtain the following .ilp file:
\ Model eff_ret_portfolio_copy
\ LP format - for model browsing. Use MPS format to capture full model detail.
Maximize
Subject To
max_number_rebalancing: C96 + C97 + C98 + C99 + C100 + C101 + C102 + C103
+ C104 + C105 + C106 + C107 + C108 + C109 + C110 + C111 + C112 + C113
+ C114 + C115 + C116 + C117 + C118 + C119 + C120 + C121 + C122 + C123
+ C124 + C125 + C126 + C127 <= 10
rebalancing_threshold[Obbligazionari_Governativi_Dollari]: [ C64 * C96 ]
>= 0.02
rebalancing_threshold[Obbligazionari_High_Yield_Euro]: [ C70 * C102 ]
>= 0.02
rebalancing_threshold[Obbligazionari_Emergenti_Hard_Currency]: [
C71 * C103 ] >= 0.02
rebalancing_threshold[Azionari_Euro]: [ C73 * C105 ] >= 0.02
rebalancing_threshold[Obbligazionari_Governativi_Breve_Termine_Europe_ex_Euro]:
[ C84 * C116 ] >= 0.02
rebalancing_threshold[Obbligazionari_Governativi_Breve_Termine_Yen]: [
C85 * C117 ] >= 0.02
rebalancing_threshold[Obbligazionari_Inflation_Linked_Dollari]: [
C87 * C119 ] >= 0.02
rebalancing_threshold[Obbligazionari_Corporate_Finanziari]: [ C89 * C121 ]
>= 0.02
rebalancing_threshold[Obbligazionari_Corporate_Dollari_Breve_Termine]: [
C91 * C123 ] >= 0.02
rebalancing_threshold[Obbligazionari_ABS]: [ C92 * C124 ] >= 0.02
rebalancing_threshold[Obbligazionari_Convertible_Euro]: [ C94 * C126 ]
>= 0.02
Bounds
C64 free
C70 free
C71 free
C73 free
C84 free
C85 free
C87 free
C89 free
C91 free
C92 free
C94 free
Binaries
C96 C97 C98 C99 C100 C101 C102 C103 C104 C105 C106 C107 C108 C109 C110
C111 C112 C113 C114 C115 C116 C117 C118 C119 C120 C121 C122 C123 C124 C125
C126 C127
End
Can you please tell me if I coded the model correctly and where the source of infeasibility is? Thanks a lot in advance.
Paolo

Related

Dynamic Neo4j Cypher Query

Is there a way to write the below neo4j cypher script to handle n case whens depending on the size of the array being read? I have varying array sizes on which to calculate co2 consumption so to use a one size fits all case when would be highly inefficient.
MATCH paths = allShortestPaths((a: Flights {label: 'Paris'})-[: FLIGHT*]->(b:Flights {label: 'Sydney'}))
WITH paths, relationships(paths) AS rels
UNWIND rels AS rel
WITH paths,
collect(rel.co2) AS co2,
collect(rel.engine_consumption) as ec
RETURN
reduce(acc1=0.0,
x IN range(0, size(fc)-1) |
case when x=0 then acc1 + co2[x]
when x=1 then acc1 + co2[x] * ec[x-1]
when x=2 then acc1 + co2[x] * ec[x-1] * ec[x-2]
when x=3 then acc1 + co2[x] * ec[x-1] * ec[x-2] * ec[x-3]
...
when x=size(ec)-1 then acc1 + co2[x] * ec[x-1] * ... * ec[0]
end
) AS normalised_co2
;
I did this in the end using the python library py2neo, and created the cypher query using python
case_when = ''
accumulator = ''
for x in range(max_paths):
accumulator += f'* co2[{x}]'
case_when += f'when x={x+1} then acc + co2[{x+1}]' + accumulator + ' \n '

CPLEX: Error 5002 Objective is not convex -> Problem can be solved to global optimality with optimality target 3 ->

I am receiving this error on CPLEX Optimization studio. The problem is a simple quadratic problem with one equality and two inequality constraints.
.mod code shown below (no .dat used):
/*********************************************
* OPL 12.10.0.0 Model
* Author: qdbra
* Creation Date: Sep 14, 2020 at 9:40:57 PM
*********************************************/
range R = 1..5;
range B= 6..10;
dvar float x[R];
dvar boolean y[B];
minimize
( x[1]^2 - 2*x[2]^2 + 3*x[3]^2 + 4*x[4]^2
- 5*x[5]^2 + 6*y[6]^2 + 7*y[7]^2 -
8*y[8]^2 + 9*y[9]^2 + 10*y[10]^2 +
8*x[1]*x[2] + 17*x[3]*y[8] - 20*y[6]*y[9]
+ 26*y[9]*y[10])/2 ;
subject to {
ct1:
x[1] + x[2] + x[3] + x[5] + y[6] + y[7] == 20;
ct2:
x[1] + x[4] + y[8] + y[9] + y[10] >= 1;
ct3:
x[2] - x[4] - y[6] + y[7] >= 0;
}
if you set the optimality target to 3 you ll get a result:
execute
{
cplex.optimalitytarget=3;
}
range R = 1..5;
range B= 6..10;
dvar float x[R];
dvar boolean y[B];
minimize
( x[1]^2 - 2*x[2]^2 + 3*x[3]^2 + 4*x[4]^2
- 5*x[5]^2 + 6*y[6]^2 + 7*y[7]^2 -
8*y[8]^2 + 9*y[9]^2 + 10*y[10]^2 +
8*x[1]*x[2] + 17*x[3]*y[8] - 20*y[6]*y[9]
+ 26*y[9]*y[10])/2 ;
subject to {
ct1:
x[1] + x[2] + x[3] + x[5] + y[6] + y[7] == 20;
ct2:
x[1] + x[4] + y[8] + y[9] + y[10] >= 1;
ct3:
x[2] - x[4] - y[6] + y[7] >= 0;
}
will give
x = [20
0 0 0 0];
y = [0 0 0 0 0];

How to solve simple linear programming problem with lpSolve

I am trying to maximize the function $a_1x_1 + \cdots +a_nx_n$ subject to the constraints $b_1x_1 + \cdots + b_nx_n \leq c$ and $x_i \geq 0$ for all $i$. For the toy example below, I've chosen $a_i = b_i$, so the problem is to maximize $0x_1 + 25x_2 + 50x_3 + 75x_4 + 100x_5$ given $0x_1 + 25x_2 + 50x_3 + 75x_4 + 100x_5 \leq 100$. Trivially, the maximum value of the objective function should be 100, but when I run the code below I get a solution of 2.5e+31. What's going on?
library(lpSolve)
a <- seq.int(0, 100, 25)
b <- seq.int(0, 100, 25)
c <- 100
optimal_val <- lp(direction = "max",
objective.in = a,
const.mat = b,
const.dir = "<=",
const.rhs = c,
all.int = TRUE)
optimal_val
b is not a proper matrix. You should do, before the lp call:
b <- seq.int(0, 100, 25)
b <- matrix(b,nrow=1)
That will give you an explicit 1 x 5 matrix:
> b
[,1] [,2] [,3] [,4] [,5]
[1,] 0 25 50 75 100
Now you will see:
> optimal_val
Success: the objective function is 100
Background: by default R will consider a vector as a column matrix:
> matrix(c(1,2,3))
[,1]
[1,] 1
[2,] 2
[3,] 3

Accurately calculate moon phases

For a new project I like to calculate the moon phases. So far I haven't seen any code that does that. I don't want to rely on online-services for this.
I have tried some functions, but they are not 100% reliable. Functions I have tried:
NSInteger r = iYear % 100;
r %= 19;
if (r>9){ r -= 19;}
r = ((r * 11) % 30) + iMonth + iDay;
if (iMonth<3){r += 2;}
r -= ((iYear<2000) ? 4 : 8.3);
r = floor(r+0.5);
other one:
float n = floor(12.37 * (iYear -1900 + ((1.0 * iMonth - 0.5)/12.0)));
float RAD = 3.14159265/180.0;
float t = n / 1236.85;
float t2 = t * t;
float as = 359.2242 + 29.105356 * n;
float am = 306.0253 + 385.816918 * n + 0.010730 * t2;
float xtra = 0.75933 + 1.53058868 * n + ((1.178e-4) - (1.55e-7) * t) * t2;
xtra = xtra + (0.1734 - 3.93e-4 * t) * sin(RAD * as) - 0.4068 * sin(RAD * am);
float i = (xtra > 0.0 ? floor(xtra) : ceil(xtra - 1.0));
float j1 = [self julday:iYear iMonth:iMonth iDay:iDay];
float jd = (2415020 + 28 * n) + i;
jd = fmodf((j1-jd + 30), 30);
and last one
NSInteger thisJD = [self julday:iYear iMonth:iMonth iDay:iDay];
float degToRad = 3.14159265 / 180;
float K0, T, T2, T3, J0, F0, M0, M1, B1, oldJ = 0.0;
K0 = floor((iYear-1900)*12.3685);
T = (iYear-1899.5) / 100;
T2 = T*T; T3 = T*T*T;
J0 = 2415020 + 29*K0;
F0 = 0.0001178*T2 - 0.000000155*T3 + (0.75933 + 0.53058868*K0) - (0.000837*T + 0.000335*T2);
M0 = 360*[self getFrac:((K0*0.08084821133)) + 359.2242 - 0.0000333*T2 - 0.00000347*T3];
M1 = 360*[self getFrac:((K0*0.07171366128)) + 306.0253 + 0.0107306*T2 + 0.00001236*T3];
B1 = 360*[self getFrac:((K0*0.08519585128)) + 21.2964 - (0.0016528*T2) - (0.00000239*T3)];
NSInteger phase = 0;
NSInteger jday = 0;
while (jday < thisJD) {
float F = F0 + 1.530588*phase;
float M5 = (M0 + phase*29.10535608)*degToRad;
float M6 = (M1 + phase*385.81691806)*degToRad;
float B6 = (B1 + phase*390.67050646)*degToRad;
F -= 0.4068*sin(M6) + (0.1734 - 0.000393*T)*sin(M5);
F += 0.0161*sin(2*M6) + 0.0104*sin(2*B6);
F -= 0.0074*sin(M5 - M6) - 0.0051*sin(M5 + M6);
F += 0.0021*sin(2*M5) + 0.0010*sin(2*B6-M6);
F += 0.5 / 1440;
oldJ=jday;
jday = J0 + 28*phase + floor(F);
phase++;
}
float jd = fmodf((thisJD-oldJ), 30);
All are working more and less, but none is really giving the correct dates of full moon for 2017 and 2018.
Does anyone have a function that will calculate the moon phases correctly - also based on time zone?
EDIT:
I only want the function for the Moonphases. SwiftAA offers a lot more and only produces not needed overhead in the app.

How to compute the p-value in hypothesis testing (linear regression)

Currently I'm working on an awk script to do some statistical analysis on measurement data. I'm using linear regression to get parameter estimates, standard errors etc. and would also like to compute the p-value for a null-hypothesis test (t-test).
This is my script so far, any idea how to compute the p-value?
BEGIN {
ybar = 0.0
xbar = 0.0
n = 0
a0 = 0.0
b0 = 0.0
qtinf0975 = 1.960 # 5% n = inf
}
{ # y_i is in $1, x_i has to be counted
n = n + 1
yi[n] = $1*1.0
xi[n] = n*1.0
}
END {
for ( i = 1; i <= n ; i++ ) {
ybar = ybar + yi[i]
xbar = xbar + xi[i]
}
ybar = ybar/(n*1.0)
xbar = xbar/(n*1.0)
bhat = 0.0
ssqx = 0.0
for ( i = 1; i <= n; i++ ) {
bhat = bhat + (yi[i] - ybar)*(xi[i] - xbar)
ssqx = ssqx + (xi[i] - xbar)*(xi[i] - xbar)
}
bhat = bhat/ssqx
ahat = ybar - bhat*xbar
print "n: ", n
print "alpha-hat: ", ahat
print "beta-hat: ", bhat
sigmahat2 = 0.0
for ( i = 1; i <= n; i++ ) {
ri[i] = yi[i] - (ahat + bhat*xi[i])
sigmahat2 = sigmahat2 + ri[i]*ri[i]
}
sigmahat2 = sigmahat2 / ( n*1.0 - 2.0 )
print "sigma-hat square: ", sigmahat2
seb = sqrt(sigmahat2/ssqx)
print "se(b): ", seb
sigmahat = sqrt((seb*seb)*ssqx)
print "sigma-hat: ", sigma
sea = sqrt(sigmahat*sigmahat * ( 1 /(n*1.0) + xbar*xbar/ssqx))
print "se(a): ", sea
# Tests
print "q(inf)(97.5%): ", qtinf0975
Tb = (bhat - b0) / seb
if ( qtinf0975 > Tb )
print "T(b) plausible: ", Tb, " < ", qtinf0975
else
print "T(b) NOT plausible: ", Tb, " > ", qtinf0975
print "confidence(b): [", bhat - seb * qtinf0975,", ", bhat + seb * qtinf0975 ,"]"
Ta = (ahat - a0) / sea
if ( qtinf0975 > Ta )
print "T(a) plausible: ", Ta, " < ", qtinf0975
else
print "T(a) NOT plausible: ", Ta, " > ", qtinf0975
print "confidence(a): [", ahat - seb * qtinf0975,", ", ahat + seb * qtinf0975 ,"]"
}
You're probably trying to do a paired t-test under the assumption of variance equality. I suggest you have a look at the corresponding entry in the excellent MathWorld website.
OK, I've found a javascript implementation and ported it to awk this are the functions used to compute the p-value:
function statcom ( mq, mi, mj, mb )
{
zz = 1
mz = zz
mk = mi
while ( mk <= mj ) {
zz = zz * mq * mk / ( mk - mb)
mz = mz + zz
mk = mk + 2
}
return mz
}
function studpval ( mt , mn )
{
PI = 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679 # thank you wikipedia
if ( mt < 0 )
mt = -mt
mw = mt / sqrt(mn)
th = atan2(mw, 1)
if ( mn == 1 )
return 1.0 - th / (PI/2.0)
sth = sin(th)
cth = cos(th)
if ( mn % 2 == 1 )
return 1.0 - (th+sth*cth*statcom(cth*cth, 2, mn-3, -1))/(PI/2.0)
else
return 1.0 - sth * statcom(cth*cth, 1, mn-3, -1)
}
I've integrated them like this:
pvalb = studpval(Tb, n)
if ( pvalb > 0.05 )
print "p-value(b) plausible: ", pvalb, " > 0.05"
else
print "p-value(b) NOT plausible: ", pvalb, " < 0.05"
pvala = studpval(Ta, n)
if ( pvala > 0.05 )
print "p-value(a) plausible: ", pvala, " > 0.05"
else
print "p-value(a) NOT plausible: ", pvala, " < 0.05"