Market monitor — 2026-05-29
Rules-based streaming projections over the auction record and the append-only event log. Not ML — every flag is explainable to the exact offer, bid, or event that tripped it (the property a regulator needs and an opaque score cannot give). Three detectors fire on synthetic triggers below; eight more are projection-ready.
Synthetic surveillance feed — the triggers are deliberately rigged to demonstrate each detector; figures are illustrative, seed=42.
The evening-peak flags below are not independent scenarios on the same hour — they are one causal chain. The coal fleet withholds ~12 GW (offers 18000 MWh of 30000 MWh rated, no outage), which (1) makes it the pivotal supplier (RSI 0.91), (2) forces the marginal unit up the supply curve onto the Eskom Holdings — OCGT peaker (Generator), and (3) lifts the cleared price to R2188.30/MWh — above the trailing band whose basis is the un-withheld R1081.69/MWh (IPP — battery storage (BESS) (Generator) marginal). Withhold → OCGT marginal → price spike.
1 · Capacity-withholding
RSI: RSI = (total_supply − largest_supplier) / load.
RSI<1 means the largest supplier is pivotal — load cannot
be met without it, so it could raise price unilaterally. Combined with a
submitted-vs-rated heatmap (<80% with no outage logged = red).
(PJM/CAISO DMM three-pivotal-supplier test · FERC.)
How this avoids false positives
Legitimate behaviour: A plant on a forced/planned outage, a derate, or a fuel/water constraint legitimately offers below nameplate; renewables offer below nameplate when the resource (sun/wind) is simply not there.
Carve-out applied: The flag fires ONLY when the system is pivotal (RSI<1) AND the gap is >20% of rated AND there is NO outage/derate on record for that hour — a logged outage or a non-pivotal hour clears the suspect with no analyst time spent.
Not yet modelled: Nameplate here is the offered volume unless a registry override is supplied; a real run would read rated capacity, hedge/affiliate positions, and fuel-availability from the registry. Scarcity-vs-conduct is the analyst call.
| Generator | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Aggregator — renewables pool | ||||||||||||||||||||||||
| IPP — battery storage (BESS) (Generator) | ||||||||||||||||||||||||
| IPP — gas CCGT (Generator) | ||||||||||||||||||||||||
| Emergency reserve — synthetic scarcity tier (Generator) | ||||||||||||||||||||||||
| Eskom Holdings — coal fleet (Generator) | ! | |||||||||||||||||||||||
| Eskom Holdings — OCGT peaker (Generator) | ||||||||||||||||||||||||
| IPP — solar BW5 (Generator) | ||||||||||||||||||||||||
| IPP — wind plant (Generator) |
≥95% offered <80% (outage logged) <80% no outage = withholding suspected
2 · Bilateral wash-trade
A→B at price P matched by B→A at ±P, equal volume, within a 30-minute window — no net economic position changes, the signature of trades placed to paint volume or liquidity. (SEC/CFTC surveillance.) Benign one-way trades and reciprocal pairs outside the window are not flagged.
How this avoids false positives
Legitimate behaviour: Genuine offsetting hedges, intra-group balancing transfers, and ordinary two-way liquidity between the same counterparties are all reciprocal and are NOT manipulation.
Carve-out applied: The screen requires reciprocal direction AND equal volume AND a price delta within ±R5/MWh AND a tight (≤30 min) window — a one-way trade, a different volume, a wide price, or a wide gap is not flagged (shown by the benign and out-of-window rows that stay green on this page).
Not yet modelled: It does not yet net affiliate/hedge registrations or known market-making mandates, which would exempt legitimate two-way flow. The flag is a prompt to ask "why", not a finding of intent.
| Trade id | From → To | Price (R/MWh) | MWh | Minute |
|---|---|---|---|---|
| t-benign-1 | IPP — wind plant (Generator) → Large customer — aluminium smelter | R620.00 | 30 | 09:05 |
| t-wash-A | Aggregator — renewables pool → Aggregator — pool B | R900.00 | 100 | 11:02 |
| t-wash-B | Aggregator — pool B → Aggregator — renewables pool | R901.00 | 100 | 11:14 |
| t-far-A | Large customer — EIUG mine → Distributor — Eskom Distribution | R850.00 | 50 | 14:00 |
| t-far-B | Distributor — Eskom Distribution → Large customer — EIUG mine | R850.00 | 50 | 14:45 |
3 · Price-spike vs trailing-30-day band
Today's hourly SMP against the p5–p95 of a trailing-30-day band for the same hour. Outside-band hours auto-flag (above p95 = red, below p5 = amber). (AEMO Average Price Tables.) The hour 18 flag is the consequence of detector 1's withhold: with ~12 GW of cheap coal held back, demand reaches the Eskom Holdings — OCGT peaker (Generator), so today's cleared SMP (R2188.30/MWh) sits above the band (whose basis is the un-withheld market). The price is a real clearing outcome of the rigged input, not an injected number. The price band itself is synthetic (mulberry32 ±8% of the un-withheld SMP), illustrative only.
How this avoids false positives
Legitimate behaviour: A real scarcity event — a heatwave peak, a large forced outage, or a fuel shortage — produces a high but entirely legitimate clearing price.
Carve-out applied: A band exceedance is an amber/red SCREEN, not a conduct finding: it is read alongside the withholding and marginal-unit detectors. Here the spike is corroborated by a pivotal withhold (one causal chain), which is what separates conduct from scarcity.
Not yet modelled: The band is a synthetic ±8% perturbation of the un-withheld SMP for the demo; a real run anchors the band to metered history and cross-checks demand/outage data before any escalation.
| Hour | p5 | p95 | Today SMP | Band (p5 ▮ p95) · today ◆ |
|---|---|---|---|---|
| 00 | R791.47 | R888.98 | R847.93 | |
| 01 | R781.74 | R894.46 | R839.99 | |
| 02 | R794.94 | R909.76 | R848.83 | |
| 03 | R791.35 | R913.66 | R851.21 | |
| 04 | R778.08 | R892.37 | R832.05 | |
| 05 | R793.28 | R902.13 | R850.31 | |
| 06 | R784.04 | R893.24 | R833.51 | |
| 07 | R791.26 | R909.19 | R854.47 | |
| 08 | R805.75 | R915.86 | R862.87 | |
| 09 | R787.61 | R901.06 | R842.91 | |
| 10 | R805.58 | R903.35 | R851.80 | |
| 11 | R806.39 | R924.99 | R862.87 | |
| 12 | R794.51 | R912.69 | R856.18 | |
| 13 | R800.19 | R911.14 | R864.54 | |
| 14 | R786.73 | R905.67 | R849.56 | |
| 15 | R779.64 | R893.42 | R838.83 | |
| 16 | R786.45 | R908.15 | R847.37 | |
| 17 | R1019.29 | R1174.64 | R1091.95 | |
| 18 | R1024.38 | R1152.89 | R2188.30 | |
| 19 | R1006.37 | R1167.26 | R1086.16 | |
| 20 | R1015.58 | R1144.83 | R1088.33 | |
| 21 | R811.35 | R929.41 | R864.37 | |
| 22 | R803.82 | R918.79 | R869.65 | |
| 23 | R797.45 | R920.28 | R857.23 |
Projection-ready detectors — not yet firing
8 detectors are projection-ready but do NOT fire in this build — only the three above (capacity-withholding, wash-trade, price-spike) run on live synthetic triggers this pass. The same event-log substrate supports each of these; they are designed and listed, not yet wired to data. Each is a rules-based projection, not ML.
Gate-open→close offer mutations: capacity offered early then pulled before gate-close.
Precedent FERC offer-mitigation screens
Cross-party bid-price correlation above a threshold across rolling windows.
Precedent CFTC/EU REMIT collusion screens
Third-party volume vs the Trading Rules R2 §08 ramp cap (20/30/40/50%): amber approaching, hard-block + NERSA-notification event when exceeded. Ties to F6.
Precedent Trading Rules R2 §08
>80% of posted margin used → margin call; at >100% the participant is prudential-collateral-blocked (new positions held until cover is restored). Illustrative SGX-inspired cascade — not a NERSA-published rule.
Precedent SGX EMC prudential / default-waterfall vocabulary (illustrative)
<95% of expected meter telemetry reporting for the hour → reduced-confidence banner.
Precedent AEMO data-quality flags
Nightly re-run from the event log; any divergence from the published receipt is a P0.
Precedent event-sourcing / deterministic-replay invariant
Clustering of offers on round price points (e.g. exact R/MWh hundreds) as a soft signal.
Precedent behavioural-finance round-number bias
Price×volume scatter to surface suspiciously tight offer clusters across parties.
Precedent visual market-monitor exploratory tool