I have a dataframe of bonds. I want to maximize the yield under the following constraints: use the bonds universe (one bond corresponds to a row)

The objective function should be:

objective = max( Price * position * yield / sum(Price * position) ) for 8 bonds

bond value = Price * position

Constraints:

I want to have maximum 8 bonds.

I want a portfolio with a total value of 1,000,000. The value is the sum of 8 bonds with value = Price * position

I want sum(8 bond values * nb_days) / sum(8 bonds values) < 150

I want sum(8 bond values * nb_days) / sum(8 bonds values) > 140

The dataframe DfBill is
```
index price nb_days yield position mkt value wght
0 98.17405 334 2.004695 1000 981.7405 4.7%
1 98.34707 306 1.977307 1000 983.4707 4.7%
2 98.5219 278 1.942803 1000 985.219 4.7%
3 98.72388 250 1.861366 1000 987.2388 4.7%
4 98.87597 222 1.843473 1000 988.7597 4.7%
5 99.22865 152 1.841083 1000 992.2865 4.8%
6 99.15942 166 1.838398 1000 991.5942 4.8%
7 99.2668 145 1.833804 1000 992.668 4.8%
8 99.02267 194 1.831502 1000 990.2267 4.8%
9 99.30549 138 1.824436 1000 993.0549 4.8%
10 99.34964 131 1.798948 1000 993.4964 4.8%
11 99.39354 124 1.771433 1000 993.9354 4.8%
12 99.43418 117 1.750892 1000 994.3418 4.8%
13 99.47195 110 1.737338 1000 994.7195 4.8%
14 99.51012 103 1.720631 1000 995.1012 4.8%
15 99.55429 96 1.678896 1000 995.5429 4.8%
16 99.58933 89 1.667987 1000 995.8933 4.8%
17 99.6229 82 1.661828 1000 996.229 4.8%
18 99.7245 61 1.630393 1000 997.245 4.8%
19 99.69329 68 1.628754 1000 996.9329 4.8%
20 99.66268 75 1.624616 1000 996.6268 4.8%
```

Thank you so much for your help

PS: This is the code I wrote but it does not work:

```
def objective1(df):
PosYld = df['position'] * df['price'] * df['yield']
PosPrice = df['position'] * df['price']
AvgYld = PosYld.sum() / PosPrice .sum()
return 1/AvgYld
def constraint1(df):
PosDays = df['position'] * df['nb_days']
AvgDays = PosDays.sum() / df['position'].sum()
return AvgDays - 150
def constraint2(df):
PosDays = df['position'] * df['nb_days']
AvgDays = PosDays.sum() / df['position'].sum()
return - AvgDays + 140
b = (0,800000)
bnds = []
for i in range(len(DfBill)):
bnds.append(b)
bnds = tuple(bnds)
con1 = {'type':'ineq','fun': constraint1}
con2 = {'type':'ineq','fun': constraint2}
cons = [con1,con2]
sol = minimize(objective1,DfBill['position'].values.tolist() ,method = 'SLSQP',bounds = bnds,constraints = cons)
print(sol)
```

I used the code below I found on internet and tried to apply on my case.

```
def objective(x):
x1 = x[0]
x2 = x[1]
x3 = x[2]
x4 = x[3]
return x1*x4*(x1+x2+x3)+x3
def constraint1(x):
return x[0]*x[1]*x[2]*x[3]-25
def constraint2(x):
sum_sq = 40
for i in range(4):
sum_sq = sum_sq - x[i]**2
return sum_sq
x0 = [1,5,5,1]
b = (1,5)
bnds = (b,b,b,b)
con1 = {'type':'ineq','fun': constraint1}
con2 = {'type':'ineq','fun': constraint2}
cons = [con1,con2]
sol = minimize(objective,x0,method = 'SLSQP',bounds = bnds,constraints = cons)
print(sol)
```