Skip to content
Battery Arbitrage Lab (home)

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

$535,324
Perfect-foresight schedule on 6 Jul 2021: 48 half-hour periods. Prices $101.24 to $2,618.09 per MWh. Charging in 16 periods, discharging in 15. Revenue $535,324.0301003001k$/MWh · log scaleMW-3000+30000:0003:0006:0009:0012:0015:0018:0021:0024:00
Spot priceCharging (buy)Discharging (sell)
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.

Mandatory

The perfect but impractical battery

Knows every future price. Find the revenue-maximising schedule: a linear program.

Bonus

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

Battery parameters from the brief
RegionVIC1
Power300 MW
Capacity580 MWh
Charge efficiency90%
Discharge efficiency90%
Marginal loss factor0.991
Capital cost$0
Fixed O&M$8.10 / kW / yr
Variable O&M$0 / MWh

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.

Full benchmark
  1. Perfect foresightforesight$5.93M · 100%
  2. Perfect foresight, daily resetforesight$5.92M · 100%
  3. Time-of-day schedulebest practical$3.75M · 63%
  4. Rolling persistence (MPC)$2.44M · 41%
  5. Day-ahead persistence$2.25M · 38%
  6. 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 intervals

Brief 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

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.

  1. 2021 S2

    Battery brief set in MAST30034 at the University of Melbourne.

  2. May 2022

    Practice repo scaffolded (README, conda/venv setup, folders). No model code.

  3. 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.

Open it with one cycle