Methodology and sources
This page describes the calculation behind the Tarnița-Lăpuștești analysis precisely enough for a quantitative reader to reproduce it conceptually. Every formula carries units; there are no unexplained magic constants. Annual outputs, representative days, assumptions and the provenance manifest download as JSON/CSV from the data catalog.
1. Data sources
The market-price provenance chain has three links, honestly declared:
- Primary market: OPCOM PZU (Romania's day-ahead market), coupled via SDAC. The RO bidding-zone clearing price published on the ENTSO-E Transparency Platform is the official coupled price (= the OPCOM PZU price).
- Access mirror: the Fraunhofer ISE energy-charts interface (api.energy-charts.info), which republishes ENTSO-E Transparency data at native market-time-unit resolution. Used because it offers reproducible keyless HTTPS access.
- Validation: annual arithmetic means are checked against official OPCOM annual-report averages (tolerance 0.15 €/MWh). The build fails if the anchors do not reproduce. The table below is filled from the shipped manifest:
| Year | Official OPCOM mean (€/MWh) | Processed mean (€/MWh) | Difference | Verdict |
|---|---|---|---|---|
| Loading from manifest… | ||||
Other sources, in hierarchy order: the CNSP 2019 foundation study / embedded ISPH material (historical engineering parameters); Hidroelectrica/BVB regulatory disclosures and EDF announcements (project status); Transelectrica (installed BESS capacity); the 2019 SEA (Natura 2000, historical footprint); the NREL ATB 2024 battery framework (efficiency, life, O&M — no LCOS attribution); the WWF Romania 2026 study as a modern secondary technical source.
2. Time resolution
The model preserves the market's historical Market Time Unit: hourly until delivery day 30 September 2025, inclusive; quarter-hourly from delivery day 1 October 2025 (the SDAC 15-minute MTU go-live). No quarter-hourly data is fabricated for earlier years. Automated TEST 3 rejects any 15-minute interval before 1 October 2025.
3. Timezone / DST
All intervals are dated in Europe/Bucharest (market time). Daylight-saving transition days are never normalised:
- pre-15-minute: ordinary day 24 intervals; spring 23; autumn 25;
- post-15-minute: ordinary day 96 intervals; spring 92; autumn 100.
TEST 4 verifies every 2019–2026 transition day (e.g. 2024-03-31 → 23; 2024-10-27 → 25; 2025-10-26 → 100; 2026-03-29 → 92).
4. Price units
All prices are in EUR/MWh, DAM clearing prices. Energy in MWh (or GWh/TWh where stated), power in MW, volumes in m³, flows in m³/s.
5. Storage state definition
For the public market model we use an output-equivalent stored-energy state:
SoC[t] = MWh of electricity subsequently deliverable to the grid from the current stored-water state, under the model's simplified assumptions.
with 0 ≤ SoC ≤ 13,100 MWh, 0 ≤ Ppump ≤ 1,000 MW, 0 ≤ Pgen ≤ 1,000 MW, and Ppump and Pgen never simultaneously positive in the same interval (verified: TEST 7).
6. RTE convention
Assigning the full round-trip loss to the charging leg is a stated modelling convention, preferable to inventing a separate pump/turbine efficiency pair for which the documentation offers no robust values. Three selectable cases:
- 78.4% — documented legacy-design ratio (1,649.46 / 2,103.33 GWh, CNSP 2019 / ISPH);
- 76.2% — documented alternative (WWF 2026 scenario);
- 72% — conservative modelling stress (a scenario assumption, not Tarnița's declared efficiency).
Break-even equation: discharge price [EUR/MWh] ≥ purchase price / RTE. TEST 5 verifies: 100 MWh pumped at zero price with RTE 78.4% yields exactly 78.4 MWh deliverable — no integer rounding turns it into 50 or 100 MWh.
7. Power limits
Documented configuration: four 250 MW reversible units. The main model dispatches in 250 MW blocks (0 / 250 / 500 / 750 / 1,000 MW), separately for pumping and generation — transparent and consistent with unit granularity. Pumping power is an aggregate 1,000 MW electrical assumption (documented anchor: max. 258 MW absorbed per unit, an informative historical value, not guaranteed). The model abstracts from head-dependent pump/turbine curves.
8. Storage-capacity derivation
The model's energy ceiling is derived from useful volume, maximum flow and project power:
A simplified model parameter, marked as such — not an official electrical rating. The corresponding hydraulic duration (13.10 h at maximum documented flow) is physical intuition, not a certified storage duration.
9. Dispatch optimisation
One continuous chronological simulation across the full 2019–2026 horizon (SoC carried across days/weeks/years; no isolated daily cycles with an empty lake every morning). Optimiser: exact backward dynamic programming on a 25 MWh SoC grid with linear interpolation of the value function and an exact floating-point rollout — no integer state rounding (the v1.0 bug class is structurally absent). Ties break deterministically (idle, then lower power, generation before pumping at equal power). The result is the perfect-foresight upper bound: the maximum DAM arbitrage available with perfect hindsight under the stated constraints.
Game days use the same model (same accounting, same selected RTE, same ceiling), optimised standalone with a neutral 0 → ≤75 MWh boundary — required for a playable day. The published schedule's realised earnings are the reported value; its agreement with the interpolated grid-DP reference value V₀(0) — an independent cross-check, not a proven bound — is verified automatically (0.1% relative tolerance; observed below 0.02% on all three cases).
10. Initial/final SoC condition
Initial SoC = 0 (no free energy). Final SoC ≤ 75 MWh, unvalued: leftover water earns no value credit (a pure plant-side loss, ≤0.004% of annual throughput). TEST 8 verifies: margin = revenue − cost exactly, with no credit term; on perfectly flat prices the optimum is exact idleness (margin 0).
11. Annual aggregation
- mean price = duration-weighted mean over priced intervals;
- mean daily spread = mean over delivery days of (daily max − daily min);
- EFC (equivalent full cycles) = discharged energy / 13,100 MWh;
- utilisation [%] = discharged / (1,000 MW × period hours) × 100;
- revenue concentration: priced intervals ranked descending by per-interval generation revenue; share of annual generation revenue earned in the top 1/5/10% (bounded in [K%, 100%]);
- generation/pumping episodes = maximal contiguous blocks of active intervals.
Multi-year averages use full years 2019–2025 only; 2026 YTD is shown separately, never averaged.
12. Capture haircut
Illustrative slider 50–100%, default 100%. Not a forecast-accuracy estimate: it asks how the result changes if the operator captures only X% of the ex-post optimal value.
13. Spread-compression sensitivity
Slider 0–40%, default 0%. A scenario sensitivity, not an estimate of Tarnița's equilibrium price impact: market re-clearing would require supply–demand and network/system modelling. Combined: margin × capture × (1 − compression).
14. Capital-recovery formula
A simple annual capital-recovery test — not a lender-grade bankability model. See section 15 for what is missing.
15. Excluded revenues
The model quantifies nothing from: intraday optimisation; balancing-market revenue; reserve products; ancillary/system services; availability/capacity-type contracts; bilateral/contractual arrangements. That is why the computed difference is called the “residual annual revenue requirement in this model”, never automatically “required subsidy”.
16. BESS comparison method
The LCOS frontier compares, at each (duration h, cycles/year c), the modelled LCOS of an LFP battery with pumped hydro's, on a consistent boundary:
- same currency (EUR), same discount rate (the page's WACC slider, both sides), same charging-energy price (simulated mean pumping price, selected RTE case);
- battery: 85% AC–AC RTE, life min(15 years, 4000/cycles-per-year), fixed O&M 2.5% of CAPEX including augmentation (NREL ATB 2024 framework); costs follow the illustrative path in assumptions.json (anchor years 2026/2030/2035/2040/2050, linear interpolation, every year 2026–2050 resolved explicitly);
- hydro: page-slider CAPEX and OPEX, 60-year financial life, selected-case RTE, energy throughput c × 13.1 h × 1,000 MW;
- Tarnița marker: (13.1 derived hours, simulated mean EFC 2019–2025, selected case).
NREL ATB explicitly states it does not compute LCOS for batteries; the LCOS here is computed inside this model and attributed to neither NREL nor BNEF. “Lower modelled LCOS” is not a complete technology ranking: LCOS does not value every system service.
17. Uncertainty/sensitivity method
Deterministic first: the “What would change the conclusion?” section computes exact thresholds from the model's own maths (maximum compatible CAPEX, required top-up revenue, break-even WACC by bisection, break-even capture). Uncertainty laboratory: 1,000 Monte Carlo draws from uniform distributions with fully on-screen ranges (CAPEX, WACC, build duration, annual margin, OPEX); CAPEX spread over construction, 40 operating years; deterministic seed with an explicit resample option. The reported result is the “share of draws with NPV > 0 under the selected distributions” — never an estimated real-world probability.
18. Known limitations
- Perfect foresight is an upper bound, not an operating forecast; achievable capture is unknown and parameterised as a sensitivity.
- No market re-clearing: at 1,000 MW the plant would move its own buy/sell prices; compression is only a sensitivity.
- No hydraulic curves (head, per-unit efficiencies), no start/stop losses, no outages or planned maintenance.
- No transmission network, no congestion, no geotechnical risk, no project EIA.
- The capital test is not a financing structure: no drawdown schedule, interest during construction, debt/equity, taxes, refinancing, reserves or overruns.
- Historical engineering parameters may not match the final EDF/Hidroelectrica design.
19. Data cut-off
Coverage: 2019-01-01 → … (last complete delivery day). 2026 is YTD (259 days) and is conspicuously marked wherever it appears. Marked source gaps (no interpolation; the plant holds forced idle with SoC carried):
- Loading from manifest…
20. Model version
Model v1.1.0 — methodology & data integrity update (17 September 2026). Full history: the “What changed?” button in the main page footer.
21. Reproduction files
- scripts/fetch_opcom.mjs — reproducible interval-series download pathway;
- scripts/process_opcom.mjs — processing, Europe/Bucharest dating, OPCOM anchors;
- scripts/model.mjs — storage physics + optimiser (dynamic programming);
- scripts/backtest.mjs — continuous chronological run over 3 RTE cases;
- scripts/select_days.mjs — deterministic selection of the 4 real days;
- scripts/write_public.mjs — writing the shipped outputs;
- scripts/tests.mjs — hard tests TEST 1–13 (the build fails if they fail);
- public/data/{backtest-annual,representative-days,assumptions,data-manifest,methodology,hero}.json + annual CSV.
The full interval series is not redistributed under the mirror's licence; anyone can rebuild it with the scripts above and verify the section-1 anchors.