I have a series of accounts which charge an interest rate and every day I must decide from which to borrow money. I have a borrowing limit for every account. Obviously the easiest answer is to exhaust the cheapest rates first and so on.
As we have to compute this several times a day, the number of accounts varies and we plan a roll-forward cash flow I'm trying to write some Python code in order to automate it.
The objective function to minimize is the weighted average interest rate, identifying the money to borrow from each account (x
), bounded from 0 to an integer (depending on each agreement) in order to cover the outstanding.
The code below seems to be working fine, but I did the math on a piece of paper and it isn't reaching the global minimum. Is there anything I'm missing?
import numpy as np
from scipy.optimize import minimize
outstanding = -106332403
limit = [15000000, 29250000, 15000000, 22000000, 52567324, 5000000, 5000000, 40000000, 7398262]
interest = [0.73, 0.63, 0.78, 0.75, 0.6084, 0.97, 0.84, 0.625, 0.40]
limit = np.asarray(limit)
interest = np.asarray(interest)
def objective(x):
product = x * interest
sumproduct = sum(product)
return sumproduct / -outstanding
def constraint1(x):
return sum(x) + outstanding
# initial guesses
n = len(interest)
x0 = [1,1,1,1,1,1,1,1,1]
bnds = []
for value in limit:
b= (0,value)
bnds.append(b)
con1 = {'type': 'eq', 'fun': constraint1}
cons = (con1)
solution = minimize(objective,x0,method='SLSQP',bounds=bnds,constraints=cons)
x = solution.x