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)

0 Answers