Skip to content

Commit

Permalink
this fixes the calculation of marginal cost
Browse files Browse the repository at this point in the history
if the powerplant is not turned on, no generation cost exists
this creates a weird way to create profit - by not prividing energy though
  • Loading branch information
maurerle committed Nov 13, 2023
1 parent 8546cc9 commit 4262a17
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 15 deletions.
22 changes: 15 additions & 7 deletions assume/common/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,13 +142,6 @@ def set_dispatch_plan(
else:
added_volume = order["accepted_volume"]
self.outputs[product_type].loc[start:end_excl] += added_volume

self.outputs[product_type + "_marginal_costs"].loc[start:end_excl] = (
self.calculate_marginal_cost(
start, self.outputs[product_type].loc[start]
)
* self.outputs[product_type].loc[start:end_excl]
)
self.calculate_cashflow(product_type, orderbook)

self.bidding_strategies[product_type].calculate_reward(
Expand All @@ -157,6 +150,21 @@ def set_dispatch_plan(
orderbook=orderbook,
)

def calculate_generation_cost(
self,
start: datetime,
end: datetime,
product_type: str,
):
if start not in self.index:
return
product_type_mc = product_type + "_marginal_costs"
for t in self.outputs[product_type_mc][start:end].index:
mc = self.calculate_marginal_cost(
start, self.outputs[product_type].loc[start]
)
self.outputs[product_type_mc][t] = mc * self.outputs[product_type][start]

def execute_current_dispatch(
self,
start: pd.Timestamp,
Expand Down
12 changes: 5 additions & 7 deletions assume/common/units_operator.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,15 +258,13 @@ def write_actual_dispatch(self):
end = now
current_dispatch.name = "power"
data = pd.DataFrame(current_dispatch)
data["soc"] = unit.outputs["soc"][start:end]
unit.calculate_generation_cost(start, now, "energy")
valid_outputs = ["soc", "cashflow", "marginal_costs", "total_costs"]

for key in unit.outputs.keys():
if "cashflow" in key:
data[key] = unit.outputs[key][start:end]
if "marginal_costs" in key:
data[key] = unit.outputs[key][start:end]
if "total_costs" in key:
data[key] = unit.outputs[key][start:end]
for output in valid_outputs:
if output in key:
data[key] = unit.outputs[key][start:end]

data["unit"] = unit_id
unit_dispatch_dfs.append(data)
Expand Down
5 changes: 4 additions & 1 deletion assume/markets/base_market.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,11 @@ def validate_registration(
method to validate a given registration.
Used to check if a participant is eligible to bid on this market
"""

# simple check that 1 MW can be bid at least
requirement = lambda unit: unit["max_power"] >= 1 or unit["min_power"] <= -1
def requirement(unit):
return unit["unit_type"] != "power_plant" or abs(unit["max_power"]) >= 1

return all([requirement(info) for info in content["information"]])

def validate_orderbook(self, orderbook: Orderbook, agent_tuple: tuple) -> None:
Expand Down
4 changes: 4 additions & 0 deletions tests/test_baseunit.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ def test_calculate_bids(base_unit, mock_market_config):
# mock calculate_marginal_cost
base_unit.calculate_marginal_cost = lambda *x: 10
base_unit.set_dispatch_plan(mock_market_config, orderbook)
base_unit.calculate_generation_cost(index[0], index[1], "energy")

# we apply the dispatch plan of 10 MW
assert base_unit.outputs["energy"][start] == 10
Expand All @@ -116,6 +117,7 @@ def test_calculate_bids(base_unit, mock_market_config):

# we somehow sold an additional 10 MW
base_unit.set_dispatch_plan(mock_market_config, orderbook)
base_unit.calculate_generation_cost(index[0], index[1], "energy")

# the final output should be 10+10
assert base_unit.outputs["energy"][start] == 20
Expand Down Expand Up @@ -151,6 +153,7 @@ def test_calculate_multi_bids(base_unit, mock_market_config):
# mock calculate_marginal_cost
base_unit.calculate_marginal_cost = lambda *x: 10
base_unit.set_dispatch_plan(mock_market_config, orderbook)
base_unit.calculate_generation_cost(index[0], index[1], "energy")

assert base_unit.outputs["energy"][index[0]] == 10
assert base_unit.outputs["energy_marginal_costs"][index[0]] == 100
Expand All @@ -160,6 +163,7 @@ def test_calculate_multi_bids(base_unit, mock_market_config):
assert base_unit.outputs["energy_cashflow"][index[1]] == 110

base_unit.set_dispatch_plan(mock_market_config, orderbook)
base_unit.calculate_generation_cost(index[0], index[1], "energy")

# should be correctly applied for the sum, even if different hours are applied
assert base_unit.outputs["energy"][index[0]] == 20
Expand Down

0 comments on commit 4262a17

Please sign in to comment.