Training and demo data
Much of what you see is mock or synthetic (sample prices, simulated imbalance, invented “actual” output). The goal is to rehearse workflows—forecasting, nomination, exposure—before you plug in real market feeds, SCADA, and TSO systems. Treat numbers as illustrations, not settlement or operational truth.
ALPEX day-ahead on the desk uses the live portal results once they are in the database (after the daily scrape, around 13:45 local). Before that time, the chart uses a hybrid mock curve so the screen still works; after scrape, ALPEX is the source of truth for that series.
Trading desk (home)
- Multi-market day-ahead chart — Shows hourly shapes across connected markets (e.g. ALPEX, HUPX) plus ML and persistence-style forecasts. Reason: traders need one place to compare where power is cheap or expensive and how the model sees the day.
- Forecast mode (Settings) — You can drive the chart with ensemble, XGBoost-only, or Random Forest-only. Reason: ensemble reduces the risk that one model has a bad day; single-model modes help you compare behaviour.
- Fleet summary cards — Current price slot, total fleet output, simple imbalance risk score from price volatility. Reason: quick situational awareness without opening other tools.
- Price shape — Compact view of the day-ahead curve. Reason: fast visual read of ramps and peaks.
- Data status — A compact indicator shows whether key feeds (weather, ALPEX job, OST-style paths, etc.) look OK or failed. Reason: you see at a glance if something broke without opening Settings; details and refresh live there.
- Regional curves and spreads — When you have a full day (24 hourly points) for HUPX, HENEX, or IPEX in the database (via CSV import in Settings), those series can appear on the chart. A row can show ALPEX vs HENEX / ALPEX vs IPEX spread proxies when data allows. Reason: compare neighbouring markets without leaving the desk.
- Export forecast (CSV) — Download the brain/ML forecast series as CSV for spreadsheets or archiving. Reason: handoff outside the browser.
Market Intelligence tab
Desk-oriented views built around OST context (grid totals) and helper tools (e.g. bidding hints). It also includes an imbalance price simulation so you can learn the workflow before a real OST imbalance price feed is connected. Reason: imbalance prices drive real money when you are long or short against nomination; practising with a safe synthetic feed lets you wire UI and logic before production APIs.
Portfolio Management (new umbrella)
Portfolio Management is now the main place for BRP operations. It lets you model a real portfolio with:
- BRP (top level)
- Balancing Groups under that BRP
- Participants (consumer / prosumer / trader) under a balancing group, with nominations and actuals
At the top of the page there is a BRP selector (and optional Balancing Group selector). When you select a BRP, the Overview, Nominations & Imbalances, and Demand Response views are scoped to that BRP.
Overview
Shows a portfolio table and a net position gauge for the selected scope. The gauge uses: Total Actual − Total Nominated.
Management
Create and manage BRPs, Balancing Groups, Participants, and assets. This consolidates the “hardware” (assets) and “contracts” (participants) in one place.
Nominations & Imbalances
This is where the pro-forma nomination and imbalance monitoring live now. The goal is to see nominations and risk in the same umbrella as the BRP/portfolio model.
Demand Response (DR Execution)
Shows an IntradayAdvisor-style signal and lets you trigger a DR Event. This logs an event in the database (first version: status only) so traders can track what they executed and when.
The sections below still explain the pro-forma and imbalance monitor concepts; the difference is they are accessed from Portfolio Management rather than being their own top-level tabs.
Pro-forma nomination builds a 24-hour table that combines your AI/desk forecast with registered plant capacity (assets flagged for OST nomination) through an optimiser. You get suggested net export and technology splits (e.g. hydro, solar, BESS). Reason: nominations to the system operator must be coherent with both expected prices and physical limits; this screen is a repeatable draft you can review before any real submission.
Save for Imbalance Monitor stores that 24h schedule in this browser only. Reason: links the nomination workflow to the exposure view without requiring a full database workflow in the first iteration.
Export BRP nomination opens a simple OST-style table: each hour, the total scheduled net export for all plants flagged “include in OST nomination” (the same aggregate as the pro-forma “Nom. net” column), plus the EIC of the Lead BRP taken from Settings (repeated on every row for messaging templates). Total MW is the hourly average export power (for a one-hour slot, MWh in the hour matches average MW). You can download a CSV for the desk. Reason: gives a ready-made handoff toward real OST submission formats while staying tied to your registered Lead BRP and fleet flag.
Export full pro-forma (CSV) downloads the whole optimisation table (all columns you see on screen) for the selected day. Import CSV lets you upload a compatible file to restore or replace that table in the UI workflow. Reason: backup, desk handoff, and what-if edits outside the app.
Imbalance monitor (now under Portfolio Management)
Compares your saved nomination to estimated actual output (from telemetry when you use POST /telemetry/ingest, otherwise a desk mock) and imbalance-style reference prices, then shows per-hour exposure, forecast-vs-realisation visuals, and a spot optimiser. See Operational Optimization & BRP Management below for detail. Reason: any gap between nomination and delivery is settled at imbalance prices; this tab rehearses that logic before you rely on production feeds and official tariffs.
- Choose a balancing group first (from assets in Settings).
- Portfolio — Off (selected plant only) — Pick one plant in that group. The saved total nomination is split by capacity; you see imbalance and risk for that plant’s share only, with an hourly exposure chart and detail table. Reason: see which unit is drifting before looking at the group net.
- Portfolio — On (group aggregate) — Aggregated net imbalance for the whole balancing group (same split + portfolio API). Chart compares net group exposure to gross per-member exposure. A compact Top contributors table flags the worst plants by gross imbalance proxy; the full member table sits below. Reason: BRP-level netting and quick identification of who is costing the group under the desk mock.
Operational Optimization & BRP Management
This block ties together real-time production ingestion, imbalance visuals, intraday vs OST-style economics, balancing-group netting, and actionable desk hints. Numbers remain desk models until you connect official OST/ALPEX prices—use them as a structured checklist, not a settlement statement.
Data ingestion (production actuals)
Hourly net export (MWh) per plant is stored with POST /telemetry/ingest. Send a JSON body with a readings array: each item needs asset_id (UUID of the plant), delivery_hour_start (UTC start of that delivery hour, aligned with your saved nomination window), and net_export_mwh (positive = net export). The API upserts: the same asset + hour overwrites the previous reading. Traders and platform admins only when RBAC is enabled. The Imbalance monitor reads points back via GET /telemetry/actuals (query: asset_id, delivery_window_start) and merges missing hours with the desk synthetic curve so the screen always shows a full 24h row.
Imbalance monitoring — Forecast vs. realisation
The chart plots nomination vs realised (or estimated) output per hour. The shaded band between the two lines encodes financial risk direction at a glance: are you short or long against what you promised the system operator?
Section 1 — The Imbalance Shield (visual guide)
- Blue line — Pf (forecast / nomination): the schedule you saved from the pro-forma flow—the legal or operational nomination you compare against (OST-facing intent on the desk).
- Green line — Pr (realisation): live or best-available telemetry when ingested; otherwise the desk trend that stands in for meters.
- Colour code (band between curves)
- Red band — Under-production (shortfall): Pr < Pf. You delivered less than nominated; you may face buy-back / shortage balancing at stressed prices unless you hedge elsewhere.
- Green band — Over-production (excess): Pr > Pf. You produced more than nominated; settlement may value that energy at down-regulation or discount style levels vs. what you could have earned intraday.
Right axis: a mock intraday curve and the hourly balancing reference used elsewhere on the tab—placeholders until ALPEX intraday and official OST tariffs are wired in.
Section 2 — The Spot Market Optimizer (strategic guide)
The Spot Market Optimizer table is a decision co-pilot: for each hour it compares a desk proxy for OST-style imbalance cost with a mock ALPEX intraday price, then estimates whether trading the gap on the intraday screen could be cheaper than riding the imbalance settlement (or the reverse when you are long).
Incentive add-on (€/MWh) — a field you can edit above the table (default 5 €/MWh). Real Albanian / OST rules bundle balancing energy with add-ons (incentives, coefficients, caps). The product does not hard-code the official rulebook: you move this number when regulations or tariff sheets change so the effective shortage price stays in line with your internal reading of the latest OST documentation.
For each hour, define imbalance volume I = Pr − Pf (MWh). The desk uses:
- Short (I < 0): you need energy. Penalty-side marginal is modelled as balancing reference + incentive (€/MWh). If the mock intraday buy is cheaper than that, the row recommends BUY and shows potential savings as the euro gap on the missing volume—the classic hedge idea:
Savings (short, desk) ≈ |I| × (penalty − intraday)
where “penalty” = reference + incentive when intraday < penalty
- Long (I > 0): you have surplus. A down-regulation proxy (desk: fraction of the hourly reference) stands in for what the TSO might pay or charge for absorbed energy. If intraday is above that proxy, the row recommends SELL and shows savings as I × (intraday − down-regulation) when that difference is positive.
- If neither condition holds, the action is HOLD (savings shown as zero for that hour).
The footer sums potential savings over 24h—useful for prioritising hours, not as a guaranteed P&L.
Section 3 — Portfolio aggregation (the “alpha” guide)
Turn Portfolio — On (group aggregate) to work at balancing-group level. The system sums each plant’s nominated and actual curves (after capacity-weighted split of the saved fleet nomination), then computes a net gap per hour. That is portfolio netting: opposite errors across assets cancel before you think about imbalance charges—e.g. solar below plan and hydro above plan in the same hour.
Example. In one hour, solar is −10 MWh vs its nominated share (short) and hydro is +8 MWh (long). At the group level the net imbalance is only −2 MWh — you pay or hedge roughly two megawatt-hours of net exposure, not eighteen. KPIs such as internal penalty avoided and cumulative net gap make that netting explicit on the desk.
Actionable alerts — BUY / SELL / HOLD as co-pilot
The optimiser shows a BUY, SELL, or HOLD label per hour. These are not exchange orders: the buttons are disabled and serve as a trading co-pilot—a consistent rule applied to the same inputs you see in the chart. Use them to brief the desk (“review hours 14–17 for intraday bids”), then confirm prices, volumes, and credit in your real execution stack. When rules or fees change, adjust the incentive and eventually replace mock intraday/down-reg curves with live data so the co-pilot stays trustworthy.
Settings
The page is organised with a sidebar and categories (e.g. weather, markets, ALPEX vs other markets, TSO / ENTSO-E vs OST-style feeds, forecast/ML, integrations) so you can jump to the area you need. Reason: many toggles and keys in one place without one endless list.
- Assets / plants — Name, technology (type), capacity (MW), optional region and notes, EIC code for market messaging, hydro/BESS parameters where relevant, whether the unit is included in the OST nomination portfolio, a balancing group label (e.g.
Group_A) for roll-ups, and Lead BRP (one lead per group is enforced when a group id is set). The API can list assets withGET /assets?balancing_group=…for net-position style queries. Reason: ties physical units to OST/export messaging, BRP structure, and downstream aggregation services. - Forecast model choice — Stored in the browser; affects the trading chart and flows that read the same mode. Reason: lets you align the visible forecast with the strategy you are testing.
- Integrations & password — Encrypted API fields and session login when enabled on the server. Reason: secrets stay off the frontend and are protected behind your configured backend password.
- Data sources status — Table of feeds (ALPEX scrape, weather file paths, OST-related paths, etc.) with last success or error text. Use Refresh ALPEX to trigger a scrape on demand (subject to backend scheduling and portal availability). Reason: diagnose “why is my chart mock?” or “why did weather fail?” in one place.
- Other markets — CSV import — Upload day-ahead hourly curves for HUPX, HENEX, or IPEX. The file should list 24 hours for the target day with clear date/hour and price columns (the API validates shape; see
POST /market-data/import-csv?market=…in/docs). Reason: bring regional DA into the desk and spreads without a live vendor feed in demo.
Backend (API)
A FastAPI service exposes market-style data, chart building, ML forecast, dispatch optimisation, asset CRUD (with balancing-group filters), analytics, nomination pro-forma, imbalance exposure, portfolio / balancing-group aggregation (POST /portfolio/balancing-group/aggregate— net nomination, net actuals, net gap, and a simple internal “penalty avoided” netting proxy), production telemetry (POST /telemetry/ingest, GET /telemetry/actuals), weather samples, and settings endpoints.
ALPEX portal results cache — a background job uses a real browser (Playwright/Chromium) to scrape the dynamic table at 13:45 CET/CEST every day (after day-ahead results are typically published). It upserts MTU, AL MCP, KS MCP, and AL Volume into the database. The API endpoint GET /market-data/alpex/results reads from the database only (not the website), so the UI is instant. Reason: protects the app from portal slowness/layout changes during trading hours and avoids repeatedly scraping the public site.
Trading chart payload (GET /market-data) serves ALPEX day-ahead from the database when available; otherwise it falls back to the hybrid mock until results exist. ML training for the brain forecast prefers the ALPEX_AL_MCP series when history is present. Reason: one coherent “desk truth” for ALPEX and forecasts aligned to the same price definition where possible.
Operational visibility: GET /status/data reports health of configured data paths and jobs; POST /refresh/alpex requests an on-demand ALPEX scrape. Exports: GET /export/nomination/pro-forma.csv and GET /export/forecast/brain.csv back the desk CSV downloads. Reason: automation-friendly URLs and the same data the UI uses.
Interactive documentation is at /docs when the API is running. Reason: the UI stays thin; heavy logic and future real integrations live in one place the whole product can share.
Docker & dev
Compose runs database, API, and Next.js. The frontend container uses a dedicated volume for the .next build cache so Windows folders and Linux chunks do not clash. Reason: avoids broken “missing chunk” errors when the app is edited from the host while running in a container.
If you change backend dependencies (for example requirements.txt), rebuild the API image (docker compose build or up --build) so uploads and new packages work. Reason: the running container only sees libraries baked into its image.
Suggested workflow
- Define or update plants under Settings (capacity, type, EIC, balancing group, Lead BRP where relevant).
- Choose forecast mode and confirm the desk chart looks reasonable.
- In Settings, check Data sources status; use Refresh ALPEX if you need today's results sooner than the scheduled job (when the portal allows).
- Optional: import HUPX/HENEX/IPEX CSV under other markets if you want those curves and spreads on the desk.
- Open Pro-forma nomination, build the 24h table, review numbers; use Export BRP nomination or Export full pro-forma for CSV; use Import CSV if you are restoring a saved table.
- Save the schedule for the monitor. Optionally push hourly actuals with
POST /telemetry/ingest(see User manual → Operational Optimization). Then open Imbalance monitor — pick a balancing group, toggle Portfolio off (one plant) vs on (group aggregate) to compare unit vs BRP net, and read the forecast vs realisation chart and Spot Market Optimizer table. - When you move to production, replace mocks with live feeds and validate every number externally.