‹ back to the map

Methodology

Every number on the map is either computed from archived public IEMOP market files or a labeled constant with a primary source. This page lists the sources, the access mechanics, the units, and the caveats. Nothing here is an estimate of ours dressed as a fact.

The three questions and how each is answered
  1. Supply headroom. Labeled demand-side anchors (DICT forecast, DOE range, Meralco commitment, DCPH pipeline) are drawn against the market operator's published May 2026 system supply margin, plus observed curtailment and reserve shortfalls computed from the archived real-time regional summaries.
  2. Infrastructure readiness. Named binding equipment counted from IEMOP's public "congestions manifesting" files; the two HVDC inter-island links and three named AC corridors from primary reports; Sual unit-trip arithmetic against the published margin; Sual outage days read from archived outage schedules.
  3. Prices. Each day's average of the load-weighted 5-minute prices per grid from archived LWAP files, split into the administered (pre-resumption) and market regimes; regional spreads; the WESM-to-Meralco pass-through from the June 2026 advisory.

Datasets archived from IEMOP

IEMOP (the WESM market operator) publishes these on public pages under iemop.ph/market-data/ with no login. The public window is rolling (about 90 days per dataset), so this repository archives the files daily; the git history becomes the durable public archive. Access mechanic: each page lists files via wp-admin/admin-ajax.php (action display_filtered_market_data_files) and serves them via a ?md_file=<base64 path> parameter.

DatasetPageWhat we compute
Congestions Manifesting in RTD / DAP (daily CSV) RTD, DAP The constraint league: named equipment and station, ranked by days at a limit (a day counts once, so a day-ahead re-run cannot inflate it). The league keys on equipment, station, and voltage, so a transformer appears under each winding voltage and a line under each terminal: over the window it holds 89 monitored constraints across 75 distinct pieces of equipment, and the headline count is the distinct-equipment one. Real-time (RTD) 5-minute intervals and day-ahead (DAP) hourly rows are kept in separate columns, because the day-ahead projection re-prices through the day and its raw row count measures re-run persistence, not time at the limit. Two severity columns ride along, and reading the wrong one hides the most bound equipment. Overload MW is how far flow was pushed PAST the limit, and it is zero on about 96 percent of the real-time congestion rows because the dispatch holds flow AT the limit rather than over it, so the two Naga transformers and the Leyte-Cebu corridor, among the most persistently bound in the league, carry zero overload. Percent of limit is the real how-bound signal: it never drops below 100 on a congestion row and reaches 112 on the Tabango-Daanbantayan line and 140 at its archive peak. Both are exported; read percent of limit for severity and overload only for the rare true over-limit push.
RTD Regional Summaries (daily CSV; CLUZ/CVIS/CMIN; En/Dr/Fr/Ru/Rd) page Per grid per day: peak scheduled demand (LOAD_BID), curtailed energy (LOAD_CURTAILED, MW per 5-min interval summed to MWh), minimum reserve slack (GENERATION minus MKT_REQT per reserve commodity), shortfall intervals.
Load Weighted Average Prices, final (daily CSV, PhP/MWh) page Unweighted daily mean of 5-minute LWAP per grid, divided by 1,000 to PhP/kWh; daily inter-grid spread and the widest spread in the window.
HVDC Limits Imposed in RTD page Archived; per-interval limit series is a v1.1 layer.
Outage Schedules Used in RTD page Days on which a Sual unit appears in the outage schedule.
DIPC Energy Results, final (hourly zips; nodal LMP with LMP_SMP + LMP_LOSS + LMP_CONGESTION) page Two uses. (1) Per-resource daily energy: SCHED_MW summed per resource per day feeds data/derived/dipcef_daily/ (the raw hourly zips are too heavy to commit, so the compact dailies are the durable record; each day must reconcile to the RTDSUM regional totals within 2 percent or it is refused, and the administered-period days fail that gate by 3 to 5 percent, so only market days are derived). This is where the studio's observed hydro water budgets come from. (2) The LMP_CONGESTION column stays NOT displayed, on purpose: it is zero through the market suspension window and small and intermittent afterward, nonzero on a minority of sampled days and touching only 1.18 percent of clean-day node-hours, so a per-node congestion layer would read as near-empty noise rather than signal. Resolved against the WESM price-determination methodology: across the full derived archive the pricing flags run about 55% ordinary (OK), 22% administered (AP), 16% price-substitution (PSM, re-priced under the market's substitution rules; we do not restate the substituted-price formula here because we have not read it out of the market manual), and 8% security-limited (SEC), so a large share of intervals is priced away from a pure congestion-inclusive nodal price, and even in ordinary intervals WESM expresses inter-island congestion as one regional price per island grid, not a per-node charge. So a "congestion premium = 0" chart would still mislead; the layer stays archived. Full resolution in docs/research-launch-20260705.md.
RTD Market Clearing Price (daily CSV; names the marginal resource and its price per region per 5-minute interval) page Two uses. (1) The observed price-setter table: which resource the operator itself names as marginal, per grid, with share of intervals and mean price when setting; shown beside the model's marginal-block table, never merged with it. (2) The hourly regional clearing-price series the backcast scores against as a second target (per_grid_mcp): the ex-ante clearing price is the quantity commensurate with a dispatch dual, while LWAP additionally carries nodal spread and settlement substitution.
RTD Regional Reserve Prices (daily CSV) page The official co-optimised regional reserve price series per grid and reserve commodity (daily means, window stats). Supersedes the two-day per-resource sample as the reserve view's price evidence; the commodity-code meaning stays a labeled inference (IEMOP publishes no key).
MPI Advisories (daily CSV; the NSO advisory stream) page HVDC blockings and de-blockings, alert states, and trips as the operator announced them: the event log behind the alert-streak and corridor-separation stories, replacing news citations inside the window.
Outage Schedules Used in WAP (daily CSV, week-ahead projection) page The archive's only forward-looking file: what is scheduled out for the coming days, matched to DOE-fleet MW where the alias is confident (the Drivers panel's week-ahead block).
Must-Run Units (weekly CSV, processed SO dispatch report) page Units instructed to run out of merit for grid security, with the stated reason; administered intervals, not market outcomes.
Registered Capacity, generation (daily CSV; participant, resource, maximum capacity) page Archived as the authoritative resource-code-to-MW-and-participant key; next in line to replace the hand-maintained alias table's MW where codes match.
RTD Generation Offers + Self-Scheduled Nominations (hourly CSVs; every resource's priced offer curve, and the price-taking capacity that submits none) offers, self-scheduled The observed supply curve itself. The hourly files are too heavy to commit raw, so pipeline/offers.py fetches a day transiently and commits a compact daily (data/derived/offer_daily/): each hour's book at its first 5-minute interval, all segments pooled per grid and compacted to at most 48 price blocks, self-scheduled MW folded in at the offer floor. Gate: each grid-hour's book must cover that hour's dispatched generation or the day is refused (that gate is how the self-scheduled fold-in was found to be mandatory, not optional). These stacks feed the offer-mode backcast: the same day LP with the market's own bids instead of the cost proxy.
RTD Reserve Offers (hourly CSVs; every resource's priced reserve offer curve per commodity: Fr contingency, Dr dispatchable, Ru/Rd regulation) page Same breakpoint schema as the generation offers. Hourly files too heavy to commit raw, so pipeline/reserve_offers.py derives a compact daily book per grid and commodity (data/derived/reserve_daily/), carrying the hour's scheduled reserve and requirement from RTDSUM beside it. Gate, like-for-like: each grid-hour-commodity book (the hour's opening interval) must cover the opening interval's scheduled reserve or the day is refused (resources re-offer within the hour, so the hour mean is not the opening book's obligation). Now consumed by the reserve replay (each book cleared at the operator's scheduled MW and scored against the official RSVPR price at the same interval, market_ops.json), and input for the queued per-resource joint energy+reserve clear.
GWAP final (daily CSV; per-region generator weighted average price per 5-minute interval) page The series the ERC secondary cap's 72-hour rolling trigger runs on. Raw dailies committed. The trigger arithmetic is now computed on it per region (market_ops.json gwap_trigger), with a clamp scan against the observed price record.
RTD HVDC Schedules (daily CSV; per-interval corridor flow, congestion flag, overload MW for VISLUZ1 and MINVIS1) page The operator's own corridor record, unlike the header-only HVDC-limits files. Raw dailies committed. Now scores both backcast modes' corridor flows directly (profiles.json flows_rtdhs) and supplies per-interval binding truth (CONGESTION_FLAG), a target the advisory-window inference never had.
PSM constrained-on generators (daily CSV; the named units network or security constraints forced to run out of merit, per 5-minute interval, with the cleared or substituted price) page The congestion story with unit names beside the shadow-price league: which generators the constraints forced on, joined to the DOE fleet (market_ops.json constrained_on). Administered outcomes, not market clearing. A final-calculation dataset, about two weeks behind the market day. Added after the round-8 audit.
Security limits used in RTD (daily CSV; per-resource MAX and MIN operating MW per window) page The per-resource operating points security constraints held units to; MAX equals MIN in 99.3 percent of archived windows (regulating hydro, the Agus units, is the exception), so nearly every row is a pinned operating point, the physical record beside the corridor story (market_ops.json security_limits). Published next-day. Added after the round-8 audit.
MOT-raise re-dispatch list (weekly processed CSV; every out-of-merit raise instruction per 5-minute interval with its MW, from the SO dispatch instruction report) page The full out-of-merit record beside the must-run subset: 104 thousand instructions across the archived window at a pooled 55 MW median, against the must-run list's 5.7 per-interval; 2 of the 14 weekly files were published empty and are counted as published (market_ops.json so_instructions). Added after the round-9 audit found it untriaged.
SO dispatch instruction report (per-grid CSVs: dailies plus the operator's weekly compilations; each instruction with MW from/to, category, and the operator's remark) page The instruction log with the CAUSE in the operator's own words: reserve activations with their variance readings, and line limitations named per instruction (the remarks screen in market_ops.json so_instructions counts them). The weekly compilations are archived beside the dailies but never counted, or the window's day-counts would double. Added after the round-9 audit.
Valid discrepancies on the SO dispatch instruction report (revision-stamped weekly CSV) page The operator's own data-quality flag on the instruction family; newest revision per week counted beside the record it corrects. Added after the round-9 audit.
DIPC reserve results final (hourly zips; every resource's cleared reserve schedule and price per commodity, Fr/Dr/Ru/Rd) page The per-resource reserve results the pooled reserve replay and the one-price RSVPR could not carry. Hourly per-resource zips too heavy to commit raw, so pipeline/reserve_results.py takes each hour's opening interval and commits a compact daily (data/derived/reserve_results_daily/, 76 days, 196 resources named). Two comparisons in market_ops.json reserve_results: the final cleared price against the real-time RSVPR, whose gap concentrates on the regulation products (Ru/Rd, largest on Mindanao at about P6/kWh) and stays small on contingency and dispatchable reserve, and the RTDOR book replay's marginal against the same final price, a tighter target than the RTD price, which the book replay under-prices on every one of the twelve pools (the co-optimisation opportunity-cost wedge, one-signed). DIPCRF is the final solve, so its schedule differs from the real-time RTDSUM schedule; that revision is a few MW at most, near zero on Luzon's contingency and dispatchable pools and reaching about 4 MW on the regulation pools and the tight island dispatchable reserve, and is reported not gated. The per-resource cleared schedules are the input the queued joint energy+reserve clear needs. Added by the post-convergence build queue.
Registered capacity, ancillary services (daily CSV; participant, resource, product type Ru/Fr/Rd/Dr, maximum capacity) page The reserve twin of registered-capacity-generation: the reserve book's registration denominator. Raw daily committed. market_ops.json reserve_registration sizes each grid's reserve offer book against its registration base, the same neutral data cut as the generation not-offered screen (registered reserve that did not appear in the offer book, with the same legitimate explanations). Added by the post-convergence build queue.
Settlement-side price families, sampled (hourly zips: indicative administered prices, prices used in settlement, day-ahead prices and schedules) administered, settlement, day-ahead Measured, not built into the replay, because the measurement decided each (pipeline/settlement_side.py, sampled on market days, market_ops.json settlement_side). The indicative administered price is the operator's cost-based counterfactual, not the as-bid market price; it carries the island premium on the corridors (Visayas and Mindanao administered prices run well above Luzon's), a cost-regime cross-check rather than a market series. The settlement congestion component is zero at the one-price-per-island granularity WESM settles at, so it adds no receipt beyond the inter-island differences the flows table carries. The day-ahead price is a projection, out of the real-time replay's scope, and its signed spread to the settled price is reported as a diagnostic. Added by the post-convergence build queue.

Courtesy: fetches are sequential with a 250 ms sleep and abort after 5 consecutive errors. IEMOP data is republished here as-is for public research with attribution; if IEMOP objects to any part of this mirror we will take it down.

Named choke points (primary sources)

CorridorFacts usedSource
Leyte-Luzon HVDCConverter stations Ormoc (Leyte) and Naga (Camarines Sur); 440 MW, 350 kV, 451 km; operating Luzon-to-Visayas limit 250 MW; at max or offline 69% of the December 2025 billing period. Wikipedia (stations, nameplate); IEMOP Dec 2025 report
Mindanao-Visayas HVDC (MVIP)Cable terminals Santander (Cebu) and Dapitan (Zamboanga del Norte); 450 MW expandable to 900 MW; 184 ckm submarine; first energization 30 April 2023; frequently at maximum or security-limited in May 2026. T&D World; IEMOP May 2026 via Power Philippines
230 kV Leyte-Cebu corridorNamed congested, limiting internal Visayas transfers and elevating Leyte nodal prices. IEMOP Dec 2025 report
Cebu import corridor (Cebu-Lapu-Lapu 230 kV)Congestion relief targeted by NGCP projects due 2026. PIA; NGCP TDP 2025-2050 (PDF)
Cebu-Negros-Panay 230 kV backboneCompleted March 2024 to relieve Region 6 constraints; the Visayas grid ran a 52-day daily yellow-alert streak (May 11 to July 1, 2026) that ended when one 150 MW unit returned, with 935.3 MW still unavailable that day. SunStar; GMA

Corridor lines on the map follow the real routed geometry of the lines between the named endpoints above, taken from the OpenStreetMap grid layer described in the next section. A corridor that cannot be resolved onto that geometry would fall back to a straight schematic link and say so on hover; on the current bake all five corridors resolve.

The grid itself: real geometry from OpenStreetMap

NGCP publishes no public GIS. Its Transmission Development Plan maps are raster PDFs, and the network model behind WESM (impedances, ratings) is distributed to members only. The only public source of real routed line geometry is OpenStreetMap, so the map draws it and labels it what it is: community-mapped data under ODbL, not an NGCP document.

Nodal prices: what the market publishes, and the model built on the geometry

DIPCEF (nodal LMP results, final) prices about 1,200 resource nodes per 5-minute interval and decomposes each LMP into SMP + loss + congestion. The raw hourly zips are too heavy to commit and IEMOP's window rolls, so pipeline/nodal_prices.py derives one compact JSON per day into data/derived/nodal_daily/ (the nightly cron tops it up): the regional SMP series, each node's hourly mean deviation from its regional SMP, each node's hourly scheduled MW, and the day's pricing-flag tally (OK / PSM / SEC).

The derived record is surfaced in the product: the map's Prices mode draws each node's persistent deviation from its regional price (clean market days only), each dot sitting on the faint transmission network it belongs to, so the price field reads as the grid coloured node by node rather than dots on a blank basemap. The studio's Analysis section carries a Nodal prices view with the full per-node table. Both label the statistic as an observed locational deviation, not a congestion premium, for the reason stated next.

Placement resolves through a priority of public evidence, every dot tagged with its source: a named OSM substation on the HV network, a named OSM power-plant site, the repo's named-generator pin, a locality centroid for load and delivery codes that name their locality, and a DOE plant-list row whose location column names the municipality (the last two placed at the OSM place centroid, city-precision). Region must agree in every path and ambiguity is a miss, never a guess. The resolved share of scheduled MW per grid ships inside nodal_obs.json as a scoreboard, so the resolution number is public and its drift visible.

What the derived record shows, stated plainly: the published LMP_CONGESTION column is zero through the market suspension window and small and intermittent after real-time pricing resumed on 2026-05-01, nonzero on 28 of the 70 sampled days (median 0.56 PhP/kWh where it fires, up to 19 PhP/kWh on 2026-05-26) and nonzero on 1.18 percent of clean-day node-hours. The SMP is region-constant per interval, so most within-region locational separation rides the loss column, inter-island congestion appears as the regional SMPs splitting, and the small nodal congestion that is priced is sparse rather than a persistent per-node charge. Administered intervals also carry a bimodal SMP (a base value and the same value about 2.2% higher); the regional reference series takes the per-interval mode and reports how many intervals were multimodal.

pipeline/nodal_dcopf.py is the honest tier of nodal modeling this data supports: a reduced backbone (class-typical reactances scaled by real routed length, class-default ratings, both labeled estimates) solved as B-theta linear programs on HiGHS. A replay mode places the day's observed per-node scheduled MW on the network and asks where the flows load it; the defensible validation is whether the equipment RTDCV actually recorded at its limit ranks among the model's most-loaded branches. An OPF mode re-dispatches within each unit's observed-day capability at grid-fuel proxy costs and reads nodal prices off the bus-balance duals. Resolution of DIPCEF resource codes onto buses is partial and reported (share of MW resolved); nothing from this model is presented as an observed number. Branch ratings carry provenance tags: the operator's own observed operating limits (RTDCV/DAPCV BINDING_LIMIT) where the equipment matched, replay-calibrated floors where the observed dispatch visibly carried more than the class default, and labeled class defaults for the rest. The public NGCP TDP attachment is the summary report and carries only grid-level facility aggregates, so per-line TDP ratings cannot be keyed from it; that is the exact boundary, not a hand-wave. The OPF's own measured finding, recorded in the artifact: at the current resolution the re-dispatch concentrates each grid's unresolved generation onto its few resolved plant buses, so modeled price LEVELS are not usable; the probe reports binding geography and the honest gap, and the zonal engine remains the price model.

The loss-surface validation. Because the market's within-region nodal structure is loss-dominated (the congestion column is small and sparse, 1.18 percent of clean-day node-hours), network physics can be tested against it at scale: replay the observed injections on the reduced backbone, take marginal loss factors per node (class-typical resistances scaled by real routed length, labeled estimates), and compare the modeled deviation against each node's observed deviation, grid by grid. The comparison is Spearman rank correlation across nodes plus the error after a per-grid affine fit (the loss-reference convention is an affine choice, so slope and intercept are fitted and reported). The result recomputes nightly as clean days accumulate and ships in loss_surface.json with a self-computing verdict: grids where physics ranks the market's deviations are listed as validated, and grids that fail the test are listed as failing, not hidden. Both surfaces draw it: a three-panel scatter figure in the README (scripts/loss_surface_fig.py) and the studio's Analysis, Loss validation view, which renders the same per-node points, fitted lines, and per-grid verdict from the baked artifact.

Two honest limits on that verdict. The comparison runs on the 15 clean market days (about 21 percent of the 70 sampled) that clear a 90-percent OK-flag filter, so administered PSM and SEC days are excluded; whether the excluded days line up with the choke-point episodes the rest of the site tracks is not yet checked. And because DIPCEF resources that share a substation resolve to the same model bus, the 314, 96, and 118 node counts collapse to 72, 25, and 37 independent buses; the reported spearman_ci95 uses those bus counts, and the 0.4 validated cutoff is a moderate-correlation reporting convention, not a power calculation.

Data-center sites

Only facilities with a citable public source are pinned; each pin carries its source URL and a mw value only where a public figure exists (hollow pins have none). Pins are placed at the named city or municipality, never at a street address. This is NOT a complete inventory: Cushman & Wakefield counts 24 operational facilities (73 MW) with 22 MW under development and 89 MW in planning (APAC DC Update); DataCenterMap lists 44 Philippine facilities.

Demand-side anchors (all labeled)

Market and bill anchors

Units and conversions

The chronological engine and the studio

The studio's engines solve the dispatch as linear programs through HiGHS (the July 2026 solver pass): the snapshot views as a single-hour LP, Chronology and the Backcast as one LP over the 24 coupled hours. Prices are the balance-row duals, real locational marginal prices: an importing grid can price at its neighbour's marginal block plus the small wheeling cost, an exporter at the importer's minus it, and the price-setter label says so (import, export, storage, shortage, or the named fuel). Unserved load prices at the WESM offer cap of P32/kWh (Tripartite Committee Joint Resolution No. 2 s.2013, permanent since December 2015): the market's own ceiling, a published rule rather than a fitted value, applied identically in every engine, the map's browser clear included. One stated exception: if a what-if edit pushes a fuel cost above the cap, the shedding penalty rises just above that cost instead (shedding must stay strictly dearer than serving), and the hour still labels 'shortage'. The secondary price cap (P7.423/kWh when the 72-hour rolling GWAP breaches P12.413/kWh, ERC Resolution 26 s.2025) is stated here as the other published cap, and its trigger arithmetic is now computed rather than cited: the 72-hour rolling mean of the published 5-minute GWAP series (generator-weighted-average-price-final; archived here since July 2026 after a round-7 audit found the earlier "not published" claim false) runs per region in market_ops.json, and for the combined Luzon-Visayas region the operator also publishes. The computation is a finding in both directions. Read the offer-cap-held series, not the raw one: the raw file carries intervals priced up to P165.05/kWh, five times the market's own P32/kWh offer cap, which are violation and scarcity coefficients rather than clears (the operator's own price-substitution record caps at exactly the offer cap, with no exceptions). Held at the cap, LUZON breaches zero windows and its peak falls below the threshold, so its entire breach count came from those intervals. That correction does not erase the finding elsewhere: the System row still breaches held at the cap, as does the combined Luzon-Visayas row, and Visayas and Mindanao run hot either way. Two things that were listed here as unknowns are in fact published: the rule monitors the EX-ANTE rolling GWAP while GWAPF is the final series, and under ERC Res. 26 s.2025 the regional or island cap applies only while a grid interconnection is on outage, which makes the System row the default trigger and the Visayas and Mindanao rows conditional. The observed price record shows no day pinned at either the current P7.423 or the prior P6.245 cap level, so the gap between the computed trigger and the operational one narrows but does not close; what remains unreproduced is the weighting and the imposition and lifting mechanics. The widest-swing as-bid scenario day lands just UNDER the stated threshold (P12.23 against P12.413); an earlier version of this page said it crossed, which was true of the day the old hourly binning selected. Impositions announce themselves in the archived advisory stream when they happen. Tiny deterministic epsilons (at most fractions of a centavo, largest on the last enumerated block) make the optimum unique on the model's flat cost plateaus so both solver builds land on the same answer. The inputs and the checks:

The planning layers (July 2026 pass)

Five layers added in the market-operations pass. Each is either computed from the archive or a sourced list; none runs an optimizer.

Energy-limited hydro, first scoped out for want of a citable monthly figure, later shipped from a better source: the archive's own DIPCEF per-resource schedules give OBSERVED daily hydro energy per grid, day resolution instead of monthly, no interpolation (see the hydro water budgets bullet above). Still not carried, and why: security-constrained unit commitment and minimum up/down times would require per-unit commitment data the Philippine sources do not publish, so modeling them would be fabricated fidelity. RAMP RATES are a different case and this page used to get it wrong: the operator DOES publish them. Every RTDOE offer row carries a piecewise ramp-rate curve (RR_BREAK_QUANTITY1-5 with RR_UP1-5 and RR_DOWN1-5, in MW per minute by MW band), populated on essentially every resource in the interval, in the same hourly file this project already downloads for the offer books. So the question is not whether ramp limits could be modelled but whether they would bind, and that is now measured rather than asserted (market_ops.json ramp_probe, pipeline/ramp_probe.py). They would not, at this engine's resolution. Aggregate each unit's one-hour ramp capability, capped at its own offered range because a machine cannot exceed it, and compare against the largest hour-to-hour demand RISE anywhere in the archived observed profiles (1,223 MW on Luzon, 308 on the Visayas, 307 on Mindanao). The margin depends on how the fleet is counted, so the figure reported is the conservative one: resources that were actually GENERATING that hour, not everything that offered; each unit's SLOWEST published ramp band, not its fastest; and the WORST of six sampled hours spanning weekday and weekend, morning pickup and evening peak. On that strict basis the fleet still out-ramps the worst demand rise by 3.5 times on Luzon, 2.4 on the Visayas and 4.3 on Mindanao. (Counting every offered resource at its fastest band lifts those to 6.1, 3.4 and 6.0, which is why the strict read is the one quoted.) A per-fuel hourly ramp constraint is therefore inert by construction, and building one would be fidelity theater: engine complexity for no accuracy. It is measured out, not skipped. Two honest qualifications travel with that: the result is a grid and fuel-aggregate one at HOURLY resolution, which is this engine's resolution, and per RESOURCE an hourly ramp limit could still bind for about a third of the book (the tightest are oil and coal machines moving under a tenth of their range per hour, so a per-UNIT model would need them); and the 5-minute case is a different question this measurement does not answer.

Boundaries and queued builds, each with its named input

What this map does NOT claim

Known gaps: what a siting or trading decision still needs

This page states its limits section by section; here is the short list a decision-maker would want up front. None of these three is built in, and none is a promise of a future feature: the underlying queue and curtailment data are not public, so this is a stated scope boundary, not a gap we plan to close.

All data sourced from public records (IEMOP market files, NGCP publications, Meralco advisories, PCIJ reporting, company announcements). This tool computes statistical indicators only. Patterns may have legitimate explanations. Specific allegations, if any, require independent investigation and corroboration.

Code MIT; baked data products CC-BY-4.0. Attribution when redistributing: Power Dispatch Studio (2026), IEMOP public market data archive, https://github.com/xmpuspus/power-dispatch-studio.