{"id":18088504,"url":"https://github.com/prakaa/nemstorageunderuncertainty","last_synced_at":"2026-02-09T04:05:32.963Z","repository":{"id":62133699,"uuid":"554035321","full_name":"prakaa/NEMStorageUnderUncertainty","owner":"prakaa","description":"Modelling to investigate how imperfect foresight and information affects storage operation. Case studies using data from the Australian National Electricity Market and the Australian Energy Market Operator","archived":false,"fork":false,"pushed_at":"2024-12-06T04:12:42.000Z","size":162846,"stargazers_count":6,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-13T03:12:59.794Z","etag":null,"topics":["aemo","energy","energy-storage","forecasting","julia","jump","national-electricity-market","pre-dispatch"],"latest_commit_sha":null,"homepage":"https://prakaa.github.io/NEMStorageUnderUncertainty/","language":"Julia","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/prakaa.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-10-19T06:30:55.000Z","updated_at":"2024-12-06T04:02:58.000Z","dependencies_parsed_at":"2023-09-24T09:17:13.746Z","dependency_job_id":"b6133d9a-9286-4402-80d7-5dde64666d5d","html_url":"https://github.com/prakaa/NEMStorageUnderUncertainty","commit_stats":{"total_commits":372,"total_committers":1,"mean_commits":372.0,"dds":0.0,"last_synced_commit":"09cf989af184868398d6dd6e8dbbe46db02c92ac"},"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prakaa%2FNEMStorageUnderUncertainty","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prakaa%2FNEMStorageUnderUncertainty/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prakaa%2FNEMStorageUnderUncertainty/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prakaa%2FNEMStorageUnderUncertainty/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/prakaa","download_url":"https://codeload.github.com/prakaa/NEMStorageUnderUncertainty/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248657923,"owners_count":21140846,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aemo","energy","energy-storage","forecasting","julia","jump","national-electricity-market","pre-dispatch"],"created_at":"2024-10-31T17:13:12.931Z","updated_at":"2026-02-09T04:05:32.932Z","avatar_url":"https://github.com/prakaa.png","language":"Julia","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NEMStorageUnderUncertainty\n\n[![CI](https://github.com/prakaa/NEMStorageUnderUncertainty/actions/workflows/CI.yml/badge.svg)](https://github.com/prakaa/NEMStorageUnderUncertainty/actions/workflows/CI.yml)\n[![codecov](https://codecov.io/gh/prakaa/NEMStorageUnderUncertainty/branch/master/graph/badge.svg?token=K14NYRGFPX)](https://codecov.io/gh/prakaa/NEMStorageUnderUncertainty)\n[![Documentation](https://github.com/prakaa/NEMStorageUnderUncertainty/actions/workflows/Docs.yml/badge.svg)](https://prakaa.github.io/NEMStorageUnderUncertainty/dev/)\n[![Code Style: Blue](https://img.shields.io/badge/code%20style-blue-4495d1.svg)](https://github.com/invenia/BlueStyle)\n[![DOI](https://zenodo.org/badge/554035321.svg)](https://zenodo.org/badge/latestdoi/554035321)\n\nThis repository contains the following:\n  1. Analysis of historical prices and of (30-minute) pre-dispatch and 5-minute pre-dispatch price \"forecast\"[^1] errors from the Australian National Electricity Market (NEM).\n  2. Source code and results from simulations that investigate how imperfect foresight affects storage arbitrage operation and revenues. This modelling uses historical actual price data and price forecasts from pre-dispatch \u0026 5-minute pre-dispatch.\n  \nThe results from this study have been submitted for publication. You can use this repository to access the model source code, documentation and results in the form of charts. \n\n[^1]: We use the term *\"forecast\"* loosely, especially given that these *\"forecasts\"* change once participants update offer information (e.g. through rebidding) or submit revised resource availabilities and energy constraints. Both of these are intended outcomes of these *\"ahead processes\"*, which are run by the Australian Energy Market Operator (AEMO) to provide system and market information to participants to inform their decision-making. However, to avoid confusion and to ensure consistency with the language used by AEMO, we use the term *\"forecast\"*.\n\n## Analysis of prices \u0026 price forecast errors in the NEM\n\nAll charts produced from the analysis of prices \u0026 price forecast errors in the NEM can be found [here](price-characterisation/plots). A couple of the most interesting charts are linked below.\n\n- [This chart](price-characterisation/plots/historical/spreads/historical_daily_price_spreads.pdf) shows that historical daily price spreads ($p_{max} - p_{min}$ for each day) have been increasing over time in each region of the NEM\n- [This chart](price-characterisation/plots/historical/nsw/tod.pdf) shows the median, 5th and 95th percentile prices in NSW for each dispatch interval in 2021 (i.e. by time of day)\n- [This chart](price-characterisation/plots/historical/errors/price_errors_nemwide_2012_2021.pdf) shows how price forecast errors in the day-ahead and hour-ahead horizons have increased in the past few years. Months with a high number of large price errors do not appear to necessarily coincide with market or system events\n\n### Source code installation\n\n1. Install poetry\n2. Use poetry within [price-characterisation](./price-characterisation) to install the required dependencies\n3. Run `.py` plot scripts\n\n## Simulating storage operation under uncertainty\n\nStudy terminology and detailed methodology (e.g. objective functions, constraints, etc.) can be found in the [source code documentation](https://prakaa.github.io/NEMStorageUnderUncertainty/).\n\n### Overview of methodology\n\n1. At a decision point, optimise a battery energy storage system (BESS) according to model formulation (objective function) for duration of lookahead horizon using 5-minute pre-dispatch (5MPD) and (30-minute) pre-dispatch (PD) price \"forecasts\"\n    - Remove PD forecasts that overlap with 5MPD and only use 5MPD within hour ahead\n2. Take results but only *bind* the dispatch decision of next interval (i.e. 5 minutes ahead)\n3. Roll horizon forward (rolling horizon optimal control at a frequency of 5 minutes) \u0026 repeat until entire year simulated\n4. Repeat steps 1-3 with actual price data\n5. Run perfect foresight model, where BESS is optimised across entire year with actual data in one go\n\n![Simulation procedure](docs/src/sim_example.png)\n\n### Formulations\n\nA variety of formulations (objective functions) are modelled. Refer to [this section](https://prakaa.github.io/NEMStorageUnderUncertainty/dev/formulations/) of the documentation for more detail.\n\n### Values of perfect lookahead (VPL) and perfect information (VPI)\n\n**Value of perfect lookahead**: What is the additional benefit (revenue) that a participant\ncould gain if they were to know exactly what the market prices will be in the *lookahead\nhorizon*.\n\n```math\nVPL = \\textrm{Revenue}_\\textrm{Actual Data Simulation} -  \\textrm{Revenue}_\\textrm{Forecast Data Simulation}$$\n```\n\n**Value of perfect information**: What is the additional benefit (revenue) that a participant\ncould gain if they were to know exactly what the market prices will be *over the entire\nyear*\n\n```math\nVPI = \\textrm{Revenue}_\\textrm{Perfect Foresight} -  \\textrm{Revenue}_\\textrm{Forecast Data Simulation}\n```\n\n### Results\n\nAll charts produced from the analysis of simulation results can be found [here](results/plots). A couple of the most interesting charts are linked below.\n\n- [This chart](results/plots/revenues/NSW_100.0MWh_100.0MW_allformulations_revenue.pdf) shows absolute revenues for a 1 hour duration BESS (100 MW/100 MWh) for different lookahead horizons and modelled formulations\n- [This chart](results/plots/operation/NSW_100MW_100MWh_Revenue_Lookahead.pdf) shows how under imperfect foresight, a 1 hour duration BESS can miss significant discharge opportunities or make very poor charge decisions\n- [This chart](results/plots/vpl_vpi/NSW_100_allformulations_vpl_vpi.pdf) shows VPLs and VPIs for BESS with durations of 15 minutes, 1 hour and 4 hours across lookaheads and modelled formulations\n- [This chart](results/plots/throughput/NSW_100_arbitrage_throughputpenalty_no_degradation_600000_throughputs.pdf) shows the cumulative throughput of BES with durations of 15 minutes, 1 hour and 4 hours (all with modelled throughput penalty that amortises a BESS capital cost of 600,000 AUD/MWh across BESS lifetime throughput) across the modelled year (2021).\n\n\"Actual prices in binding\" results are located in [results/data/actual-prices-binding](results/data/actual-prices-binding).\n\n### Source code installation\n\n#### Julia environment\n\n1. Hit `]` to enter package mode\n2. With this project as the current directory, enter:\n  ```julia\n  activate .\n  ```\n3. Then instantiate the project\n  ```julia\n  instantiate\n  ```\n#### Obtain price data\n\nWe make use of [`NEMOSIS`](https://github.com/UNSW-CEEM/NEMOSIS) and [`NEMSEER`](https://github.com/UNSW-CEEM/NEMSEER) to obtain actual and forecast regional price data, respectively.\n\nTo populate `data/` with the required data, run (with this project as the current directory):\n```bash\nmake get_NEM_data\n```\nThis command installs the mini-package located in `data_scripts/`, installs the `get_data.py` script as a console command and then runs the console command to obtain the data\n\n- The Makefile assumes Python 3 is installed on your machine.\n\n## Author \u0026 licenses\n\nThis modelling framework and its associated case studies were developed by Abhijith (Abi) Prakash, PhD Candidate at the UNSW Collaboration on Energy and Environmental Markets.\n\nThe source code from this work is licensed under the terms of [GNU GPL-3.0-or-later licences](./LICENSE).\n\nThe results (generated plots) and the content within the documentation for this project is licensed under a [Creative Commons Attribution 4.0 International License](http://creativecommons.org/licenses/by/4.0/).\n\nIf you use any of the material from this work, please cite the [Zenodo DOI](https://zenodo.org/badge/latestdoi/554035321).\n\n## Acknowledgements\n\nData used in this study were made accessible by [`NEMOSIS`](https://github.com/UNSW-CEEM/NEMOSIS) and [`NEMSEER`](https://github.com/UNSW-CEEM/NEMSEER).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprakaa%2Fnemstorageunderuncertainty","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprakaa%2Fnemstorageunderuncertainty","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprakaa%2Fnemstorageunderuncertainty/lists"}