ED.PCT.AT.PRICE
Share of a volume metric whose hours fall on one side of a price threshold.
Signature
ED.PCT.AT.PRICE(volume, threshold, [op], [price], [start], [end], [zone], [agg], [unit], [headers])Description
How much of a volume metric (generation, demand, cross-border flow, programmed) was produced/consumed in hours where a price series satisfied op threshold. Generalises questions like "how much solar PV happened at ≤ 0 EUR/MWh?" or "what fraction of demand was served below 10 EUR/MWh?".
The function joins the volume and the price on the same civil hour, evaluates price <op> threshold per hour, and reduces over the requested window. Result is a share of the total volume by default (unit="pct"), the absolute energy below the threshold (unit="mwh"), or the count of qualifying hours (unit="hours").
**Realized vs ex-ante**: pass volume="gen_*" for the realized (post-curtailment) view, or volume="program_pbf_*" for the ex-ante OMIE schedule view (matches ED.CAPTURE method=1). program_p48_* gives the post-RRTT view (after technical redispatch).
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| volume* | string | — | Volume metric. Accepted families: gen_* (e.g. gen_solar_pv, gen_wind, gen_total), demand_*, xborder_*, program_pbf_*, program_p48_*. Use program_pbf_* for the ex-ante OMIE schedule view (matches ED.CAPTURE method=1). |
| threshold* | number | — | Price threshold in EUR/MWh. Negative values are allowed (e.g. -10 for negative-price hours). |
| op | "lte" | "lt" | "gte" | "gt" | "lte" | Comparison: lte (default, ≤), lt (<), gte (≥), gt (>). Hours where the price exactly equals the threshold are included with lte/gte. |
| price | string | "dayahead" | Price series to compare against. dayahead (default), pvpc, pvpc_final, intraday_s1_price / intraday_s2_price / intraday_s3_price, imbalance_price_up, imbalance_price_down. |
| start | date | — | Start. Defaults: omit end for today (Madrid, with a small overnight cutoff), omit start for 30 days before end. |
| end | date | — | End. Omit for today. |
| zone | "ES" | "PT" | "ES" | MIBEL zone. |
| agg | 2-7 | string | 7 (total) | Aggregation is controlled by agg: 0=native, 5min/10min/15min, 1=hourly, 2=daily (default), 3=monthly, 4=quarterly, 5=semiannual, 6=annual, 7=total. Default is total (single number for the window); pass 3 for a monthly spill, etc. |
| unit | "pct" | "mwh" | "hours" | "pct" | pct (default) returns the share of total volume that satisfied the threshold (%). mwh returns the absolute energy below/above the threshold per bucket. hours returns the count of qualifying civil hours in each bucket. |
| headers | 0 | 1 | 0 | Set 1 for header row (only applies when agg returns more than one row). |
* Required.
Returns
Number when agg="total" (default), otherwise a spill array — [period, value] rows. Units: % / MWh / hours depending on unit.
Examples
=ED.PCT.AT.PRICE("gen_solar_pv", 0, "lte", "dayahead", "2026-01-01", "2026-04-30")— % solar PV at price ≤ 0 EUR/MWh — realized (post-curtailment)=ED.PCT.AT.PRICE("program_pbf_solar_pv", 0, "lte", "dayahead", "2026-01-01", "2026-04-30")— Same question in the OMIE PBF (ex-ante) view — equivalent to ED.CAPTURE method=1=ED.PCT.AT.PRICE("gen_solar_pv", 5, "lte", "dayahead", "2026-01-01", "2026-04-30")— % solar PV at price ≤ 5 EUR/MWh (~65%)=ED.PCT.AT.PRICE("gen_solar_pv", 0, "lte", "dayahead", "2026-01-01", "2026-04-30", "ES", 7, "mwh")— Total solar PV MWh at price ≤ 0 EUR/MWh=ED.PCT.AT.PRICE("gen_solar_pv", 0, "lte", "dayahead", "2026-01-01", "2026-04-30", "ES", 3, "hours", 1)— Hours per month where dayahead ≤ 0 EUR/MWh, with headers=ED.PCT.AT.PRICE("demand_real", 100, "gte", "dayahead", "2025-01-01", "2025-12-31")— % real demand served at price ≥ 100 EUR/MWh — peak-price exposureNotes
- **Realized (
gen_*) vs ex-ante (program_pbf_*) vs post-RRTT (program_p48_*)**: each volume family gives a different denominator.gen_*reflects what actually flowed (already net of technical curtailment).program_pbf_*is the OMIE day-ahead schedule (matchesED.CAPTURE method=1).program_p48_*is post-RRTT (after Restricciones Técnicas). - **MW vs MWh aggregation**:
gen_*/demand_*/xborder_*are stored as MW power; the API multiplies by the native sample interval (5-min or 15-min) before summing.program_pbf_*/program_p48_*are stored as MWh per 15-min slot and SUM'd directly. Both code paths ultimately produce hourly MWh consistently —unit="mwh"numbers betweengen_solar_pvandprogram_pbf_solar_pvare comparable in scale (~1-2% difference). - **Threshold operator**:
lte/gteinclude exact equality.lt/gtare strict. For "hours at ≤ 0" uselteandthreshold=0. - **
hoursunit**: counts civil hours (always 60-min buckets) where the price satisfied the operator, regardless of how much volume there was that hour. Useful for documenting market stress separately from production.