MAST30034 Applied Data Science · 2021 S2 industry brief · practice
Charge when it's cheap.
Sell when it isn't.
A 300 MW / 580 MWh grid battery in Victoria, scheduled by a linear program on eight years of public AEMO spot prices. The 2022 practice repo for this brief never got past its folder scaffold; this is the brief, finally solved and made explorable.
Perfect foresight · Tue 6 Jul 2021
Best day of the brief's test window
- Bought at
- $144.30
- Sold at
- $466.71
- Cycles
- 3.59
- Perfect-foresight revenue
- $5.93M
- Test window 1 Jul 2021 to 11 Aug 2021
- Captured without foresight
- 63%
- Time-of-day schedule, the best of four practical policies
- Deliverable 1, single cycle
- $43,360
- Best revenue on 17 Jul 2020 with at most 580 MWh discharged
- Half-hours verified
- 63,456
- of 63,456 match the staff dataset exactly
The brief, in plain words
One battery, one price signal, two levels of honesty
Victoria's wholesale electricity price is reset every half hour. A big battery makes money by charging when power is cheap (often at midday, when rooftop solar floods the grid) and discharging into the evening peak. Every round trip loses about a fifth of the energy, so only large enough price gaps are worth trading.
The industry brief behind MAST30034 in 2021 asked for two algorithms. Students worked on 2018 to 2020 for training, the first half of 2021 for cross-validation, and a six-week test window from 1 July to 11 August 2021.
The perfect but impractical battery
Knows every future price. Find the revenue-maximising schedule: a linear program.
The practical but imperfect battery
Sees only past and current prices. Decide each half hour without peeking ahead.
Spec sheet
Battery technical and commercial properties
| Region | VIC1 | Sets which spot price the battery trades at |
|---|---|---|
| Power | 300 MW | Max charge or discharge rate |
| Capacity | 580 MWh | About 1.9 hours at full power |
| Charge efficiency | 90% | Share of grid energy that gets stored |
| Discharge efficiency | 90% | Share of stored energy that reaches the grid |
| Marginal loss factor | 0.991 | Transmission losses at the connection point |
| Capital cost | $0 | Treated as sunk |
| Fixed O&M | $8.10 / kW / yr | $2,430,000 a year at 300 MW |
| Variable O&M | $0 / MWh | Adjustable as degradation in the Lab |
Results at a glance
Hindsight is worth 37% of the money
Revenue over the brief's six-week test window, with the battery starting empty on 1 July 2021 and carrying its charge from day to day.
- Perfect foresightforesight$5.93M · 100%
- Perfect foresight, daily resetforesight$5.92M · 100%
- Time-of-day schedulebest practical$3.75M · 63%
- Rolling persistence (MPC)$2.44M · 41%
- Day-ahead persistence$2.25M · 38%
- Fixed price thresholds$1.59M · 27%
How sure? · added in 2026
One six-week total is one draw. Day by day, with 95% block-bootstrap intervals, the time-of-day schedule's share of perfect foresight is:
Sensitivity and regret with intervalsBrief test window · n = 42 days
63.3%
95% CI 52.7% to 73.0%
Calendar 2025 · n = 365 days
51.6%
95% CI 40.9% to 58.7%
Beyond the brief: the same perfect battery would have earned $33.4M across 2018 and $56.8M across 2025, as negative midday prices became routine (57 negative half-hours in 2018, 4,218 in 2025). Explore the Price Atlas.
What's inside
Six ways in
Dispatch Lab
Any day from 2018 to 2025. Change power, capacity, efficiency or degradation and re-solve the optimisation in your browser.
OpenPrice Atlas
Every half-hour of Victorian prices as a heatmap, the deepening solar duck curve, and what a perfect battery could have earned each day.
OpenSix-week benchmark
The brief's test window: perfect foresight against four strategies that cannot see the future.
OpenSizing and losses
How revenue scales with power, hours of storage, round-trip efficiency and wear costs.
OpenEvaluation with uncertainty
Sensitivity and regret with 95% intervals over market days, paired comparisons, printed seeds, and a test of the AI explanations.
OpenMethods and decisions
The linear program, the evaluation design, decision records, a model card, the AI use statement and Deliverable 1.
Open
About this project
A practice run, revived
In May 2022 Rin and Martin set up a repository to attempt this brief in their own time, alongside the industry project they were assessed on. It stopped at a README, an environment script and an empty folder tree. This site completes it: the mandatory linear program, the bonus no-foresight policies, and the Deliverable 1 questions.
2021 S2
Battery brief set in MAST30034 at the University of Melbourne.
May 2022
Practice repo scaffolded (README, conda/venv setup, folders). No model code.
2026
Revived: public AEMO data, Python reference solver, TypeScript port, this site.
Project card
MAST30034 · Applied Data Science
- University
- The University of Melbourne
- Brief
- 2021 Semester 2 industry project: grid-battery revenue optimisation
- Status
- Self-run practice, ungraded. Not a submission and not an official course resource.
- Team
- Sunchuangyu (Rin) Huang, with Martin (Quizihan Wu) as practice teammate
- Original stack
- Python 3.10, Jupyter, conda / venv scaffold (no model code)
- Revived stack
- Python + SciPy/HiGHS MILP (reference), TypeScript LP + branch-and-bound (browser), SQLite, Next.js 16, Tailwind CSS
- Data
- AEMO aggregated price and demand, VIC1, 1 Jan 2018 to 31 Dec 2025 (half-hourly; five-minute prices averaged from Oct 2021)
- Source
- Revived code: private GitHub repository, public release pending.Original 2022 scaffold: preserved unchanged under coursework/original in the project repository. Course-supplied data and brief figures are not redistributed.
Try Deliverable 1 yourself
What could the battery earn on Fri 17 Jul 2020 with a single cycle? The optimiser says $43,360: charge 03:00–04:00, 05:30–06:00 and 13:30–15:00, sell 08:00–08:30, 10:00–10:30 and 17:30–18:30.
The cap is on energy discharged (580 MWh, one full battery), so the best schedule charges and sells twice. Why, and the stricter reading.