You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The RPM Final Zonal Capacity Price is natively `$/MW-day`, so we blend by the **actual number of calendar-year days** each DY covers (an exact day-count blend), rather than ISO-NE's `$/kW-month × months` shape:
153
153
154
-
where $P$ is the annualized `$/kW-year` from Final Zonal Capacity Price (convert from `$/MW-day`).
where $P^{\text{day}}$ is the Final Zonal Capacity Price in `$/MW-day`, $d_{\text{Jan–May}}$ is 151 days (152 in a leap year), $d_{\text{Jun–Dec}}$ is 214 days, and the `/1000` converts MW → kW. (The earlier `× 5 / × 7` month split is the same idea approximated to whole months; the day-count form is exact and dimensionally consistent for a daily price.)
155
157
156
158
---
157
159
@@ -227,7 +229,16 @@ Each decision below is **independent**. Recommended defaults are marked ★.
227
229
|**F2 Exceedance weighting**| Threshold-exceedance among the 5 hours (or top-K from summer pool) | Consistent with `allocate_annual_exceedance_to_hours` in `supply_utils.py`; used for RI |**Not** how PLC is defined (average, not exceedance) |
228
230
|**F3 Load-proportional**| Weight by zone load in each hour | Simple physical interpretation | Still not identical to PLC reconciliation |
229
231
230
-
**Recommendation:** F1 if prioritizing PJM fidelity; F2 if prioritizing platform consistency. Document the choice explicitly.
232
+
**Decision: F1 (equal 1/K weights).** This is the implemented choice in `supply_capacity_pjm.py`.
233
+
234
+
**Rationale.** PJM defines a customer's capacity obligation (PLC) as the **simple average** of that customer's reconciled load across the five coincident-peak hours (PJM Manual 19 §4.3; BGE PLC Overview). Averaging across the five hours is mathematically equivalent to giving each hour a weight of exactly **1/5**. Equal weighting is therefore the literal analog of how the capacity obligation is assigned: it is _definitionally_ correct, not merely a convenient default. The exceedance (F2) and load-proportional (F3) alternatives re-introduce a within-peak load signal that the PLC _average_ deliberately removes, so both deviate from the obligation definition. F2 is retained only as a cross-component-consistency sensitivity (it matches the RI dist/bulk-TX convention), not as a capacity-fidelity option.
235
+
236
+
**Empirical note (BGE).** For BGE the choice is also immaterial in practice: BGE's zonal load at the five summer-2025 5CP hours is nearly flat (≈ 6.1–6.6 GW), so F1 vs. load-weighting changes the within-peak split by only about ±4%. Both options place the same total `$/kW-year` on the same five hours.
237
+
238
+
**Sources:**
239
+
240
+
-[PJM Manual 19 §4.3 — Peak Load Allocation (5CP), PLC = average of five hourly loads](https://www.pjm.com/-/media/DotCom/documents/manuals/m19.pdf)
241
+
-[BGE Peak Load Contribution (PLC) Overview — "average of … load during those five hours"](https://supplier.bge.com/electric/load/plcs.asp)
231
242
232
243
---
233
244
@@ -278,7 +289,7 @@ For any new PJM utility MC pipeline:
278
289
## 7. Zone and LDA
279
290
280
291
- BGE serves the **BGE zone** in PJM (Maryland territory).
281
-
- BGE is **not**a separately constrained LDA; it typically clears at the **RTO**Final Zonal Capacity Price.
292
+
- BGE **is frequently a separately constrained LDA**: in the curated RPM dataset it clears at a BGE-specific Final Zonal Capacity Price (above the RTO system price) in 6 of 9 delivery years, including DY2024/25 and DY2025/26 (the DYs that feed calendar-year 2025). The implementation therefore selects the utility's **own zone row**(`zone == "BGE"`) and uses its `final_zonal_capacity_price_per_mw_day`, which already incorporates the locational adder — it does **not** assume the RTO price. (Only DY2018/19 and DY2026/27 had BGE at the RTO price.)
282
293
- Pepco/DPL serve other Maryland areas under different zones/LDAs — do not reuse BGE prices for them.
283
294
284
295
**Sources:**
@@ -376,16 +387,16 @@ Useful for validating order-of-magnitude but **not** a direct hourly MC formula.
@@ -412,15 +423,13 @@ Useful for validating order-of-magnitude but **not** a direct hourly MC formula.
412
423
413
424
Implemented (curated data pipelines, reproducible from committed source intermediates):
414
425
415
-
-`data/pjm/capacity/rpm/` — RPM BRA + Final Zonal prices, DY 2018/19–2026/27. Per-DY markdown intermediates under `sources/` (`rpm_YYYY_YY.md`, both source URLs in the header) → `just convert` → CSV. Rows carry `source_url` (final zonal) and `bra_source_url` citations.
416
-
-`data/pjm/capacity/5cp/` — summer 5CP peaks, **summers 2021–2025** (only those feeding 2025+ runs are retained; earlier summers dropped). Per-summer markdown intermediates under `sources/` (`5cp_YYYY.md`) → `just convert` → CSV.
426
+
-`data/pjm/capacity/rpm/` — RPM BRA + Final Zonal prices, DY 2018/19–2026/27. Per-DY markdown intermediates under `sources/` (`rpm_YYYY_YY.md`, both source URLs in the header) → `just convert` → CSV → `s3://data.sb/pjm/capacity/rpm/data.parquet`. Rows carry `source_url` (final zonal) and `bra_source_url` citations.
427
+
-`data/pjm/capacity/5cp/` — summer 5CP peaks, **summers 2021–2025** (only those feeding 2025+ runs are retained; earlier summers dropped). Per-summer markdown intermediates under `sources/` (`5cp_YYYY.md`) → `just convert` → CSV → `s3://data.sb/pjm/capacity/5cp/data.parquet`.
-`rate_design/hp_rates/md/` — state config (future)
429
+
-`data/pjm/hourly_demand/zones/` — PJM-native zonal hourly loads on S3 (only needed for the E1/F2 load-weighted sensitivity, not the v1 equal-weight pipeline).
0 commit comments