Beta — Data under validation. Values may contain errors.
Back to docs

Changelog

Add-in versions and notable platform updates. Older fixes live in the git log.

8.7.2.0

2026-05-20

Added

  • Internal: `vitest` guard test (`src/functions/__tests__/matrix-functions.test.ts`) parses `functions.ts` via the TypeScript compiler API and asserts every `@customfunction` declaring `@dimensionality matrix` in its JSDoc is present in both `matrixFunctions` Sets in `webpack.config.js`. Prevents the recurring bug pattern that produced 8.6.0.0 (`OFFER.CURVE`) and 8.6.0.1 (`DAYAHEAD.RANGE`) hotfixes.

Fixed

  • Matrix dimensionality for **six functions** that were silently mis-registered as scalars in `webpack.config.js`'s `matrixFunctions` set: `ED.UP.SEARCH`, `ED.OWNERS`, `ED.REER.AWARDS`, `ED.OMIE.SEGMENTS`, `ED.GRIDACCESS`, `ED.GRIDACCESS.PORTAL`. Excel may previously have rendered these as `#N/A` or `#VALUE!` instead of spilling the full matrix. Re-side-load the add-in to pick up the fix.
  • Dev/prod drift on the `matrixFunctions` set — `BESS.RANGE`, `UNIT.RANGE`, `UPS`, `CAPACITY.RANGE` were registered for production builds but missing from the dev-server interceptor. Both sets are now identical (24 functions) and guarded by an automated test.

Minor bump 8.7.1.0 → 8.7.2.0 (fix release + new internal CI infra). The six fixed functions all return 2-D ranges (search results, owner registries, REER auction awards, OMIE segments, REE grid-access trajectories) — their backends were correct all along; only the metadata bit was missing. Manifest bump forces Excel to re-pull `functions.json` so the corrected dimensionality activates.

8.7.1.0

2026-05-19

Changed

  • **Breaking** — `ED.OFFER.CURVE(...)` with `agg=1` now returns **24 rows hour-of-day Madrid (00..23)** aggregated across the date range, replacing the previous 'hour timestamp' semantic (8760 rows / year, ~1.4M cells with tech='all' — impractical in Excel). New shape mirrors ED.OFFER.HEATMAP's hour-of-day dimension. ADR-011.
  • `=ED.OFFER.CURVE(;;;1;;1)` (default range + agg=1 + headers) now lands on pre-aggregated table `omie_offer_curve_year_tech_hora` (10,368 rows: 9y × 3 zones × 16 techs × 24h) → <100 ms vs ~8 s live. Live fallback for sub-natural-year boundaries computes hour-of-day on the fly with `EXTRACT(HOUR FROM ts_utc AT TIME ZONE 'Europe/Madrid')`.

Patch bump 8.7.0.0 → 8.7.1.0 forces Excel to re-pull functions.json so the new `agg=1` description appears in IntelliSense. No existing JSDoc example used `agg=1`, so the break is theoretical for callers — but a re-side-load is needed.

8.7.0.0

2026-05-19Latest

Added

  • Pre-aggregated table `omie_offer_curve_year_tech` (432 rows: 9y × 3 zones × 16 techs incl. interconnect; ~150 KB). Endpoint routes to pre-agg when `agg ∈ {6, 7}` AND boundaries align to natural Madrid year; otherwise live SQL. Default call `=ED.OFFER.CURVE()` drops from ~8 s to <200 ms.
  • Aliases `all` / `vre` / `thermal` sum bins across sub-techs in the route layer (bins are additive — unlike F3 percentiles). `n_slots` for these aliases may double-count slots when multiple sub-techs offer in the same slot; documented in `methodology_note`.

Changed

  • **Breaking-ish** — `ED.OFFER.CURVE()` default range when `agg ∈ {6, 7}` (annual / total) is now **last completed natural year (Madrid)**, replacing the previous '12 months rolling from first-day-after-last-published-month'. Explicit `start/end` args still respected. Other agg levels (hourly, daily, monthly, quarterly, semiannual) keep the 12-month rolling default. ADR-009.

Minor bump 8.6.0.x → 8.7.0.0 communicates the default-behavior change. Existing explicit calls (`start=YYYY-01-01, end=YYYY+N-01-01, agg=6`) unchanged in result.

8.6.0.1

2026-05-19

Fixed

  • ED.DAYAHEAD.RANGE matrix dimensionality — versions 8.4.0.0 through 8.6.0.0 shipped with `DAYAHEAD.RANGE` accidentally registered as a scalar (`result: {type: 'number'}`) in `webpack.config.js` `matrixFunctions` set, even though the canonical `OMIE.RANGE` alias was correctly registered as matrix. Excel was returning `#N/A` instead of spilling the price-range matrix. Now correctly registered. Re-side-load the add-in to pick up the fix. (Workaround until re-side-load: use `=ED.OMIE.RANGE(...)` — the deprecated alias delegates to the same backend with the same signature.)

Patch release. Manifest 8.6.0.0 → 8.6.0.1 forces Excel to re-pull functions.json so the corrected dimensionality activates.

8.6.0.0

2026-05-19Latest

Added

  • ED.OFFER.HEATMAP([tech], [year], [zone], [metric], [headers]) — OMIE day-ahead bid-price heatmap as a 24×12 matrix (hours × months) for a single tech / year / zone. Killer Dec 2025 ES sample: **solar h9-12 p50 = -10 €/MWh (floor)**, **solar h20-21 p50 ≈ +280 €/MWh (evening scarcity)**. Closes the ADR-003 OMIE offer-* trio (STRATEGY + CURVE + HEATMAP). Pre-aggregation table `omie_offer_heatmap_year_tech` (8 years × 15 sub-techs × 3 zones × 24h × 12m = 80k rows) refreshed monthly; sub-ms read latency.

Fixed

  • ED.OFFER.CURVE matrix dimensionality — version 8.5.0.0 shipped with `OFFER.CURVE` accidentally registered as a scalar (`result: {type: 'number'}`) in `webpack.config.js` `matrixFunctions` set. Excel was returning only the first cell instead of the full 11-col histogram. Now correctly registered as matrix. Re-side-load the add-in to pick up the fix.

Minor (additive) bump: no existing function signatures change. Manifest 8.5.0.0 → 8.6.0.0 forces Excel to refresh the function set so the new ED.OFFER.HEATMAP appears in IntelliSense and the ED.OFFER.CURVE matrix-spill fix activates.

8.5.0.0

2026-05-18

Added

  • ED.OFFER.CURVE([tech], [start], [end], [agg], [zone], [headers]) — OMIE day-ahead aggregate offer-curve histogram split across 8 price tiers: `<-10`, `-10..0`, `0..5`, `5..20`, `20..50`, `50..100`, `100..180`, `≥180` €/MWh. Reveals 'merit order interna' per tech. Dec 2025 ES sample: **solar 99% in ≤20 €/MWh, gas 79% in >100 €/MWh, wind spread across all bins**. Same tech enum as ED.OFFER.STRATEGY / ED.OMIE.BIDS.

Minor (additive) bump: no existing function signatures change. Manifest 8.4.0.0 → 8.5.0.0 forces Excel to refresh the function set so the new ED.OFFER.CURVE appears in IntelliSense.

8.4.0.0

2026-05-18Latest

Added

  • ED.DAYAHEAD([date], [hour], [quarter], [zone], [tz]) — canonical multi-zone day-ahead spot price function. Replaces ED.OMIE (kept as deprecated alias, no warning, same signature). Now serves 21 bidding zones: 6 pre-existing (ES, PT, FR, DE, BE, NL) + 15 new via ADR-008 — 8 CET (AT, CH, PL, HU, CZ, SK, SI, HR) + 7 Italian (IT_NORD, IT_CNOR, IT_CSUD, IT_SUD, IT_CALA, IT_SARD, IT_SICI).
  • ED.DAYAHEAD.RANGE([start], [end], [agg], [zone], [headers], [noDate], [tz]) — range variant of ED.DAYAHEAD with same multi-zone coverage.
  • 15 EU bidding zones live in production with historical backfill 2014-2024 (1.57M rows ingested 2026-05-18 via ENTSO-E A44, daily-forward updates continue automatically).
  • ENTSO-E parser hardening: `classPos=1` filter ensures deterministic price selection when multiple parallel SDAC curves coexist (Italian cluster scenario).

Changed

  • ED.OMIE / ED.OMIE.RANGE are now documented as deprecated aliases. Calls keep working unchanged — no breakage. Migrate at your own pace to ED.DAYAHEAD / ED.DAYAHEAD.RANGE for clarity (the only difference is the name; zone defaults to ES on both).

Minor bump: zero breaking changes. Manifest 8.3.0.0 → 8.4.0.0 forces Excel to expose the new canonical function in IntelliSense. The non-OMIE zones (FR/DE/BE/NL/AT/CH/PL/HU/CZ/SK/SI/HR/IT_*) require pre-existing backfill — on-demand fetch for historical dates not yet implemented (returns 404 for non-backfilled past dates outside the ingested range; daily-forward always works).

8.3.0.0

2026-05-17

Added

  • ED.OFFER.STRATEGY([tech], [start], [end], [agg], [zone], [headers]) — OMIE day-ahead offer-strategy split by technology across 4 price tiers: `mwh_neg` (<0 €/MWh, must-run/hedge), `mwh_zero` (=0 €/MWh, exact price-taker), `mwh_pos_real` (0..180, competitive bids), `mwh_safety` (≥180, near-cap safety bids). Plus headline `pct_neg` and `pct_safety`. Killer Dec 2025 ES insight: **solar 88% negative, gas/nuclear 30-50% safety**. Same tech enum as ED.OMIE.BIDS (18 values).

Minor (additive) bump: no existing function signatures change. Manifest 8.2.0.0 → 8.3.0.0 forces Excel to refresh the function set so the new ED.OFFER.STRATEGY appears in IntelliSense.

8.2.0.0

2026-05-12

Added

  • ED.OMIE.BIDS([tech], [start], [end], [agg], [zone], [headers]) — raw OMIE day-ahead bidding behavior by technology. Companion to ED.CURTAIL.ECON with NO curtailment claim; surfaces offered + cleared volumes, weighted prices, clearing rate, and slot marginal across the full tech spectrum (renewables + flexible thermal + interconnects). Tech enum open to 18 values: `solar`, `wind`, `vre`, `hydro`, `bombeo`, `bess`, `hybrid`, `nuclear`, `coal`, `thermal_gas`, `thermal_fueloil`, `thermal` (alias), `biomass`, `cogen`, `autoprod`, `all` (default), and the special case `interconnect` (MIEU/MIP/MIE only, tech bucket = 'interconnect' literal).

Minor (additive) bump: no existing function signatures change. Manifest 8.1.0.0 → 8.2.0.0 forces Excel to refresh the function set so the new ED.OMIE.BIDS appears in IntelliSense.

8.1.0.0

2026-05-12

Added

  • ED.CURTAIL.ECON(tech, [start], [end], [agg], [zone], [headers]) — strict OMIE-based economic curtailment for must-run renewables (solar/wind/vre). Per-slot marginal-price filter: `Σ(offered side=V, price ≤ slot_marginal) − Σ(cleared side=V)`, grouped by tech via `uof_tech_map`. Excludes interconnects (MIEU/MIP/MIE). Flexible techs (thermal_gas/nuclear/hydro/coal/cogen/bombeo/bess) return 400 with an explanatory message — their unmatched offered is strategic bidding, not curtailment.

Minor (additive) bump: no existing function signatures change. Manifest 8.0.0.3 → 8.1.0.0 forces Excel to refresh the function set so the new ED.CURTAIL.ECON appears in IntelliSense.

8.0.0.0

2026-05-05Latest

Added

  • ED.CAPTURE / ED.CAPTURE.RANGE unit parameter: "" (default, EUR/MWh) | "pct" (capture rate %, gen-weighted, the AFRY/EMBER number).
  • ED.CURTAIL.RANGE — renewable curtailment time series. type=economic (forecast vs Σ PBF, VRE only) or type=technical (PBF vs P48, default). unit=mwh|pct.
  • ED.PCT.AT.PRICE — share of a volume metric (gen_*, demand_*, xborder_*, program_pbf_*, program_p48_*) whose hours fall on one side of a price threshold. Use program_pbf_* for the ex-ante OMIE-schedule view (matches ED.CAPTURE method=1) or gen_* for the realized post-curtailment view.

Changed

  • BREAKING: ED.CAPTURE signature reorders to ED.CAPTURE(tech, [date], [zone], [unit], [method], [tz]) — `unit` inserted between `zone` and `method`. Calls that passed `method` or `tz` positionally need an empty slot for the new param. v7 `=ED.CAPTURE(1, date, "ES", 1)` becomes v8 `=ED.CAPTURE(1, date, "ES", , 1)`.
  • BREAKING: ED.CAPTURE.RANGE signature reorders to ED.CAPTURE.RANGE(tech, [start], [end], [agg], [unit], [zone], [headers], [noDate], [method], [tz]) — `unit` inserted between `agg` and `zone`. v7 `=ED.CAPTURE.RANGE(1, A1, A2, 3, "ES", 1, 0, 1)` becomes v8 `=ED.CAPTURE.RANGE(1, A1, A2, 3, , "ES", 1, 0, 1)`.

The bump is BREAKING for users who passed method/tz positionally on capture functions. Manifest version goes to 8.0.0.0 to force Excel to refresh the function definitions. Calls that only used the first three args of ED.CAPTURE (or first four of ED.CAPTURE.RANGE) are unaffected.

7.1.1.0

2026-04-25

Added

  • BE and NL day-ahead spot prices wired into the daily cron via ENTSO-E A44.
  • PT intraday prices recovered via geo_id=1 fallback (sessions s1/s2/s3).
  • unit_generation table migrated to ts_utc PK; per-unit fall-DST 02:XX rows no longer collide.

Fixed

  • DST handling overhaul: every hourly metric now reports the full 8760/8784 CET-fixed buckets per year. Previously the fall-DST 02:XX hour collided with the second 02:XX (CET) and got dropped on insert.
  • Server-side primary key migrated to (ts_utc, metric, zone) so duplicate civil times can coexist; readers using tz=cet/utc see exactly one row per UTC hour.
  • Spanish DST archive recovered: ~5,700 mis-labelled rows patched + 24 fall/spring DST days re-ingested from OMIE, ESIOS and ENTSO-E with DST-aware parsers.

Cosmetic manifest bump; bundle byte-identical to 7.1.0.0 — safe to re-load without breaking sheets.

7.1.0.0

2026-04-24

Added

  • Optional tz parameter on every time-series function: 0/madrid (default, DST-aware) | 1/cet (fixed UTC+1) | 2/utc.

Changed

  • Web /api/data and /api/prices accept the same tz=… query string for parity with the Excel layer.

7.0.x

2026-04-21

Added

  • ED.CAPTURE / ED.CAPTURE.RANGE method parameter: 0=realized (default, matches publications) | 1=PBF (ex-ante, ES only).
  • 5 metals commodities via Yahoo Finance: gold (GC=F), silver (SI=F), copper (HG=F), platinum (PL=F), palladium (PA=F).
  • Slack alerting on daily-ingest sanity-check failures.

Fixed

  • Capture price now uses PBF for current-day fallback when realized data hasn't published yet.
  • 60 ESIOS scheduled-program metrics (PBF/PVP/P48 × 20 techs) seeded back to 2014.

6.5.x

2026-04-15

Added

  • noDate parameter on every *.RANGE function (1 = omit the date column from the spill array).
  • 5-min in-memory cache for repeated cell evaluations (avoids re-fetch when inserting Excel columns).
  • /docs/install: full sideloading guide for Excel Web, Windows Desktop, and Mac.

Fixed

  • Admin Data panel OK/Stale/Missing counters now match the filter-button counts (both compute via getEffectiveStatus client-side).
  • ED.RANGE for monthly aggregates now correctly aggregates by Madrid civil month boundary instead of UTC.

6.0.x

2026-04-12

Added

  • Stripe checkout, webhook, and customer portal (test mode) — 5 plan tiers (free/standard/pro/premium/dev).
  • OilPrice API for Dubai Crude (replaces FRED, discontinued Feb 2026).
  • Yahoo Finance TTF=F for EU gas (replaces FRED).
  • Per-API-key rate limiting (3 windows: rpm/rpd/rpMonth) on public data API.

Fixed

  • Admin license listing collapsed N+1 queries into single listUsers() + Set lookup.
  • API error responses no longer leak raw error.message; logged server-side instead.

5.0.x

2026-04-05

Added

  • Refactored to 9 unified function families (was 20+ scattered).
  • ED.METRICS() spill array listing every available metric with unit and description.
  • Auth (Supabase) + plan-based metric access control via DB.

Earlier

2026-03

Initial milestone: =ED.OMIE() returning real OMIE day-ahead prices in Excel. Capture price (PV/Wind), generation by tech, basic commodities. See git log for the full list.