mariuscomper.uk
Methodology · Model v1.1.0

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:

  1. 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).
  2. 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.
  3. 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:
YearOfficial OPCOM mean (€/MWh)Processed mean (€/MWh)DifferenceVerdict
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:

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.

SoC[t+1] [MWh] = SoC[t] + Ppump[t] [MW] × dt [h] × RTE [–] − Pgen[t] [MW] × dt [h]
Revenue[t] [EUR] = Pgen × dt × price [EUR/MWh]   ·   Cost[t] [EUR] = Ppump × dt × price

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:

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:

Emax [MWh] = 10,000,000 [m³] / 212 [m³/s] / 3,600 [s/h] × 1,000 [MW] = 13,102.7 → 13,100 MWh

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

Multi-year averages use full years 2019–2025 only; 2026 YTD is shown separately, never averaged.

12. Capture haircut

scenario margin [EUR] = ex-post optimal margin × capture [%] / 100

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

scenario margin [EUR] = margin × (1 − compression [%] / 100)

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

Annuity [EUR/yr] = CAPEX [EUR] × r(1+r)^n / ((1+r)^n − 1),   r = WACC [–], n = horizon [yr]
Residual annual requirement [EUR/yr] = annuity + OPEX − modelled DAM revenue (− assumed top-up revenue)

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:

LCOS [EUR/MWh] = (annualised capital [EUR/yr] + OPEX [EUR/yr]) / discharged energy [MWh/yr] + charging price [EUR/MWh] / RTE [–]

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

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):

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

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.