I am trying to optimize for a given date of deposit and withdrawal of a given commodity in a storage considering that the storage max capacity is 50 and the rate of injection/withdrawal is 5/day. Assume that it costs 0.01 per month to store the commodity. My commodity prices list is equally spaced in monthly dates.
At first I want to try to optimize for a single injection and withdrawn and next extend for multiples injections and withdrawns for the given timeframe i am analyzing.
So I created few constraint functions
i. withdrawal date > deposit date
ii. total volume injected – total volume withdrawn < 50
iii. volume injected = volume withdrawn
iv. withdrawn <= 5 per day
v. deposit <= 5 per day
The profit function is given by
i. volume withdrawn * commodity_price[date_withdrawn] – volume injected * commodity_price[date injected] – cost*(date withdrawn – date injected)
The code is as follows:
##Volume in mm BBTUs
max_volume = 50
##Volume in mm BBTUs per day
rate = 5
##Cost in million dollars per day
costs = 0.01
commodity_prices = hw_nat_gas['Complete'].to_list()
from scipy.optimize import minimize
def constraint1(dates):
deposit_date, withdrawal_date, volume_deposit, volume_withdrawal = dates
return withdrawal_date - deposit_date
# Define constraint function for volume constraint
def constraint_volume(dates):
deposit_date, withdrawal_date, volume_deposit, volume_withdrawal = dates
total_volume = volume_deposit - volume_withdrawal
return max_volume - total_volume
def constraint_volume2(dates):
deposit_date, withdrawal_date, volume_deposit, volume_withdrawal = dates
return volume_deposit - volume_withdrawal
def profit_function(dates):
deposit_date, withdrawal_date, volume_deposit, volume_withdrawal = map(int, dates)
profit = volume_withdrawal*commodity_prices[withdrawal_date] - volume_deposit*commodity_prices[deposit_date] - costs*(deposit_date-withdrawal_date)
return -profit
def withdrawal(dates):
deposit_date, withdrawal_date, volume_deposit, volume_withdrawal = map(int, dates)
return rate - volume_withdrawal
def deposit(dates):
deposit_date, withdrawal_date, volume_deposit, volume_withdrawal = map(int, dates)
return rate - volume_deposit
constraints = [{'type': 'ineq', 'fun': constraint1},
{'type': 'ineq', 'fun': constraint_volume},
{'type': 'ineq', 'fun': withdrawal},
{'type': 'ineq', 'fun': deposit},
{'type': 'eq', 'fun' : constraint_volume2}]
bounds = [(0, 58), (0, 58), (0,5), (0,5)]
initial_guess = [7, 12, 0, 0]
result = minimize(profit_function, initial_guess, bounds=bounds, constraints=constraints)
At first what I am getting is that there is no variation in the dates of deposit and withdrawal, it simply optimizes for the initial guess, the value i am inserting in the scipy.minimize function. Second, it is not varying as well the volumes for injection.
If I instead of using initial guess of [7, 12, 0, 0]
use [7, 12, 5, 5]
the value of the profit increases, but i wanted the function to perform this analysis by itself, by varying the parameters and obtaining the combination of values that get the max profit.
Any suggestions?
Arthur is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.