AU Hack 2026 — InCommodities case · JAKA Team
A Streamlit dashboard for exploring European electricity market data: spot prices, supply and demand, cross-border flows, weather fundamentals, market coupling, and spot price prediction from fundamentals.
The European power market behaves like a complex distributed system. Spot prices, flows, and generation are driven by supply–demand balance, weather, and cross-border coupling. This project provides:
- Interactive exploration of day-ahead spot prices, generation mix, load, and physical flows across European bidding zones
- Fundamental analysis — merit order, duck curve, renewable penetration vs price, congestion detection
- Market coupling insights — price correlation, coupling events, arbitrage opportunities
- Weather–price relationships — temperature vs load, wind vs generation, cloud vs solar, temperature extremes vs price
- Spot price prediction — train models (RandomForest, XGBoost, LightGBM, CatBoost, stacking) on load, generation, weather, and flows
Choose between bidding zones or bring your own data
Transform raw generation, load, and weather feeds into high-value charts
Select the most impactful features and train your models
Benchmark the ML pipeline against reality
- Python 3.10+
- Streamlit — dashboard UI
- pandas, numpy — data handling
- matplotlib — plotting
- scikit-learn — RandomForest, stacking, metrics
- XGBoost, LightGBM, CatBoost — gradient boosting models
- FastAPI + uvicorn — optional ML API for training/inference
- Folium — interactive zone map
- Docker — containerized deployment
- Spot prices — day-ahead electricity prices (EUR/MWh) per zone
- Total load — electricity consumption (MW)
- Generation — by fuel type (solar, wind, hydro, gas, coal, nuclear, etc.)
- Physical flows — cross-border imports/exports between zones
- Weather — temperature, wind speed, cloud cover (Open-Meteo style)
Data lives under data/ with subfolders: spot-price/, total-load/, generation/, flows/, weather/. Set DATA_ROOT if using a different path.
- Feature engineering — hour, dayofweek, month, load, renewable share, net import, weather variables
- Temporal split — train on first 80%, validate on 10%, test on last 10%
- Multi-seed ensembling — average predictions across seeds for stability
- Stacking — meta-models (Ridge, MLP) on base model predictions
- Merit order — generation stacked from cheapest (renewables) to most expensive (gas/oil)
- Duck curve — residual load shape on high-solar vs low-solar days
- Congestion detection — flows flatlining at capacity limits
- Flow driver decomposition — correlations of net import with price spread, wind, load, renewable share
- Python 3.10+
- Data in
data/(see structure above)
pip install -r requirements.txtOr in editable mode:
pip install -e .streamlit run dashboard/app.pyOpen http://localhost:8501 in your browser.
Run the dashboard as usual; training and inference run in-process. No Docker needed.
To offload training/inference to a separate service:
-
Start the ML API:
docker compose up ml-api -d
-
Run the dashboard locally:
streamlit run dashboard/app.py
-
In the Prediction tab, choose API (ML API) instead of Local. Train and predict via the API.
docker compose up --build- ML API: http://localhost:8000
- Dashboard: http://localhost:8501
Run in background:
docker compose up --build -dStop services:
docker compose down| Variable | Default | Description |
|---|---|---|
DATA_ROOT |
./data |
Path to data directory |
MODEL_DIR |
./models |
Path for saved models (ML API) |
ML_API_URL |
http://localhost:8000 |
ML API base URL (dashboard) |
Copy .env.example to .env and adjust if needed.
- Choose a zone — Use the map or dropdown to select a bidding zone (e.g. DE, FR, DK1).
- Set date range — Start and end dates filter most plots.
- Add custom zones — Optional: add zones via the sidebar section.
| Tab | What it answers |
|---|---|
| Data Overview | What data do we have, and is it complete? Distributions and time ranges per data type. |
| Spot Prices | What do spot prices look like? When do they spike, go negative, or become volatile? Peak vs off-peak spread. |
| Supply & Demand | How does supply meet demand? What drives the spot price? Why do renewables earn a profit? |
| Flows | How is power distributed between countries? What drives imports/exports? When do interconnectors hit capacity? |
| Weather | How does weather affect production and consumption? Temperature, wind, cloud cover. |
| Market Coupling | Which zones are price-linked? When do they couple or decouple? Where are arbitrage opportunities? |
| Prediction | Can we predict spot prices from fundamentals? Which features matter most per zone? |
- Choose Local (in-process) or API (ML API) if the ML service is running.
- Select a model: RandomForest (lightest), XGBoost, LightGBM, CatBoost, or Stacking (Ridge/MLP).
- Click Start train — trains on first 90% of the date range, predicts on last 10%.
- View metrics (MAE, RMSE, R²), prediction plot, and optional CSV upload for inference.
auhack2026/
├── dashboard/ # Streamlit app and plots
│ ├── app.py # Main layout, tabs, sidebar
│ ├── plots/ # Plot modules (spot_prices, supply_demand, flows, etc.)
│ ├── zone_map.py # Interactive Folium map
│ └── ml_client.py # Client for ML API
├── src/ # Shared logic
│ ├── config.py # DATA_ROOT, MODEL_DIR, ML_API_URL
│ ├── data_loader.py # Load spot, load, generation, flows, weather
│ ├── features.py # Feature engineering for prediction
│ ├── ml_trainer.py # Train/predict (RF, XGB, LGB, CB, stacking)
│ └── zone_registry.py # Zone discovery (built-in + disk + custom)
├── ml_service/ # FastAPI ML service (optional)
│ ├── main.py # /train, /predict, /health
│ └── ...
├── data/ # Input data (spot-price, total-load, generation, flows, weather)
├── models/ # Saved models (when using ML API)
├── docs/
│ └── RUNNING.md # Detailed run instructions
└── requirements.txt
For AU Hack 2026 / InCommodities case use.



