pricecast 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mattéo Hauglustaine
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,177 @@
1
+ Metadata-Version: 2.4
2
+ Name: pricecast
3
+ Version: 0.1.0
4
+ Summary: Synthetic hourly electricity price years for prospective energy system studies
5
+ Author-email: Matteo Hauglustaine <matteo@abeo.be>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/Matt-haug/pricecast
8
+ Project-URL: Repository, https://github.com/Matt-haug/pricecast
9
+ Project-URL: Issues, https://github.com/Matt-haug/pricecast/issues
10
+ Keywords: electricity,day-ahead price,price profile,synthetic data,energy system modelling,techno-economic analysis,duck curve,time series
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Science/Research
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Scientific/Engineering
19
+ Requires-Python: >=3.9
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: numpy>=1.21
23
+ Requires-Dist: pandas>=1.3
24
+ Provides-Extra: entsoe
25
+ Requires-Dist: entsoe-py>=0.6; extra == "entsoe"
26
+ Provides-Extra: plot
27
+ Requires-Dist: matplotlib>=3.5; extra == "plot"
28
+ Provides-Extra: test
29
+ Requires-Dist: pytest>=7.0; extra == "test"
30
+ Provides-Extra: docs
31
+ Requires-Dist: mkdocs>=1.5; extra == "docs"
32
+ Requires-Dist: mkdocs-material>=9.0; extra == "docs"
33
+ Requires-Dist: mkdocstrings[python]>=0.24; extra == "docs"
34
+ Provides-Extra: dev
35
+ Requires-Dist: pricecast[docs,entsoe,plot,test]; extra == "dev"
36
+ Dynamic: license-file
37
+
38
+ [![PyPI version](https://img.shields.io/pypi/v/pricecast)](https://pypi.org/project/pricecast/)
39
+ [![Documentation Status](https://img.shields.io/readthedocs/loadcast)](https://pricecast.readthedocs.io/en/latest/)
40
+ [![Build Status](https://github.com/Matt-haug/pricecast/actions/workflows/tests.yml/badge.svg)](https://github.com/Matt-haug/pricecast/actions/workflows/tests.yml)
41
+ [![License](https://img.shields.io/github/license/Matt-haug/pricecast)](https://github.com/Matt-haug/pricecast/blob/main/LICENSE)
42
+ [![DOI](https://img.shields.io/badge/DOI-10.5281%2Fzenodo.23264989-blue)](https://doi.org/10.5281/zenodo.23264989)
43
+
44
+ # pricecast
45
+
46
+ **Synthetic hourly electricity price time-series for prospective energy system studies**
47
+
48
+ ```python
49
+ import pricecast
50
+ from pricecast.entsoe import fetch_year
51
+
52
+ prices, drivers = fetch_year("BE", 2025) # day-ahead price, load, solar, wind
53
+ model = pricecast.load("BE") # or pricecast.fit(prices, drivers)
54
+
55
+ future = pricecast.scale_drivers(drivers, solar=1.39, wind=1.38, load=1.30)
56
+ year = model.predict(future) # the shape of a 2030 year
57
+ year = pricecast.rescale_to_level(year, level=88) # its level, from a fuel-and-carbon scenario
58
+ ```
59
+
60
+ Returns an hourly series of day-ahead prices in EUR/MWh, ready to feed an LP or
61
+ MILP design model: a heat pump with storage, a battery, a thermal store, an
62
+ electrolyser.
63
+
64
+ ![The average day of 2025: the model keeps the duck curve that a reused year cannot know about](https://raw.githubusercontent.com/Matt-haug/pricecast/main/docs/figures/daily_shape_2025.png)
65
+
66
+ *The average day of 2025, each series over its own annual mean. The model (fitted
67
+ on 2023-24, driven by 2025's load, solar and wind) keeps the midday trough;
68
+ reusing a past year cannot know about the panels installed since.*
69
+
70
+ ## Why
71
+
72
+ A study that sizes equipment for 2030 needs a 2030 price year. The usual
73
+ stand-in is a past year reused as it was, which carries the past's solar fleet,
74
+ the past's price level, and the past's weather. `pricecast` instead generates the
75
+ year from what a scenario *does* provide - installed solar and wind, demand and
76
+ fuel prices - so the features a design reacts to follow the scenario:
77
+
78
+ - how deep the price falls at midday, and how far it climbs in the evening;
79
+ - what a solar kilowatt-hour is worth against the average one;
80
+ - what the electricity for a kilowatt-hour of heat costs.
81
+
82
+ The model is one least-squares regression of hourly price on the clock and on
83
+ three drivers - load, solar and wind generation - fitted on recent years. A full
84
+ year is generated in one shot, with no autoregression on the price.
85
+
86
+ **It is not a forecaster.** Nobody has next decade's hourly solar output, so it
87
+ does not compete with forecasting models. It produces a plausible *shape* and
88
+ leaves the *level* to an outside scenario, because the level is set by fuel and
89
+ carbon prices and cannot be extrapolated from price history.
90
+
91
+ ## What it has been tested on
92
+
93
+ Five European markets (BE, DE, FR, ES, PL), fitted on 2023-24 and judged on 2025
94
+ by what a design optimiser decides, not by hourly error:
95
+
96
+ | | this model | last year's prices reused |
97
+ |---|---|---|
98
+ | daily storage, share of achievable arbitrage captured | 88% | 60% |
99
+ | household with PV, battery and heat pump, share of savings captured | 93% | 82% |
100
+ | sizing penalty with the price level given, data 1 / 2 / 4 / 6 years old (EUR/yr) | 2 / 29 / 16 / 7 | 8 / 94 / 147 / 198 |
101
+ | midday price / annual mean, mean absolute error across countries | 0.09 | 0.11 |
102
+ | solar value factor, mean absolute error | 0.07 | 0.11 |
103
+
104
+ Full results, and where it falls short, are in the accompanying paper.
105
+
106
+ ## Building a future year
107
+
108
+ The [recipe](docs/recipe.md), in short:
109
+
110
+ 1. **Fit** on the two most recent complete years, or start from `pricecast.load`.
111
+ 2. **Choose one weather year** and take every weather-dependent input from it:
112
+ the model's drivers, and your asset's PV output, heat demand and ambient
113
+ temperature. Prices respond to the same weather; mixing years makes heat
114
+ look 2-10% cheaper than it is.
115
+ 3. **Scale the drivers** by target-over-weather-year capacity and demand
116
+ (`scale_drivers`), from ERAA, TYNDP or national plans.
117
+ 4. **Run the model** (`PriceModel.predict`).
118
+ 5. **Set the level** as the market's recent ratio times a gas plant's running
119
+ cost in the target year (`level_ratio`, `gas_plant_cost`,
120
+ `rescale_to_level`). **Err low**: an overestimated level costs a design far
121
+ more than an underestimated one.
122
+ 6. **Check the reach** (`share_beyond_training`): where several percent of
123
+ hours lie beyond the net load the model was fitted on, floor the year at the
124
+ training years' 1% price quantile (`training_floor`).
125
+
126
+ ![2030 built from ERAA 2025 drivers and a gas-plant level, on 2025 weather](https://raw.githubusercontent.com/Matt-haug/pricecast/main/docs/figures/year_2030.png)
127
+
128
+ *2030 from ERAA 2025 capacities and demand on 2025 weather. Germany and Poland
129
+ (13% and 7% of hours beyond the training net load) need the floor.*
130
+
131
+ ## What it does not do
132
+
133
+ - **Negative hours.** It smooths away part of the midday collapse in
134
+ solar-heavy markets: 1.8% negative hours against 5.7% in reality in 2025. The
135
+ residual noise (`noise=True`) restores the share, but in hours uncorrelated
136
+ with the real ones - use it for revenue estimates, never for sizing.
137
+ - **Extrapolation.** It is linear in its drivers; far beyond them it must be
138
+ floored, and it has no storage driver, so future spreads are upper bounds.
139
+ - **Drifting coefficients.** The price response to solar steepens as the fleet
140
+ grows. Correcting the coefficients for that was tested and does not pay;
141
+ refit on recent years instead.
142
+ - **Other markets.** Day-ahead only - not intraday, balancing or forward.
143
+
144
+ ## Install
145
+
146
+ ```bash
147
+ pip install git+https://github.com/Matt-haug/pricecast
148
+ pip install "pricecast[entsoe] @ git+https://github.com/Matt-haug/pricecast" # with ENTSO-E download
149
+ ```
150
+
151
+ Requires Python 3.9+, numpy and pandas. Downloading data needs `entsoe-py` and a
152
+ free ENTSO-E Transparency Platform token, passed as `token=` or set as the
153
+ `ENTSOE_TOKEN` environment variable.
154
+
155
+ ## Data
156
+
157
+ The shipped models are fitted on ENTSO-E Transparency Platform data for
158
+ 2024-2025: day-ahead prices, actual total load and actual generation per
159
+ production type. What ships is the fitted coefficients only; the raw series are
160
+ not redistributed and are downloaded with your own token.
161
+
162
+ ## Contributing
163
+
164
+ Issues and pull requests are welcome - see [CONTRIBUTING.md](CONTRIBUTING.md).
165
+ Reports that a generated year disagrees with a market you know well are
166
+ especially welcome. This project follows the
167
+ [Contributor Covenant](CODE_OF_CONDUCT.md). Generative AI was used in building
168
+ it; see [AI_USAGE.md](AI_USAGE.md).
169
+
170
+ ## Citing
171
+
172
+ Use the "Cite this repository" button, or `CITATION.cff`. Each release is
173
+ archived on Zenodo with a DOI.
174
+
175
+ ## Licence
176
+
177
+ MIT - see [LICENSE](LICENSE). Changes are recorded in [CHANGELOG.md](CHANGELOG.md).
@@ -0,0 +1,140 @@
1
+ [![PyPI version](https://img.shields.io/pypi/v/pricecast)](https://pypi.org/project/pricecast/)
2
+ [![Documentation Status](https://img.shields.io/readthedocs/loadcast)](https://pricecast.readthedocs.io/en/latest/)
3
+ [![Build Status](https://github.com/Matt-haug/pricecast/actions/workflows/tests.yml/badge.svg)](https://github.com/Matt-haug/pricecast/actions/workflows/tests.yml)
4
+ [![License](https://img.shields.io/github/license/Matt-haug/pricecast)](https://github.com/Matt-haug/pricecast/blob/main/LICENSE)
5
+ [![DOI](https://img.shields.io/badge/DOI-10.5281%2Fzenodo.23264989-blue)](https://doi.org/10.5281/zenodo.23264989)
6
+
7
+ # pricecast
8
+
9
+ **Synthetic hourly electricity price time-series for prospective energy system studies**
10
+
11
+ ```python
12
+ import pricecast
13
+ from pricecast.entsoe import fetch_year
14
+
15
+ prices, drivers = fetch_year("BE", 2025) # day-ahead price, load, solar, wind
16
+ model = pricecast.load("BE") # or pricecast.fit(prices, drivers)
17
+
18
+ future = pricecast.scale_drivers(drivers, solar=1.39, wind=1.38, load=1.30)
19
+ year = model.predict(future) # the shape of a 2030 year
20
+ year = pricecast.rescale_to_level(year, level=88) # its level, from a fuel-and-carbon scenario
21
+ ```
22
+
23
+ Returns an hourly series of day-ahead prices in EUR/MWh, ready to feed an LP or
24
+ MILP design model: a heat pump with storage, a battery, a thermal store, an
25
+ electrolyser.
26
+
27
+ ![The average day of 2025: the model keeps the duck curve that a reused year cannot know about](https://raw.githubusercontent.com/Matt-haug/pricecast/main/docs/figures/daily_shape_2025.png)
28
+
29
+ *The average day of 2025, each series over its own annual mean. The model (fitted
30
+ on 2023-24, driven by 2025's load, solar and wind) keeps the midday trough;
31
+ reusing a past year cannot know about the panels installed since.*
32
+
33
+ ## Why
34
+
35
+ A study that sizes equipment for 2030 needs a 2030 price year. The usual
36
+ stand-in is a past year reused as it was, which carries the past's solar fleet,
37
+ the past's price level, and the past's weather. `pricecast` instead generates the
38
+ year from what a scenario *does* provide - installed solar and wind, demand and
39
+ fuel prices - so the features a design reacts to follow the scenario:
40
+
41
+ - how deep the price falls at midday, and how far it climbs in the evening;
42
+ - what a solar kilowatt-hour is worth against the average one;
43
+ - what the electricity for a kilowatt-hour of heat costs.
44
+
45
+ The model is one least-squares regression of hourly price on the clock and on
46
+ three drivers - load, solar and wind generation - fitted on recent years. A full
47
+ year is generated in one shot, with no autoregression on the price.
48
+
49
+ **It is not a forecaster.** Nobody has next decade's hourly solar output, so it
50
+ does not compete with forecasting models. It produces a plausible *shape* and
51
+ leaves the *level* to an outside scenario, because the level is set by fuel and
52
+ carbon prices and cannot be extrapolated from price history.
53
+
54
+ ## What it has been tested on
55
+
56
+ Five European markets (BE, DE, FR, ES, PL), fitted on 2023-24 and judged on 2025
57
+ by what a design optimiser decides, not by hourly error:
58
+
59
+ | | this model | last year's prices reused |
60
+ |---|---|---|
61
+ | daily storage, share of achievable arbitrage captured | 88% | 60% |
62
+ | household with PV, battery and heat pump, share of savings captured | 93% | 82% |
63
+ | sizing penalty with the price level given, data 1 / 2 / 4 / 6 years old (EUR/yr) | 2 / 29 / 16 / 7 | 8 / 94 / 147 / 198 |
64
+ | midday price / annual mean, mean absolute error across countries | 0.09 | 0.11 |
65
+ | solar value factor, mean absolute error | 0.07 | 0.11 |
66
+
67
+ Full results, and where it falls short, are in the accompanying paper.
68
+
69
+ ## Building a future year
70
+
71
+ The [recipe](docs/recipe.md), in short:
72
+
73
+ 1. **Fit** on the two most recent complete years, or start from `pricecast.load`.
74
+ 2. **Choose one weather year** and take every weather-dependent input from it:
75
+ the model's drivers, and your asset's PV output, heat demand and ambient
76
+ temperature. Prices respond to the same weather; mixing years makes heat
77
+ look 2-10% cheaper than it is.
78
+ 3. **Scale the drivers** by target-over-weather-year capacity and demand
79
+ (`scale_drivers`), from ERAA, TYNDP or national plans.
80
+ 4. **Run the model** (`PriceModel.predict`).
81
+ 5. **Set the level** as the market's recent ratio times a gas plant's running
82
+ cost in the target year (`level_ratio`, `gas_plant_cost`,
83
+ `rescale_to_level`). **Err low**: an overestimated level costs a design far
84
+ more than an underestimated one.
85
+ 6. **Check the reach** (`share_beyond_training`): where several percent of
86
+ hours lie beyond the net load the model was fitted on, floor the year at the
87
+ training years' 1% price quantile (`training_floor`).
88
+
89
+ ![2030 built from ERAA 2025 drivers and a gas-plant level, on 2025 weather](https://raw.githubusercontent.com/Matt-haug/pricecast/main/docs/figures/year_2030.png)
90
+
91
+ *2030 from ERAA 2025 capacities and demand on 2025 weather. Germany and Poland
92
+ (13% and 7% of hours beyond the training net load) need the floor.*
93
+
94
+ ## What it does not do
95
+
96
+ - **Negative hours.** It smooths away part of the midday collapse in
97
+ solar-heavy markets: 1.8% negative hours against 5.7% in reality in 2025. The
98
+ residual noise (`noise=True`) restores the share, but in hours uncorrelated
99
+ with the real ones - use it for revenue estimates, never for sizing.
100
+ - **Extrapolation.** It is linear in its drivers; far beyond them it must be
101
+ floored, and it has no storage driver, so future spreads are upper bounds.
102
+ - **Drifting coefficients.** The price response to solar steepens as the fleet
103
+ grows. Correcting the coefficients for that was tested and does not pay;
104
+ refit on recent years instead.
105
+ - **Other markets.** Day-ahead only - not intraday, balancing or forward.
106
+
107
+ ## Install
108
+
109
+ ```bash
110
+ pip install git+https://github.com/Matt-haug/pricecast
111
+ pip install "pricecast[entsoe] @ git+https://github.com/Matt-haug/pricecast" # with ENTSO-E download
112
+ ```
113
+
114
+ Requires Python 3.9+, numpy and pandas. Downloading data needs `entsoe-py` and a
115
+ free ENTSO-E Transparency Platform token, passed as `token=` or set as the
116
+ `ENTSOE_TOKEN` environment variable.
117
+
118
+ ## Data
119
+
120
+ The shipped models are fitted on ENTSO-E Transparency Platform data for
121
+ 2024-2025: day-ahead prices, actual total load and actual generation per
122
+ production type. What ships is the fitted coefficients only; the raw series are
123
+ not redistributed and are downloaded with your own token.
124
+
125
+ ## Contributing
126
+
127
+ Issues and pull requests are welcome - see [CONTRIBUTING.md](CONTRIBUTING.md).
128
+ Reports that a generated year disagrees with a market you know well are
129
+ especially welcome. This project follows the
130
+ [Contributor Covenant](CODE_OF_CONDUCT.md). Generative AI was used in building
131
+ it; see [AI_USAGE.md](AI_USAGE.md).
132
+
133
+ ## Citing
134
+
135
+ Use the "Cite this repository" button, or `CITATION.cff`. Each release is
136
+ archived on Zenodo with a DOI.
137
+
138
+ ## Licence
139
+
140
+ MIT - see [LICENSE](LICENSE). Changes are recorded in [CHANGELOG.md](CHANGELOG.md).
@@ -0,0 +1,60 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "pricecast"
7
+ version = "0.1.0"
8
+ description = "Synthetic hourly electricity price years for prospective energy system studies"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = "MIT"
12
+ authors = [
13
+ { name = "Matteo Hauglustaine", email = "matteo@abeo.be" },
14
+ ]
15
+ keywords = [
16
+ "electricity",
17
+ "day-ahead price",
18
+ "price profile",
19
+ "synthetic data",
20
+ "energy system modelling",
21
+ "techno-economic analysis",
22
+ "duck curve",
23
+ "time series",
24
+ ]
25
+ classifiers = [
26
+ "Development Status :: 4 - Beta",
27
+ "Intended Audience :: Science/Research",
28
+ "Programming Language :: Python :: 3",
29
+ "Programming Language :: Python :: 3.9",
30
+ "Programming Language :: Python :: 3.10",
31
+ "Programming Language :: Python :: 3.11",
32
+ "Programming Language :: Python :: 3.12",
33
+ "Topic :: Scientific/Engineering",
34
+ ]
35
+ dependencies = [
36
+ "numpy>=1.21",
37
+ "pandas>=1.3",
38
+ ]
39
+
40
+ [project.optional-dependencies]
41
+ entsoe = ["entsoe-py>=0.6"]
42
+ plot = ["matplotlib>=3.5"]
43
+ test = ["pytest>=7.0"]
44
+ docs = ["mkdocs>=1.5", "mkdocs-material>=9.0", "mkdocstrings[python]>=0.24"]
45
+ dev = ["pricecast[entsoe,plot,test,docs]"]
46
+
47
+ [project.urls]
48
+ Homepage = "https://github.com/Matt-haug/pricecast"
49
+ Repository = "https://github.com/Matt-haug/pricecast"
50
+ Issues = "https://github.com/Matt-haug/pricecast/issues"
51
+
52
+ [tool.setuptools.packages.find]
53
+ where = ["src"]
54
+
55
+ [tool.setuptools.package-data]
56
+ pricecast = ["data/*.json"]
57
+
58
+ [tool.pytest.ini_options]
59
+ testpaths = ["tests"]
60
+ addopts = "-q"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,60 @@
1
+ """pricecast -- synthetic hourly electricity price years for prospective studies.
2
+
3
+ A full year of hourly day-ahead prices, generated in one shot from three
4
+ physical drivers -- load, solar and wind generation -- by a regression fitted
5
+ on recent years. It is built to be an *input* to LP and MILP design studies
6
+ (heat pumps, batteries, thermal stores, electrolysers), not to forecast
7
+ tomorrow's price.
8
+
9
+ import pricecast
10
+
11
+ model = pricecast.fit(prices, drivers) # or pricecast.load("BE")
12
+ year = model.predict(future_drivers) # the shape of the year
13
+ year = pricecast.rescale_to_level(year, level=80) # the level, from outside
14
+
15
+ What it is for
16
+ --------------
17
+ Because the price is driven by physical quantities, a scenario can be posed
18
+ directly: double the solar fleet, grow the demand, and read off what happens to
19
+ the *shape* of the price year -- the midday trough, the evening ramp, the value
20
+ of a solar kilowatt-hour. The level of the year is set from outside, from a
21
+ fuel-and-carbon scenario, because it cannot be extrapolated from price history.
22
+
23
+ What it is not
24
+ --------------
25
+ Not a forecaster: there are no future solar and wind series to forecast from.
26
+ It smooths away part of the midday price collapse in solar-heavy markets and
27
+ produces too few negative hours unless its residual noise is switched on --
28
+ which should stay off for sizing. It is linear in its drivers, so far outside
29
+ the range it was fitted on it must be floored (`share_beyond_training`).
30
+ """
31
+
32
+ from __future__ import annotations
33
+
34
+ from .features import DEFAULT_FEATURES, DRIVERS, design_matrix
35
+ from .model import PriceModel, fit, residual_noise
36
+ from .pretrained import available, load
37
+ from .scenario import (
38
+ CCGT_EFFICIENCY,
39
+ GAS_EMISSION_FACTOR,
40
+ gas_plant_cost,
41
+ level_ratio,
42
+ mid_year_capacity,
43
+ net_load,
44
+ rescale_to_level,
45
+ scale_drivers,
46
+ share_beyond_training,
47
+ training_floor,
48
+ )
49
+ from .structure import METRICS, compare, lay_on_calendar, structure_metrics
50
+
51
+ __version__ = "0.1.0"
52
+
53
+ __all__ = [
54
+ "CCGT_EFFICIENCY", "DEFAULT_FEATURES", "DRIVERS", "GAS_EMISSION_FACTOR",
55
+ "METRICS", "PriceModel", "available", "compare", "design_matrix", "fit",
56
+ "gas_plant_cost", "lay_on_calendar", "level_ratio", "load",
57
+ "mid_year_capacity", "net_load", "rescale_to_level", "residual_noise",
58
+ "scale_drivers", "share_beyond_training", "structure_metrics",
59
+ "training_floor", "__version__",
60
+ ]
@@ -0,0 +1,60 @@
1
+ {
2
+ "coefficients": {
3
+ "const": -56.5235359601092,
4
+ "hour_1": -0.7669196170514694,
5
+ "hour_2": -2.731116500299967,
6
+ "hour_3": -3.4527653674331056,
7
+ "hour_4": -1.6429779999073855,
8
+ "hour_5": 0.7686290646237683,
9
+ "hour_6": 2.595466752009719,
10
+ "hour_7": -3.1358589017332994,
11
+ "hour_8": -10.676045837259961,
12
+ "hour_9": -14.506601010880328,
13
+ "hour_10": -16.673921806288583,
14
+ "hour_11": -18.520858353391933,
15
+ "hour_12": -18.298984811653252,
16
+ "hour_13": -13.698092038253144,
17
+ "hour_14": -8.675930491839814,
18
+ "hour_15": -3.661220973966519,
19
+ "hour_16": 5.2232791877790055,
20
+ "hour_17": 15.749246737076014,
21
+ "hour_18": 17.400630672850472,
22
+ "hour_19": 9.296905386332488,
23
+ "hour_20": 4.1710832202910435,
24
+ "hour_21": 1.1066447217502757,
25
+ "hour_22": -0.32508525239284314,
26
+ "hour_23": -0.49413458536332555,
27
+ "dow_0": 9.264707146449423,
28
+ "dow_1": 8.976551496191302,
29
+ "dow_2": 8.43460328506335,
30
+ "dow_3": 6.333805991988828,
31
+ "dow_4": 5.728469942510179,
32
+ "dow_5": 2.6026486669747912,
33
+ "load": 0.020011661479056832,
34
+ "solar": -0.017238509794863417,
35
+ "wind": -0.018118779297168295,
36
+ "net_load_sq": -2.1177924502957524e-07
37
+ },
38
+ "residual_std": 27.2859419579615,
39
+ "student_df": 4.2522262189900415,
40
+ "features": {
41
+ "hour_dummies": true,
42
+ "weekday_dummies": true,
43
+ "net_load_curvature": true,
44
+ "driver_lags": [],
45
+ "timezone": "UTC"
46
+ },
47
+ "metadata": {
48
+ "country": "BE",
49
+ "bidding_zone": "BE",
50
+ "train_years": [
51
+ 2024,
52
+ 2025
53
+ ],
54
+ "hours": 17544,
55
+ "source": "ENTSO-E Transparency Platform: day-ahead prices, actual total load, actual generation per production type (solar; wind onshore + offshore), hourly means",
56
+ "fitted": "2026-10-09",
57
+ "pricecast_version": "0.1.0",
58
+ "r2_in_sample": 0.645
59
+ }
60
+ }
@@ -0,0 +1,60 @@
1
+ {
2
+ "coefficients": {
3
+ "const": 7.19026510279194,
4
+ "hour_1": -1.20148543350422,
5
+ "hour_2": -2.767557895420281,
6
+ "hour_3": -3.169483224275901,
7
+ "hour_4": -0.14403996269299663,
8
+ "hour_5": 5.268354869113266,
9
+ "hour_6": 8.805548839332554,
10
+ "hour_7": 9.178618955644064,
11
+ "hour_8": 6.862625763288568,
12
+ "hour_9": 5.06106822195469,
13
+ "hour_10": 3.13431433336983,
14
+ "hour_11": 0.3874876888249261,
15
+ "hour_12": -0.3579715679936854,
16
+ "hour_13": 1.4653212233822654,
17
+ "hour_14": 4.1527596040978265,
18
+ "hour_15": 8.399679937223057,
19
+ "hour_16": 15.501495821102045,
20
+ "hour_17": 21.82537980978079,
21
+ "hour_18": 18.968835983927757,
22
+ "hour_19": 6.8344665793981125,
23
+ "hour_20": 1.06408943971504,
24
+ "hour_21": -0.26925928084918693,
25
+ "hour_22": 0.4301775232787318,
26
+ "hour_23": 0.9847530077836216,
27
+ "dow_0": 4.52046221906403,
28
+ "dow_1": 5.354188120736446,
29
+ "dow_2": 4.519355385955019,
30
+ "dow_3": 2.9186525163558947,
31
+ "dow_4": 3.1473642291647206,
32
+ "dow_5": 2.9664983842534376,
33
+ "load": 0.0022518423956802624,
34
+ "solar": -0.0027591543389505445,
35
+ "wind": -0.0023582761389554195,
36
+ "net_load_sq": 6.597765889182483e-09
37
+ },
38
+ "residual_std": 28.829962242404854,
39
+ "student_df": 4.2,
40
+ "features": {
41
+ "hour_dummies": true,
42
+ "weekday_dummies": true,
43
+ "net_load_curvature": true,
44
+ "driver_lags": [],
45
+ "timezone": "UTC"
46
+ },
47
+ "metadata": {
48
+ "country": "DE",
49
+ "bidding_zone": "DE_LU",
50
+ "train_years": [
51
+ 2024,
52
+ 2025
53
+ ],
54
+ "hours": 17544,
55
+ "source": "ENTSO-E Transparency Platform: day-ahead prices, actual total load, actual generation per production type (solar; wind onshore + offshore), hourly means",
56
+ "fitted": "2026-10-09",
57
+ "pricecast_version": "0.1.0",
58
+ "r2_in_sample": 0.7006
59
+ }
60
+ }
@@ -0,0 +1,60 @@
1
+ {
2
+ "coefficients": {
3
+ "const": -68.94520315102986,
4
+ "hour_1": 2.320155607076745,
5
+ "hour_2": 2.5050613582949826,
6
+ "hour_3": 1.8798222606992945,
7
+ "hour_4": -0.8283885716266107,
8
+ "hour_5": -5.4451690988078,
9
+ "hour_6": -11.433150624700835,
10
+ "hour_7": -14.159816410276242,
11
+ "hour_8": -13.889161759628301,
12
+ "hour_9": -10.944550285386548,
13
+ "hour_10": -8.048337710439503,
14
+ "hour_11": -7.456152458198253,
15
+ "hour_12": -8.279015036613128,
16
+ "hour_13": -6.669495626779215,
17
+ "hour_14": -3.86999751808008,
18
+ "hour_15": -1.4653887129495744,
19
+ "hour_16": -3.034383058522941,
20
+ "hour_17": -6.727737759258486,
21
+ "hour_18": -12.90116969919224,
22
+ "hour_19": -17.297175837922904,
23
+ "hour_20": -22.455224904517042,
24
+ "hour_21": -17.25102664098335,
25
+ "hour_22": -8.764447369468675,
26
+ "hour_23": -4.0222397937104,
27
+ "dow_0": -5.155731171679184,
28
+ "dow_1": -6.476037042409885,
29
+ "dow_2": -5.680993359830503,
30
+ "dow_3": -4.964853006794855,
31
+ "dow_4": -4.594212528162333,
32
+ "dow_5": -0.07443642823720201,
33
+ "load": 0.008847771880458202,
34
+ "solar": -0.006384871806866504,
35
+ "wind": -0.007110465646601332,
36
+ "net_load_sq": -3.9232280091283656e-08
37
+ },
38
+ "residual_std": 28.049732208308708,
39
+ "student_df": 30.0,
40
+ "features": {
41
+ "hour_dummies": true,
42
+ "weekday_dummies": true,
43
+ "net_load_curvature": true,
44
+ "driver_lags": [],
45
+ "timezone": "UTC"
46
+ },
47
+ "metadata": {
48
+ "country": "ES",
49
+ "bidding_zone": "ES",
50
+ "train_years": [
51
+ 2024,
52
+ 2025
53
+ ],
54
+ "hours": 17544,
55
+ "source": "ENTSO-E Transparency Platform: day-ahead prices, actual total load, actual generation per production type (solar; wind onshore + offshore), hourly means",
56
+ "fitted": "2026-10-09",
57
+ "pricecast_version": "0.1.0",
58
+ "r2_in_sample": 0.6406
59
+ }
60
+ }