This repo stays public and usable; issues are welcome, but responses may be slower while I’m focused on the other projects.
Fetch, tidy, and visualize Nordic (SE3/SE4/FI) imbalance prices & volumes with hour×weekday patterns and simple deviation-risk views.
Why this exists: Imbalance exposure drives intraday/VPP decisions. This repo cleans Nordic imbalance data (demo for now) and gives fast visuals to decide when to rebid vs accept deviation.
Open-source only (from 2025-08-20): New code is authored manually using standard open-source libraries (requests/entsoe-py, lxml, pandas, matplotlib, etc.).
No LLMs at runtime. Seedocs/PROVENANCE.mdfor the history and policy.
No token needed — uses a tiny sample XML in tests/fixtures/.
python src/fetch_a85_entsoe.py --area SE3 --start 2025-01-10 --end 2025-01-11 --out data/SE3_A85_fixture.parquet --use-fixture- Create a local
.env(not committed) withENTSOE_TOKEN=... - Run (UTC, end-exclusive):
python src/fetch_a85_entsoe.py --area SE3 --start 2025-01-10 --end 2025-01-11 --out data/SE3_A85_20250110.parquetNotes:
- Day-Ahead uses Bidding Zone EIC; A85 uses Control Area EIC. IDs live in
src/eic_map.py. - Timestamps are UTC;
--endis exclusive. - On “no data” or any error the CLI writes an empty Parquet with the right columns.
- ✅ DA (A44) via ENTSO-E REST is live → tidy Parquet secrets in (
.env). - 🟡 Imbalance (A85) fetcher is scaffolded; the demo uses converted CSVs for now.
- ➡️ Next: wire A85 XML→Parquet for SE3/SE4, then extend to FI and update the joins/plots.
- ℹ️ Outputs target 15-minute granularity (Nordic ISP), with one-click Windows rebuilds.
data/– tidy Parquet extracts (prices/volumes)src/– small Python CLIs to fetch and plotreports/– PNGs + a tiny Markdown stats filenotebooks/– optional EDA later
python -m venv .venv
call .venv\Scripts\activate
pip install -r requirements.txt
REM DEMO data (synthetic) for SE3, May 2025
python src\fetch_imbalance.py --area SE3 --start 2025-05-01 --end 2025-05-31 --out data\SE3.parquet --demo
REM Heatmaps + quick stats
python src\make_heatmaps.py --input data\SE3.parquet --out reportsOne-click rebuilds (Windows): run run_all_SE3.bat or run_all_SE4.bat to regenerate all charts and stats.
Methods & reproducibility: see METHOD.md for data sources, steps, assumptions, and checks.
Quick links:
SE3 weekly report ·
SE4 weekly report ·
SE3 DA ↔ Imbalance (stats) ·
SE4 − SE3 spread (stats)
See quick stats: reports/SE3/stats.md
Weekly report (one-pager): reports/SE3/weekly_report.md
See quick stats: reports/SE3/da_price_stats.md
See quick stats: reports/SE3/da_vs_imbalance_stats.md
Note: uses demo imbalance parquet (SE3_imbalance_api_demo.parquet) while A85 is empty.
See quick stats: reports/SE3/da_vs_imbalance_api_stats.md
See quick stats: reports/SE4/da_price_stats.md
See quick stats: reports/SE3_SE4/da_spread_stats.md
Top moves (per day): reports/SE3_SE4/spread_monitor.csv · summary
Hourly join parquet: reports/SE3_SE4/da_spread_hourly.parquet.
Weekly report (one-pager): reports/SE4/weekly_report.md
See summary: reports/SE3/rebid_accept_summary.md
- CSV: reports/SE3/ida_prepsheet.csv
- One-pager: reports/SE3/ida_prepsheet.md
- CSV: reports/SE4/ida_prepsheet.csv
- One-pager: reports/SE4/ida_prepsheet.md
What’s inside: per-day DA/Imbalance means & std, correlation, # of big deviation hours (|Imb−DA| > 50 €/MWh), p95 abs spread, max/min spread.
See stats: reports/SE3/battery_stats.md
Assumptions: 10 MWh cap, 5 MW power, 90% round-trip efficiency; simple DA-only rule; no fees.
See stats: reports/SE4/battery_stats.md
Schedule CSVs:
Convert any CSV to this repo’s schema, then build charts.
Note: Change --area to your zone (SE3/SE4/FI) to match your data.
REM 1) Convert CSV -> Parquet
python src\csv_to_parquet.py --csv data\YOUR_FILE.csv --ts-col ts --price-col price_eur_mwh --volume-col imbalance_volume_mwh --area SE3 --out data\SE3_real.parquet
REM 2) Make heatmaps + stats
python src\make_heatmaps.py --input data\SE3_real.parquet --out reports\SE3Expected columns in CSV:
ts— timestamp (with or without timezone)price_eur_mwh— numericimbalance_volume_mwh— numeric (± for direction)
What this does: fetches day-ahead prices for SE3/SE4 straight from ENTSO-E, saves to Parquet, and (optionally) plots a PNG.
1) Token (once)
- In your Transparency Platform account: My Account Settings → Web API Security Token → Generate new token.
- Save locally in
.env(never commit):ENTSOE_TOKEN=YOUR-REAL-TOKEN
2) Fetch & plot (example window)
call .venv\Scripts\activate
python src\fetch_da_entsoe.py --area SE3 --start 2025-05-10 --end 2025-05-13 --out data\DA_SE3_API.parquet
python src\plot_da_api.py --input data\DA_SE3_API.parquet --out reports\SE3\da_price_api.png3) One-click (Windows)
run_all_SE3.bat
run_all_SE4.batDry-run (no token needed) Prints the exact endpoint with your token redacted.
python src\fetch_da_entsoe.py --area SE3 --start 2025-05-10 --end 2025-05-13 --out data\DA_SE3_API.parquet --dry-runPrerequisite: create .env and set ENTSOE_TOKEN=YOUR-REAL-TOKEN. Do not commit .env.
Fetch imbalance prices for SE3 and write a join-compatible parquet:
python src\fetch_imbalance_entsoe.py --area SE3 --start 2025-08-18 --end 2025-08-19 --out data\SE3_imbalance.parquetMake the DA vs Imbalance plot (uses your latest DA parquet):
python src\join_da_imbalance.py --da data\DA_SE3_API_latest.parquet --imb data\SE3_imbalance.parquet --out reports\SE3 --title "SE3 - DA vs Imbalance (API)"Output parquet schema (join-compatible)
index: ts_utc (UTC)
columns: price_eur_mwh, imbalance_volume_mwh
Notes (Imbalance)
- A85 uses the control-area EIC (not the bidding-zone EIC).
- Sweden (SE3 and SE4) control-area EIC:
10YSE-1--------K(Svk). - If ENTSO-E returns "No matching data" for the chosen window, the script still writes a join-compatible empty parquet so the pipeline and plots do not break.
- For SE4, change
--area SE3to--area SE4. --endis exclusive; times are handled in UTC.
Notes (Day-Ahead)
--endis exclusive (e.g., 10..13 = 72 hours).- Times are UTC internally; results are clamped to the area’s local day (Europe/Stockholm).
- Areas supported now: SE3, SE4 (EICs wired in
src/eic_map.py). FI support can be added later.
- Latest: https://github.com/EmotionalTrader/nordic-imbalance-basics/releases
- Older demo tags: v0.5.0-demo · v0.4.0-demo · v0.3.0-demo · v0.2.0-demo · v0.1.0
- Copy
.env.exampleto.envand set your token:ENTSOE_TOKEN=... .envis ignored by git; never commit real tokens.
- Copy
.env.exampleto.envand setENTSOE_TOKEN. - Fetch demo (SE3, 2 days):
python src\fetch_da_entsoe.py --area SE3 --start 2025-08-15 --end 2025-08-17 --out data\DA_SE3_API_demo.parquet- Plot:
python src\plot_da_api.py --input data\DA_SE3_API_demo.parquet --out reports\SE3\da_api_demo.pngOne-click (Windows):
run_all_SE3.bat
run_all_SE4.bat










