electricity price outputs per zone?

56 views
Skip to first unread message

Joshua Rhodes

unread,
Mar 4, 2022, 10:46:42 AM3/4/22
to Switch Model
Hello,

In Switch, is there a way to generate a CSV of zonal, hourly electricity prices as one the model outputs?

We're using Switch to model some renewables capacity expansion in ERCOT and want to know what sort of prices the wind farms are selling at, on average in each zone. 

Thanks, Josh

Josiah Johnston

unread,
Mar 4, 2022, 12:53:51 PM3/4/22
to switch...@googlegroups.com
Prices are tricky; their values depend on your assumptions (or embedded assumptions), and how the accounting rules are structured. The simplest I’ve heard of are from vertically integrated regulated utilities that base prices on the average annual cost of running the system. ERCOT market pricing is a bit more complicated and based on bids for day-ahead, real-time, capacity, plus other fine print (I’m not an expert in that). 

The easiest place to start (if you’re running it as a pure linear problem) is dual values of the satisfy load constraint.
That will be the long-run marginal costs, which can include capital costs (generation, transmission, distribution, etc). These will be different than the variable cost of individual generators. Those long run marginal costs can spike if a peak load timepoints prompted installation of more system resources. 
If you’re running it as a mixed integer problem, the dual values can’t be reliably interpreted.

If you want to mimic actual ERCOT pricing, you’d probably need to write a specialized module. A rough estimation based on variable cost of generation would be easier, but you’d need to pick some rules for transmission.. If an expensive generator is providing 5% of energy in zone A, and zone A exports to zones B & C, do you assign its variable costs to the entire system, or is one zone stuck with the entire cost? Switch doesn’t simulate which load zone is contracting with which generator; it just satisfies system-wide constraints for satisfying load, reliability, etc. 

Some other wrinkles is how to mimic long-term contracts like PPA or day ahead markets.. Simple market assumptions could say all zones pay the marginal price of the highest accepted bid (which in theory is the marginal cost of generation), but that misses some important mechanisms of lowering the overall price.

Hope that helps a little. Others who work more with markets may have better ideas than me.

Cheers,
Josiah

--
You received this message because you are subscribed to the Google Groups "Switch Model" group.
To unsubscribe from this group and stop receiving emails from it, send an email to switch-model...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/switch-model/f5ab8eb7-aa3b-4b89-b69c-b0b20a2a6404n%40googlegroups.com.

Matthias Fripp

unread,
Oct 16, 2022, 1:20:15 AM10/16/22
to Switch Model
Hi Josh,

I just came across this message and wanted to add a fairly narrow answer about calculating the marginal cost of generation. 

I have done this in the past by creating a custom module that accessed the dual values of the load balancing constraint. This is a little tricky because you need to convert the duals from model dollars (discounted, time-weighted) to dollars per MWh. You can see an example of this in the iterative demand response code at https://github.com/switch-model/switch/blob/2.0.6/switch_model/balancing/demand_response/iterative/__init__.py. The relevant lines are the ones that define m.dual and the electricity_marginal_cost function.

That file also has some code to report all the dual values of all the constraints in the model -- see the write_dual_costs() function. Looking at all the duals can be enlightening, because it helps to track down where there may be "missing money" and "surplus money" if you are pricing at simple marginal cost. In a linear program, every constraint has a shadow/dual price, and the duality theorem says that the objective value of the primal program (the costs Switch is trying to minimize) will be equal to the sum of the dual values times all the non-zero right-hand sides of these constraints. So if you look at the duals, you should find they add up to match the objective function, and you can see where surplus money may show up or money may not be available. Specifically, you will find that there are costs associated with maintaining a reserve margin that need to be recovered somehow, in addition to the revenue from marginal-cost pricing of electricity. But then there is also surplus associated with existing power plants (should provide them enough capital recovery, but possibly some rents on non-reproducible plants that are early in the merit order). There will also be some surplus associated with the best renewable energy sites. This should roughly match up with the way revenues actually move around in an energy-only market, but may not match up exactly, as Josiah said.

In general you cannot expect to retrieve dual values if you have an integer model. I seem to remember that yours was continuous, so this should not be a problem. But you can get a sort of dual by freezing all the integer values at their current levels and then re-solving and retrieving the duals. This creates an extra shadow cost that shows up in the write_dual_costs() function, which can be thought of as the extra cost associated with having to make integer choices for construction or unit commitment variables (lumpy investment options). This can also drive the marginal cost of power and reserves up or down a bit, which I think is reasonable (sometimes the system may clear above the cost of the last operating unit in order to avoid committing the next unit).

Anyway, I just wanted to point you toward these resources, and I'd be happy to talk more if you'd like (there are lots of interesting subtleties in there).

Matthias
Reply all
Reply to author
Forward
0 new messages