quintel / merit-convergence

Utility library to support price convergence in the merit order
0 stars 0 forks source link

Current plant should be price-setting #2

Closed ChaelKruip closed 10 years ago

ChaelKruip commented 10 years ago

Previously this was the next (non-running) plant in the Merit Order.

This needs to be done for the price-convergence project alone. Not (yet) decided what we will do with Merit (coupled to ETM).

antw commented 10 years ago

How urgent is this? It's non-trivial (but possible) since all price-related functions in the main Merit gem assume the first unloaded plant to be price-setting.

The changes needed to the convergence calculator are easy, but changing the Merit gem to cope with both might prove tricky. It may be simpler if all you need is the price curve and don't care about other pricing functions (such as profit, revenue, total_costs, etc).

ChaelKruip commented 10 years ago

How urgent is this?

I should probably have said that we would like this feature by next week if possible :worried:

changing the Merit gem to cope with both might prove tricky

We already implemented a step-function for the marginal cost. I think it would be relatively easy to also implement the linear cost function suggested in https://github.com/quintel/merit/issues/107 because it is a simpler version of the step-function. The desired behaviour would then be obtained by setting the slope of the cost-function to zero: the current plant determines the price, regardless of its used capacity.

It may be simpler if all you need is the price curve

That is the case indeed.

ChaelKruip commented 10 years ago

We already implemented a step-function for the marginal cost.

Better still: we could use the step-function itself. With a spread of 0% :smile:

antw commented 10 years ago

I'm not sure that using a function changes anything; the issue is that the Merit library does not allow a producer to be price-setting if any load is assigned to it. The only exception is for cost-function producers, which require a full "unit" of capacity to be available.

Getting around this should be simple: if the current plant is price setting, then price_at(hour) == cost_at(hour). I think what I have to do is:

ChaelKruip commented 10 years ago

... which require a full "unit" of capacity to be available.

Hm, I did not know about that limitation of the cost-function. How fundamental is it? The cost-function already should have the correct behaviour if a plant is using its last 'unit' (which could be a fraction of the capacity of a complete unit right?). So, if less than a complete plant is installed (installed capacity of plant X is smaller than typical_capacity_per_unit for plant X), shouldn't it behave identically and mark the next (non-running) plant as price-setting?

antw commented 10 years ago

Hm, I did not know about that limitation of the cost-function. How fundamental is it? The cost-function already should have the correct behaviour if a plant is using its last 'unit'

It's not so much a limitation as a sanity check. In quintel/merit#110 you said: _"because the price should be set by the marginal cost of the 'next' plant in the merit order, we need to evaluate linear_price_step(used_capacity + typical_capacity) to get the price"_. Therefore, it considers a cost-function producer to be price setting only if remaining_capacity >= typical_capacity (so that the price is based on the cost of adding one more plant).

ChaelKruip commented 10 years ago

Therefore, it considers a cost-function producer to be price setting only if remaining_capacity >= typical_capacity (so that the price is based on the cost of adding one more plant).

Thanks for clearing that up. I now understand the confusion. A bit further in quintel/merit#110 I said:

... the function is not defined if you are using the 'last' plant of a 'block of plants' of the same type. In that case the price should (still) be set by the next plant in the merit order, which is of a different type (say, diesel engine).

This can be interpreted in (at least) two ways:

  1. 'last' plant implies there where at least more than 1 other plants in this 'block' (I think this how you, @antw, read this)
  2. If only a fraction of a plant is installed, that automatically means you are in the 'last plant' situation (how I read it).

Sorry about not being clearer about this!

Now I understand, as well, that it is probably easier to following your suggestion of adding a cost_at method and using that to set the price. :blush:

ChaelKruip commented 10 years ago

This is done right @antw? Closing.