System cost decomposition
Spain's monthly final electricity price split into its 10 official components: market energy, ancillary services, regulated tariffs, taxes, and surplus/deficit lines. Sourced directly from ESIOS (REE) — the same numbers you see on a PVPC bill.
Final cost of electricity (3 buckets, monthly)
The headline view: monthly cost of electricity in Spain split into Wholesale (day-ahead + intraday), Technical Constraints (RRTT Phase I + RT), and Ancillary Services & others (secondary band, imbalances, capacity payment, P.O.14.6). Excludes structurally-zero post-reform components (Phase II, UPG failure, additional reserve, interruptibility) and the retired RD-L 10/2022 gas-cap (queryable individually for 2022-23 historical analysis). Sums match the official ESIOS reports within ±1 EUR/MWh.
Excel formulas — copy-paste ready
=ED.RANGE("system_cost_dayahead","2024-01-01","2025-12-31",3,,,1)+ED.RANGE("system_cost_intraday","2024-01-01","2025-12-31",3,,,1)— Wholesale bucket (day-ahead + intraday). Last arg noDate=1 → pure values, sumable arrays.=ED.RANGE("system_cost_rrtt_phase1","2024-01-01","2025-12-31",3,,,1)+ED.RANGE("system_cost_rrtt_rt","2024-01-01","2025-12-31",3,,,1)— Technical Constraints bucket (Phase I + RT). Phase II is structurally 0 post-reform — REE merged it into RT.=ED.RANGE("system_cost_band_secondary","2024-01-01","2025-12-31",3,,,1)+ED.RANGE("system_cost_imbalance_measured","2024-01-01","2025-12-31",3,,,1)+ED.RANGE("system_cost_imbalance_balance","2024-01-01","2025-12-31",3,,,1)+ED.RANGE("system_cost_capacity_payment","2024-01-01","2025-12-31",3,,,1)+ED.RANGE("system_cost_po146","2024-01-01","2025-12-31",3,,,1)— Ancillary Services & others bucket (5 active components)=ED.RANGE("system_cost_dayahead","2024-01-01","2025-12-31",3)— Dates column for labelling rows: =ED.RANGE(metric, start, end, 3) returns [date, value]PVPC residential bill by component (last 5 years)
Stacked monthly average. Each layer is one of the 10 ESIOS components that sum to the published PVPC bill price. Pre-June 2021 uses tariff 2.0.A; post-June 2021 uses 2.0TD — the metrics stitch the two cleanly so you see one continuous series per item.
=SUM(ED.RANGE("pvpc_dayahead_intraday",...) ; ED.RANGE("pvpc_ancillary",...) ; ...)Energy market
The variable, market-driven portion of the bill. Day-ahead + intraday reflects OMIE auction prices; ancillary covers RRTT, secondary/tertiary band, and imbalances passed through to the consumer.
Day-ahead + intraday
=ED.RANGE("pvpc_dayahead_intraday", "2020-01-01",, 3)— Monthly EUR/MWhAncillary services
=ED.RANGE("pvpc_ancillary", "2020-01-01",, 3)— Monthly EUR/MWhRegulated tariffs and fees
Set by CNMC (regulator) and reviewed periodically. Tolls + charges is the dominant overhead (~40 EUR/MWh pre-2021, ~25 post — the 2021 reform shifted some to power-term billing).
Tolls + system charges
=ED.RANGE("pvpc_tolls_charges", "2020-01-01",, 3)— Monthly EUR/MWhCapacity payment
=ED.RANGE("pvpc_capacity_payment", "2020-01-01",, 3)— Monthly EUR/MWhCommercialization
=ED.RANGE("pvpc_commercialization", "2020-01-01",, 3)— Monthly EUR/MWhOperator fees (REE + OMIE)
Combined < 1 EUR/MWh — formula sums both:
=ED.RANGE("pvpc_os_fee", "2020-01-01",, 3) + ED.RANGE("pvpc_om_fee", "2020-01-01",, 3)— REE + OMIE per MWhAdjustments (post-2021)
Created by recent regulation: the renewable auction line settles FER/REER auction surpluses, and MACP(since June 2022) settles the Iberian gas-cap mechanism ("tope al gas").
Renewable auction (since 2021-06)
=ED.RANGE("pvpc_renewable_auction", "2021-06-01",, 3)— Monthly EUR/MWhMACP gas-cap (since 2022-06)
=ED.RANGE("pvpc_macp", "2022-06-01",, 3)— Monthly EUR/MWhLegacy aggregated view (REE pre-calculated)
The three monthly aggregates REE used to publish before the 2021 reform broke the bill into 10 items. Kept here for backward compatibility with older analyses; for new work use the itemised series above.
Technical Constraints (RRTT)
=ED.RANGE("component_rrtt_monthly", "2020-01-01",, 2)Total ancillary (RRTT + balancing)
=ED.RANGE("component_ancillary_monthly", "2020-01-01",, 2)Market component (10211)
=ED.RANGE("component_final_price_monthly", "2020-01-01",, 2)⚠️ Note: ESIOS calls this "final" but it's really the market sub-component. For the actual consumer-bill price, sum the 10 itemised components above.
Calculated metrics
=ED.GET("rrtt_cost_mwh", "2025-07-01")— RRTT cost per MWh demand=ED.GET("balancing_cost_mwh", "2025-07-01")— Balancing cost per MWh=ED.GET("total_system_cost", "2025-07-01")— Total system cost=ED.GET("clean_spark_spread", "2025-07-01")— Clean spark spread (CCGT margin)=ED.GET("clean_dark_spread", "2025-07-01")— Clean dark spread (coal margin)