You have a battery. Electricity prices change every hour. You want to make as much money as possible by choosing when to charge (buy cheap) and discharge (sell expensive). That's it — that's an optimization problem.
Every optimization problem has exactly three ingredients. Learn these, and you can frame any decision as an optimization problem — not just batteries.
These are the knobs you get to turn. For a battery operating across 24 hours, your decisions might be:
p_charge[t] = how much power to charge in hour t (MW)
p_discharge[t] = how much power to discharge in hour t (MW)
The optimizer's job is to find the best values for these variables. Everything else (prices, battery size, efficiency) is a parameter — given, not chosen.
The objective is a single number that tells the optimizer how good a solution is. For a battery arbitraging in the day-ahead market, it's simply revenue:
maximize: Σ price[t] × (p_discharge[t] − p_charge[t]) for t = 1..24
When you discharge, you sell at price[t]. When you charge, you buy at price[t].
The optimizer will find the charge/discharge pattern that maximizes this sum.
Constraints are the physical and contractual limits the optimizer must respect. Without them, the optimizer would just say "discharge infinite power at peak price." Some battery constraints:
0 ≤ p_charge[t] ≤ P_max and 0 ≤ p_discharge[t] ≤ P_max0 ≤ SoC[t] ≤ E_max (state of charge can't exceed battery size)SoC[t] = SoC[t-1] + η×p_charge[t] − p_discharge[t]/η (what goes in must come out, minus losses)
The parameter η (eta) is round-trip efficiency — typically 0.85–0.92 for lithium-ion. This is a
parameter, not a decision variable.
Here's the complete structure of a simple battery day-ahead optimization:
Given (parameters):
price[t] — day-ahead price for each hour (€/MWh)
P_max — max charge/discharge power (MW)
E_max — battery energy capacity (MWh)
η — round-trip efficiency
SoC_init — initial state of charge (MWh)
Find (decision variables):
p_charge[t], p_discharge[t] for t = 1..24
Maximize (objective):
Σ price[t] × (p_discharge[t] − p_charge[t])
Subject to (constraints):
0 ≤ p_charge[t] ≤ P_max
0 ≤ p_discharge[t] ≤ P_max
SoC[t] = SoC[t-1] + η×p_charge[t] − p_discharge[t]/η
0 ≤ SoC[t] ≤ E_max
SoC[0] = SoC_init
In the battery formulation above, which of the following is a decision variable?
Why can't the optimizer simply discharge at maximum power during the most expensive hour and do nothing else?
If you wanted the optimizer to also minimize battery degradation, what would you need to change?
You now know the anatomy of any optimization problem. In Lesson 2, we'll implement this exact formulation in Python using the Pyomo library and the HiGHS solver — and run it on real day-ahead price data. You'll see the optimizer produce a dispatch schedule within seconds.
Boyd & Vandenberghe, Convex Optimization, Chapter 1 (pp. 1–15) — "Introduction" gives the formal definition of an optimization problem and the intuition behind it. Free PDF. Just read the first 15 pages.
Rechtliches: Impressum