← Manual home

V6 · Trader

Buy from many, sell to many — Trader Pools, the book (Rules · Forecast · Outcomes under Book), the Desk, nominations, BESS and the pool Dashboard.

You are here
1Setup
→
2Deal
→
3Strategy
→
4Nominate
→
5Market day
→
6Settle
→
7Statement

1. What this module is, and why it exists

This volume is the trader seat’s home. It starts at Trader Pools (§2), opens the book behind one pool, and walks Rules, Forecast and Outcomes under Allocation, the Desk, nominations, BESS and the Dashboard. Off-taker screens live in V5 · OffTaker. IPP screens live in V4 · IPP. The shared three-seat picture stays in V3 · Strategy.

Creating a pool (licence, rights, treatments) is §2B. The pool as an entity stays in V2 §5. This volume then opens the book when you need to trade.

1.1 The trader's problem

An energy trader in the South African wheeling market sits between generators and consumers:

The catch is that none of this is flat. Solar produces at midday and nothing at night. Your factory load runs 24/7; your mall load peaks in the daytime; a firm evening block must be served no matter what. Time-of-use tariffs make an evening kWh worth far more than a midday one. So the questions that decide whether you make money are inherently hourly:

Doing this on a spreadsheet is where portfolios go to die. This module does it with a deterministic engine and puts the answers on eight screens.

1.2 What the module does

You group your contracts and sites into pools (supply on one side, demand on the other), and the engine allocates every forecast hour of energy from supply to demand, pricing each flow with the same conventions the settlement system uses. Every result is stored as tagged, auditable allocation lines — so coverage, margin, spill and shortfall are never estimates; they are sums over hourly lines you can drill into. On top of the engine sit the decision screens summarised below.

Auditable allocation lines

An allocation line is one immutable row for one SAST hour: which member of which pool supplied which member of which pool, how much energy was sent and delivered, the buy / sell / wheeling legs in c/kWh, the Rand margin, and which rules produced it. Headline KPIs in Performance and the Dashboard are simply sums (or ratios) over those rows — open a run's Allocations tab (§8) and you can take any number apart.

Four common kinds (illustrative values, same conventions as settlement):

Kind Plain meaning Tiny example
ALLOCATION Energy that actually flowed from a supply member to a demand member 12h · Solar · IPP-A → Industrial · Factory · 16 710 sent · 16 142 delivered · buy 65.0 · sell 120.0 · whl 15.0 · **R 6 088** · merit_order — midday solar wheeled to a factory; margin is (sell − buy − wheeling) × delivered kWh
SPILL Supply nobody bought that hour — you still paid for it 02h · Wind · PPA-W · 3 000 unsold · spill value 10.0c · sunk cost **−R 2 160** — night wind with no offtake; recovery (if any) never fully offsets the buy cost
SHORTFALL Demand nobody supplied — firm buyers then take grid top-up 19h · Firm · Evening Buyer · 2 000 unserved · top-up 225.0c · **−R 1 300** — evening firm gap filled at Eskom rates; the loss shows as negative margin
BESS_CHARGE / BESS_DISCHARGE Battery movement (only when the book dispatched storage) Charge at 12h from free solar spill (margin 0 — it only positions); discharge at 19h against the firm gap, with buy = stored marginal cost and sell = discharge value — the arbitrage is the line's margin

Because every line is tagged, "coverage is 94%" means these hours and members were covered; "spill cost R 2 160" means this exact unsold row. Re-running creates a new run; old lines stay for audit (§1.3).

Decision screens on top of the engine

Off-taker and IPP seats reuse the same engine with buy- or sell-shaped screens (§12–§14); the trader path above is the fullest tour of what "Strategy" means.

1.3 Design principles you will feel in the UI

A run is one complete execution of the allocation engine: given a scenario, a calendar month and a forecast grade (P50 or P90), the engine walks every SAST hour, matches supply to demand under the book's rules, and writes the resulting allocation lines (§1.2). The run is then frozen — coverage, margin, spill and shortfall are simply sums over those lines. You create runs from the Allocation tab’s Forecast mode (§6), open any one in §8 to inspect the proof, and treat the newest non-superseded COMPLETE run for a scenario / grade / period as the current answer for that case. Four deliberate decisions shape how runs (and the screens around them) behave:

  1. Runs are immutable. Once an allocation run completes, its lines never change. Re-running the same scenario and period creates a new run and marks the old one superseded (kept, greyed out). Why: audit trail. You can always answer "what did the book say last Tuesday?", and a settlement dispute can be defended with the exact run that informed a decision.

  2. Every number is a sum over tagged lines. Each line records which member of which pool supplied which member of which pool, in which hour, at which prices, and which rules produced it. Why: when a KPI looks wrong, you drill down to the exact PPA pair and hour instead of arguing about a rollup. The same line-by-line convention reconciles with settlement.

  3. Every run pins its inputs with a hash. The run header shows an inputs hash — a SHA-256 fingerprint of everything the run consumed (members, prices, rules, forecasts, period — and the battery's dispatch parameters). Same hash ⇒ byte-identical results. Why: reproducibility. "Why did run X say margin was R 100/MWh?" — "Here is its hash; re-run with those inputs and you get the same lines."

  4. Scenarios never mix. Every run is labelled by the kind of input it consumed — not by a cosmetic tag. The four labels mean:

    Label What the run does Why it is labelled that way
    FORECAST Allocates the book's rolling supply-forecast shapes against demand profiles for the chosen month and grade It is the operating plan — "what we expect to happen" — and is the default current position in Performance
    NOMINATED Re-runs the engine using the submitted nomination rows as the declared volumes, not the free forecast It answers "what did we say we would deliver?" so you can compare declared position to the forecast plan
    ACTUAL Allocates using settled meter data for the period (when that data exists) It is labelled for realised performance — outcome review after the fact, not forward planning
    SIMULATION Allocates against hypothetical inputs (a candidate PPA, a tweaked shape, an isolated what-if) The name marks it as non-live: it never supersedes your forecast or nominated current, so a sandbox case cannot contaminate the book's real position

    A simulation never replaces your forecast; a later nominated run does not overwrite the forecast current simply because it is newer. Filter and compare within one scenario (§6.3).

    The operating-plan forecast itself has an explicit source order. A human :MANUAL upload still wins; a weather-driven :MODEL series sits below that and above the synthesised per-technology shape. Hours the model covers take dated values; hours beyond the horizon keep the shape. The operator-facing account of where those model numbers come from lives in V4 §17.

The same philosophy extends to nomination and batteries: every nomination the optimiser proposes carries its full rationale (the scenarios it considered, the asymmetric costs, the quantile it aimed for, and what the naive alternatives would have cost), and every hour the battery moves — and every profitable-looking hour it deliberately did not — is recorded and shown. You are never asked to trust a number you cannot take apart.

1.4 Concepts to have in hand before you start

Concept What it means here
Hourly grain, SAST The engine works in hours. All hours you see on screen are SAST (South Africa Standard Time, UTC+2, no daylight saving) — the timezone of meters and tariffs.
TOU (time-of-use) Tariff periods — peak / standard / off-peak — set by the SAST calendar. Contract prices can carry per-period multipliers, so the same PPA prices an evening kWh higher than a midday one.
P50 / P90

Forecast grades. P50 is the median ("expected") generation; P90 is the conservative case you are 90% confident of reaching at least. P90 ≤ P50 always. The gap between the two is where your risk number comes from (§12.3).

Worked example. If P50 is 10,000 MWh, then in a typical year you expect to wheel 10 GWh. If P90 is 9,200 MWh, then you can confidently commit to wheeling at least 9.2 GWh in almost every year.

Risk Gap (MWh) = P50 − P90
Risk Gap = 10,000 − 9,200 = 800 MWh

Risk Gap (%) = (P50 − P90) ÷ P50 × 100
Risk Gap = 800 ÷ 10,000 × 100 = 8%

DLF (distribution loss factor) Physics: energy injected at the generator loses a few percent in the network. A DLF of 0.966 means 1,000 kWh sent becomes 966 kWh delivered. You buy the sent energy and sell the delivered energy — the engine, like settlement, keeps both numbers on every line.
Wheeling The c/kWh network charge for moving energy from source to sink, charged on delivered energy. It comes straight out of your margin.
Spill

Supply nobody bought in an hour. You still paid for it (take-or-pay especially), so it is sunk cost unless the member has a spill value (e.g. a recovery price).

Spill Type Who Pays? Is Spill Lost?
zero_value Nobody Yes – generator loses revenue
discounted_value Offtaker (reduced rate) No – sold at discount
banking Offtaker later No – stored for future
no_preference Depends on default Depends
Shortfall

Demand nobody supplied in an hour. Firm demand must then be topped up from the grid at the member's Eskom top-up price — usually your most expensive energy.

Aspect Who absorbs it? How
Physical shortfall (missing energy) Offtaker They receive less energy
Operational impact Offtaker Must source replacement energy
Financial cost Generator Pays shortfall compensation
Commercial liability Generator Breach of minimum delivery obligation

Shortfall pricing options:

  • Market replacement cost
  • Agreed shortfall tariff
  • Difference between the PPA tariff and replacement tariff
Nomination A monthly declaration of how much a flexible supply member will deliver, hour by hour. Settlement holds you to it: under-deliver and you buy the gap at grid rates; over-nominate and you pay for energy that spills. Getting the number right is what the Nominations workbench (§10) is for. | Nomination workflow: | | 1. Trader forecasts demand. | 2. Trader checks the IPP generation forecast. | 3. Trader builds an MW profile. | 4. Trader submits the declaration. | 5. The declaration becomes the settlement baseline. |
SoC (state of charge)

How full a battery is, in kWh (or % of usable capacity). A battery's whole value is moving energy through time — charge cheap, discharge dear — subject to its SoC window, power limits, efficiency losses and warranty cycle cap (§11).

SoC (%) = (Remaining Capacity ÷ Full Charge Capacity) × 100

Example. If a 10 MWh BESS has degraded to 9 MWh and currently holds 4.5 MWh:

SoC = 4.5 ÷ 9 × 100 = 50%


2. Trader pools — the directory

You need to find the pool that needs action before opening its work. A trader pool groups the rights, contracts and protections under which your organisation buys and sells energy. One organisation can operate several pools. You work on one pool at a time.

Open Wheeling → Trader Pools (/org/trader-pools). Creating or editing the registration record is taught in §2B.

Follow along. Seat: trader_1@webill.net (password supersecret). Path: Trader Pools → T1 Renewables Pool. You should see the directory table, then the pool’s Operations view with five workspace tabs.

2.1 The directory

The financial verdict sits above search. Each table row shows the pool name, contracts and members, lifecycle status, coverage and next step. A pool with a forecast also shows its margin, spill, delivery window, forecast target date, generation time and source allocation run. A future target date is a forecast date; Generated tells you when the record was produced.

Attention first ranks a forecast loss ahead of high spill, other forecast issues, missing members and missing forecasts. A risk reason links to its repair: Commercial for unsold supply, Allocation for missing members, Performance for a forecast, or Operations for a missing SAWEM trading unit. Needs attention filters these rows; search, status and comparison choices survive a visit to the workspace and a return through Pools.

Not assessed · no members means there is nothing to forecast. Not assessed · awaiting forecast means members exist but no snapshot is available. These rows show — for coverage and financial rates. A measured zero appears only when there is an assessment. Active describes the registration lifecycle; it does not mean the pool earns money or is ready for every market capability.

Filters & columns opens status, sorting and optional margin, risk and PPA columns. Selecting a PPA count opens the matching Deals register. Portfolio summary & coverage notes expands the fleet metrics. How to read this links to this manual.

A missing SAWEM (South African Wholesale Electricity Market) trading unit concerns that pool’s market participation. It does not prevent PPA pool creation. Organisation accreditation, pool lifecycle and market registration are separate checks. If the organisation cannot trade, complete its accreditation in V2 §2.

2.2 The detail drawer

Select a pool name to open Operations. Pool details opens the branded right-hand drawer with the operating record, regulator preview, available Trading Units, verdict and Edit & complete pool record. Close it with the X, Escape or backdrop. Archive asks for confirmation and marks a pool Suspended; Activate restores an eligible non-active pool.

2.3 Getting in — the trader strategy area

flowchart LR
  A[Trader Pools directory] --> B[Select a pool name]
  B --> C[Operations]
  C --> D[Choose a workspace tab]
  D --> E[Review evidence and act]
  E --> A
  1. Open Trader Pools and find the pool by name.
  2. Select its name to open Operations at /org/trader-pools/pools/:id/operations.
  3. Choose the workspace tab for the task. Check the pool name and period first.
  4. Use Pools to return with your directory search and comparison choices.

Your pool’s strategy book owns forecasts, allocations and risk records. It is created automatically when needed. An unavailable or foreign pool returns you to the directory. Legacy /org/trader-pools/:id/strategy links still enter the corresponding workspace task.

2.4 The strategy tabs

Tab Job Taught in
Operations Nominations, battery dispatch and operating registration §10–§11
Performance Latest forecast, financial position, flow and exposure §4
Allocation Members, rules, forecast runs and settled allocations §5–§8
Commercial Buying, selling, indicative simulations and pool contracts §9
Dashboard Pool history, risk limits and ranked next actions §12

Older links and chapter anchors retain the names Overview (now Performance), Book (Allocation) and Desk or Simulations (Commercial). A book remains the underlying portfolio record; it is not a separate workspace tab.

Commercial shows a calendar delivery month; Performance shows the latest snapshot’s allocation-run window. They may differ. Read the visible dates and model basis before comparing energy or margin. The Performance headline is the deterministic snapshot result; its separate Monte-Carlo fan shows a distribution and a median, which can produce a different number.

View pool contracts opens an owned, pool-filtered register. Open a contract, then Back to Contracts to retain the pool and register filters. Back to pool returns to the originating workspace and delivery month.

Where this is taught. Registration drafts and applying edits: §2B. Market Trading Units: V2 §5.

2B. Onboarding a trader pool — the licence file

A factory or a wind plant is a place with a meter. A trader pool is not. It is a licensed trader’s trading book: a bundle of rights, treatments and protections under which you buy from generators and sell to consumers. Until that book exists on this platform, there is no directory card, no Strategy book, and nothing to forecast.

The papers do not arrive on one afternoon. If you had to type everything in one sitting, you would lose the work the first time you closed the tab.

Think of a new shop joining the merchant’s list. You start a licence file on the first visit and add stamps as the papers arrive. You do not open the shop until the core stamps are there. That file is the trader pool draft. The live pool is created only when you press Create trader pool.

This is not standing up a generator plant. A plant has a pin, a meter and a technology. This workspace is the pool’s licence, operating and commercial file.

Where this is taught. Generator-site onboarding (site, meter, technology, connection): V2 §4 · V4 §3. Off-taker site onboarding: V5 §2.3. The pool as an entity, accreditation and market Trading Units: V2 §5.

The create path is not a five-step modal. Add New on Trader Pools writes a draft and opens a full-page workspace at /org/trader-pools/onboarding/<case id>. Edit on an existing card opens the same workspace, prefilled from that pool — not a blank draft, and not a second book.

Follow along. Seat: trader_1@webill.net (password supersecret). Path: Trader Pools → the round + (Add New Pool, #open-trader-pool-wizard). You should land on Profile & licence with title Untitled trader pool and a Draft chip. When you have finished reading, press Discard so this seed does not keep a leftover card.

Data. full_demo · seed 42 · Trader 1 · a clean seed has no drafts · last checked 2026-09-18.

2B.1 The trader’s problem

You need a named book that counterparties and the regulator can recognise: who you are, which wires you may use, what you may do, who is accountable, how charges land, and what you promise buyers. Typing that into a one-shot wizard fails the first time a licence date or a policy reference is still in the post.

The workspace lets you pause. Each section autosaves. You return from the amber Trader pool drafts rail on /org/trader-pools until the six core sections pass.

2B.2 How you get here

You must already sit in a trader seat — an organisation accredited to trade. If it is not, Trader Pools shows an amber notice instead of the create button: “The Organization has not been accredited to trade either by Eskom or by any municipality which supports wheeling.” Fix V2 §2 first.

You want to Click path What opens
Start a new pool Trader Pools → Add New (#open-trader-pool-wizard) A new draft at /org/trader-pools/onboarding/<case id>, title Untitled trader pool, chip Draft, data-mode="draft"
Resume a draft Trader Pools → amber Trader pool drafts (#trader-pool-onboarding-drafts) → the named card (#resume-trader-pool-onboarding-<id>) The same draft, last section you were on
Change a live pool Trader Pools → pool card → drawer Edit (#trader-pool-edit-<id>) The same URL, prefilled, chip Editing (#trader-pool-onboarding-edit-badge), data-mode="edit"

The page heading is Trader pool onboarding on a draft and Edit trader pool on a live pool. The eyebrow is Draft trader pool or Registered trader pool. ← Trader Pools returns to /org/trader-pools without discarding.

A foreign or unknown case id never opens. You bounce to the directory with “That onboarding draft is unavailable for this organization.”

Draft licence file versus the live pool — objects this workspace actually writes
Organizationaccredited to trade
→owns
Draftonboarding case
→Create trader pool
Trader poolthe live book
Not created here
Generator siteV2 §4 · V4
Off-taker siteV5 §2.3
SAWEM PartyV9 registry

2B.3 Words on this workspace

Word on the screen Plain meaning
Draft trader pool Still a licence file, not a live book.
Editing You reopened a live pool. Apply changes writes that pool; autosave keeps a draft.
Pool checklist Seven sections. You may jump in any order.
Explanations A right-hand list of plain-language notes. Click a choice to fill that input.
Check & mark complete Saves this section and tells you what is still missing. It does not jump ahead.
Review readiness Lists every section badge. Create trader pool appears only when the six core sections pass.
NERSA National Energy Regulator of South Africa. Licenses trading unless you claim a Schedule 2 exemption.
SAWEM South African Wholesale Electricity Market. Registration lives in standing data, not on this form.
SAPP Southern African Power Pool. Needed only if this book may cross a national border.
Nomination A month-ahead volume plan. This pool has no meter, so a capable book settles by nomination rather than meter reads.
MW / MWh Megawatt is power (how hard you aim to contract). Megawatt-hour is energy (how much you aim to buy in a year). 1 MWh = 1,000 kWh.
Use-of-System Network charges for using the wires.
Imbalance The gap when this book is long or short against what it nominated or contracted.
IPP Independent power producer — a generator you may buy from.
BRP / MPID Balance Responsible Party and its market participant id. Kept on the organisation, not typed here.

The six core sections that must pass before create are Profile & licence, Network & roles, Activities & limits, Operations & data, Commercial & risk, and Customer protections. Market standing data never blocks create. A ready draft usually reads 6 of 7.

Pool checklist — six core sections, then an optional market handoff (as drawn on TraderPoolOnboardingLive)
1Profilename, licence, visibility
→
2Networkwires and roles
→
3Activitieswhat you may do
→
4Operationswho is accountable
→
5Commercialcharges and risk
→
6Protectionsbuyer safeguards
→
7Marketoptional · no form
Draft to directory pool — statuses the create path actually writes
DRAFT
→six core sections pass
READY
→Create trader pool
ACTIVATED
The live pool is then: ACTIVE SUSPENDED

Discard deletes the draft and never creates a pool. Edit of a live pool has no Discard. A new draft can only be created as Active.

2B.4 How to read the checklist badges

Badge What it means
Not started No answers yet.
In progress Some answers, required fields still blank.
Needs evidence Profile, Operations or Protections has some answers but is not complete.
Complete Every required field for that section is filled.
Optional Market standing data with no form — the usual state.

The progress line reads N of 7 sections complete. Beside it the save state says Draft created — no answers saved yet, Draft saved just now, or Last saved {day} at {time}.

The readiness tile is amber while core sections are missing (Draft is safely stored · N core sections still need information). It turns green when create is allowed (Ready to create pool · Core registration controls are complete). In edit mode it always says Draft changes are pending.

Check & mark complete confirms a complete section or shows inline missing-field feedback. Required fields have a star; required licence fields appear when that licence posture is selected. Draft saved does not mean section complete. Review readiness is the same reading in one place. Next: {section} beside it moves to the next section; on the last one, Market standing data, it reads Review readiness.

The section header counts the core sections on their own — Core section 2 of 6, and Optional section 1 of 1 on Market standing data — and stays pinned at the top while you scroll a long section. On a window narrower than 1280 px the checklist sits above the form as a compact two-column grid; picking a section there scrolls the form into view.

2B.5 Explanations drawer

Explanations (#trader-pool-onboarding-explanations) opens a right-hand list for this section (#trader-pool-onboarding-explanations-drawer). Think of it as the card catalogue for the form: find the word, click a choice if you want it written in, close the drawer, keep working.

The header is branded green. The title is Explanations. The eyebrow repeats the section name. Close with the header X (#trader-pool-onboarding-explanations-close), press Explanations again, or press Escape. The arrow beside Explanations points left while the drawer is open.

On a window 1280 px or wider the page makes room and the drawer sits beside the form, so the form stays usable; the checklist shrinks to an icon rail (#trader-pool-onboarding-section-rail), one icon per section with its name on hover. Narrower, the drawer would cover the form, so it opens over a dimmed backdrop (#trader-pool-onboarding-explanations-backdrop), which also closes it. Its intro says which you have — You can keep filling the form while this panel is open. or Close the panel to return to the form.

Most fields here have no ⓘ on the label. Compulsory inputs still show the red *. Topics with choices (status, licence posture, visibility, network rights, roles, activities, treatments, protections) fill the matching input when you click them. Topics without choices (name, emails, document references) are notes only — you still type those.

The drawer stays open when you jump sections, and the topics change to match. NERSA licence topics appear only after you pick NERSA trading licence required. Cross-border topics appear only after Permitted.

2B.6 Create or edit — the chrome

  1. Open Trader Pools. Confirm you may trade (the + is present).
  2. Press Add New to start a draft, or open a card and press Edit to reopen a live pool.
  3. Work the Pool checklist. Jump with the checklist, or press Next: {section} at the foot of each section. Each change autosaves. Use Explanations when a word is unfamiliar.
  4. Press Check & mark complete on a section when you think it is done. Inline feedback lists what is missing and focuses the first missing field.
  5. Keep draft & exit (#trader-pool-onboarding-save-exit) returns you to /org/trader-pools without creating or updating the pool. Draft answers stay on the amber rail. Edit answers stay on the edit case so you can reopen them from Pool details. The confirmation explicitly says the live pool is unchanged.
  6. Review readiness on a new draft, or Review & apply changes on an edit, (#trader-pool-onboarding-review) opens the modal. Every section badge is listed, with repair links for missing information. Tab stays inside the review; Escape closes it and returns focus to the review button.
  7. On a draft, Create trader pool (#trader-pool-onboarding-create-pool) is shown only when nothing core is missing. On success the case is ACTIVATED, the live pool is written, and you return with {name} was created successfully.
  8. On edit, the same button reads Apply changes to live pool. It writes the answers onto the existing pool and returns with {name} was updated successfully. It does not create a second book.
  9. Discard (#trader-pool-onboarding-discard) exists only on a draft. It asks first, then deletes the case and never creates a pool. Edit has no Discard — you cannot throw the live pool away from here.

Locked on edit (#trader-pool-onboarding-roles-locked): Eligible supply roles, Eligible demand roles, and Nomination capability. They are set at creation and stay as registered. The notice on Network says so. Save leaves those three alone even if the form is tampered with.

Dropdowns on this workspace are listed A–Z by label (Active before Suspended; Private before Public; Eskom and municipality before Eskom only).

2B.7 Profile & licence

Section hint on screen: “Pool identity, licence or exemption evidence and effective dates.”

Who this shop is, and whether it may trade under a full NERSA licence or a Schedule 2 exemption. An amber Licence evidence note is always shown: Eskom virtual wheeling still wants the evidence reference.

Defaults on a new draft: Schedule 2 exemption / registration applies, Active, Public.

Field Required to create? What it means
Pool name Yes Everyday name. Becomes the directory card and the Strategy header. Placeholder: e.g. Cape Commercial Energy Pool. A brand-new draft shows Untitled trader pool until you type one.
Initial status Yes — and it must be Active Whether this pool is allowed to trade when you create it. Active — authorised and operational. Suspended — temporarily restricted; a new draft cannot be created in this state (initial status must be Active). Expired and Revoked are not on this select — those states come later from the directory. Click-to-fill in Explanations.
Trading licence posture Yes Schedule 2 exemption / registration applies — no NERSA number is required; keep the exemption evidence reference. NERSA trading licence required — shows number, issue date and expiry. Click-to-fill.
Counterparty-directory visibility Yes Public — eligible counterparties can find this pool. Private — only your organisation sees it. Click-to-fill.
Licence / exemption evidence reference Yes A document id, controlled URL or repository name. Store a reference, not the file. Eskom asks for this on virtual wheeling.
Pool effective date No The day this pool’s mandate starts, if later than licence issue. Leave blank if it starts when you create the pool.
NERSA licence number If licence required The identifier on the trading-licence certificate. Hidden while Schedule 2 is on.
Licence issue date If licence required The day NERSA issued the licence.
Licence expiry date If licence required The day that licence ends.

Empty Pool name or missing evidence keeps Profile at Needs evidence. Picking Suspended keeps create blocked even if every other field is filled.

2B.8 Network & roles

Section hint: “Access mandate, trading roles and cross-border authority.”

Which wires this book may use, which generator and buyer shapes it may take, and whether it may cross a national border. This is the pool’s mandate, not a site connection.

Cards you are not accredited for do not appear. A trader with only Eskom accreditation sees Eskom only. Both accreditations unlock Eskom and municipality. The default is the first of Eskom · Municipality · Both that you hold.

Defaults on a new draft: cross-border Not permitted, supply Flexible, demand Trader sales, nomination Nomination capable.

Field Required to create? What it means
Network access rights Yes Eskom only — national Transmission / Distribution. Municipality only — municipal distributors. Eskom and municipality — hybrid. Click-to-fill; hidden options stay hidden.
Cross-border trading Yes Not permitted — the book stays inside South Africa. Permitted — you may import or export; two more fields then become required. Click-to-fill.
Import / export licence reference If Permitted Document id for the cross-border authority. Shown on a blue panel only when Permitted.
SAPP portfolio name If Permitted The Southern African Power Pool book this pool is registered under.
Eligible supply roles At least one supply or demand role Which generator or trader supply shapes this book may take members from. Solar — daytime photovoltaic. Wind — variable day and night. Firm — dispatchable or firmed capacity, including a BESS (Battery Energy Storage System). Flexible — nomination-capable supply. Multi-select cards. Click a card or an Explanations choice to add or remove. Locked on edit.
Eligible demand roles Same rule Which buyer shapes this book may serve. An off-taker joins only when one of its strategy demand classes intersects this list. Industrial — factories and continuous process. Commercial — daytime-biased retail. Municipal — municipal bulk. Trader sales — sales into another trader’s book. Locked on edit.
Nomination capability Yes Nomination capable — this meterless pool may submit a nomination as supply. Not nomination capable — it cannot. Locked on edit. Click-to-fill on a draft.

A plant you later add must share at least one supply class with this list. That matching is taught with generator-site classes in V2 §4.2.

Careful. Cross-border Permitted without both references flashes Still needed: import/export licence, SAPP portfolio.

2B.9 Activities & limits

Section hint: “Permitted scope, restrictions and compliance controls.”

What the licence allows, and what it forbids. Defaults: Buy energy, Sell energy, Wheel energy ticked; restrictions empty.

Field Required to create? What it means
Permitted activities At least one Operational scope under the mandate. Buy energy — contract with generators or permitted sellers. Sell energy — on-sell or allocate to customers. Wheel energy — arrange wheeling, nominations and settlement. Aggregate generators — combine more than one generator portfolio. Portfolio balance — manage aggregate mismatch. Market participation — interact with market or balancing mechanisms. Forecasting — submit generation and load forecasts. Settlement — calculate invoices, credits and imbalances. Click-to-fill.
Licence restrictions No Hard limits in the licence or mandate (red-ringed cards). No generation — cannot act as a generator. No distribution grid holding — cannot hold grid assets. No unregistered IPPs — only authorised generators. No unregistered off-takers — only approved customers. Capacity limits enforced — observe contracted limits. No market speculation — stay inside the mandate. No unilateral tariff changes — follow agreed pricing. Optional. Click-to-fill.
Compliance and market-conduct policy reference Yes A policy id or controlled document URL for how this book behaves in the market. Placeholder: Policy ID or controlled document URL.

2B.10 Operations & data

Section hint: “Accountable contacts, secure interfaces and reconciliation.”

Who runs the book day to day, and whether the secure link that carries nominations, meter data and settlement files is ready. A blue Operational accountability note is always shown: SAWEM wants that link; NERSA’s draft bilateral rules want a monthly energy and money reconciliation path.

Default: Secure data-interface readiness is Not assessed. Create will not accept that default — the interface must be Ready.

Field Required to create? What it means
Operational contact name Yes The person accountable for forecasts, interfaces and incidents.
Operational notice email Yes Where operating notices for this pool should be sent.
Settlement and reconciliation email Yes Where monthly energy and financial reconciliation notices should be sent.
Secure data-interface readiness Yes — and it must be Ready Not assessed — nobody has reviewed the link. Planned — designed, not built. Testing — under test. Ready — the link can carry operating data. Remediation required — the check failed. Create flashes data interface must be Ready for any other pick. Click-to-fill.
Monthly reconciliation procedure Yes A procedure id or controlled URL for how this book compares energy and money each month.
Data / interface failure procedure Yes What to do when the secure link drops or a file fails. A reference, not the runbook file.
Cybersecurity controls reference Yes The control-set or policy id that protects this book’s operating interfaces.

2B.11 Commercial & risk

Section hint: “Procurement targets, wheeling charges and balancing exposure.”

How you aim to buy, how network charges reach customers, and who carries imbalance. The megawatt targets are planning figures. They do not create a deal.

Defaults: wheeling Full pass-through, balancing Trader-borne.

Field Required to create? What it means
Procurement target (MW) No How many megawatts this book aims to contract. Step 0.001; minimum 0.
Annual procurement target (MWh) No How many megawatt-hours this book aims to buy in a year. Optional.
Wheeling charge treatment At least one How Use-of-System / wheeling charges reach customers. Full pass-through — charges flow at source cost. Blended — charges sit inside a blended energy price or service fee. Partial pass-through — some charges pass through; others are absorbed or capped. Multi-select. Click-to-fill.
Balancing cost treatment Yes Who carries mismatch. Trader-borne — this book carries it and charges a spread or fee. IPP-borne — the generator carries shortfall or curtailment. Off-taker-borne — the buyer carries it. Shared — split under an agreed rule. Pass-through — charges and credits follow a published formula. Market-indexed — priced from an external index. Single select, A–Z. Click-to-fill.
Commercial dispute-resolution policy Yes Procedure id for invoice, tariff or allocation disputes on this book. Placeholder: Procedure ID or controlled document URL.

Where this is taught. How settlement applies wheeling and imbalance: V8 §7.

2B.12 Customer protections

Section hint: “Safeguards, complaints, consent and dispute procedures.”

What this pool promises the buyers it serves. Defaults already ticked: Price caps, No unilateral price changes, Billing transparency, Balancing-cost protection, Dispute resolution. You may add or remove cards; at least one must remain.

Field Required to create? What it means
Off-taker protection measures At least one Contractual safeguards. Price caps / Price floors — maximum or minimum customer price. Fixed-price windows — locks a price for a defined period. Transparent indexation — names sources and fallbacks. No unilateral price changes — an agreed change process. Billing transparency — calculation lines and evidence. Supply continuity — fallback when wheeled energy is unavailable. Curtailment protection — who carries a network cut. Balancing-cost protection — limits mismatch for the buyer. Forecasting support — data and cooperation. Dispute resolution — escalation path. Error correction — recalculation windows. Independent verification — independent checks. Realtime data access — operational visibility. Data integrity — validated settlement data. Audit trails — regulatory and financial evidence. Click-to-fill.
Customer complaints procedure Yes Procedure id or controlled URL for how a buyer raises a complaint.
Customer consent register Yes Register id for the consents this book holds — data use, allocation and billing authority. A reference, not the signed file.

2B.13 Market standing data

Section hint: “SAWEM Party, agreements, accounts and credit cover remain authoritative.”

This section is a placeholder handoff, not a form. There are no inputs and no Check & mark complete; as the last section it ends with Review readiness. Market Participant identity, MPID, Market Participation and Balancing Agreements, settlement accounts and credit-cover providers belong to the organisation-level Market registration. This pool links to those records instead of copying them.

The card heading is Keep SAWEM standing data authoritative. Open Market registration goes to /org/brp/registry.

You can still create the pool and trade on a physical or virtual PPA without SAWEM registration. The pool is then not yet a market participant. The badge stays Optional.

Where this is taught. Trading-unit registration: V9 §3.9B. What a Trading Unit is: V9 §3.3.

2B.14 What “done” looks like

  1. Review readiness lists every badge. Missing core titles appear as a comma-separated list (Profile & licence, Operations & data).
  2. Create trader pool is shown only when nothing core is missing. Create on an incomplete draft stays hidden; the modal title is More evidence is needed.
  3. On success the draft is ACTIVATED, the live pool is written with the answers (and any onboarding-evidence references), and you return to the directory with {name} was created successfully.
  4. Done on this seat is: a quiet card with the name you typed, status Active, and no amber draft row for that id. Strategy still needs a first Performance click (§2.3 · §3).

Keep draft & exit on a draft leaves an amber rail Trader pool drafts (#trader-pool-onboarding-drafts) above the pool cards. A clean Trader 1 seed has no drafts until you press +.

You see It means
Untitled trader pool Brand-new draft. Type Pool name.
Still needed: … Required answers still blank, or a rule failed (Active, Ready, at least one role).
Review without Create trader pool A core section is incomplete.
That onboarding draft is unavailable… Wrong organisation or unknown id.
Market section with no inputs Built that way — not an unfinished screen.
Edit on a live card Same workspace, Editing chip, pool already filled. Apply changes to live pool writes that pool. Supply roles, demand roles and nomination stay locked.
No Discard You are editing a live pool.
Amber Trader pool drafts missing No open drafts — the usual clean seed.

Where this is taught. The directory that receives the new card: §2. Opening the book: §3. Wiring members: §5. Generator plants you may later buy from: V2 §4. Off-taker shops you may later sell to: V5 §2.3.

3. Getting in — open the book behind a trader pool

Your commercial portfolio can look healthy in the directory while still having no forecast, allocation or risk view. Strategy gives each trader pool a book: the system record that turns its contracts into a plan you can inspect and act on.

Data. full_demo · seed 42 · stage S09 (settlement matrix) · last re-derived 2026-07-18 against the full_demo manifest.

3.1 Pool, book and seat

A Trader Pool is the commercial grouping you manage: its generators, off-takers, prices, rules and coverage targets. A Trader Book is created for that pool when you first open Strategy. It owns its runs, allocations, simulations, nominations, battery schedules, snapshots and limits.

The seat determines the question you ask. A trader seat balances supply against demand; an off-taker seat starts with savings; an IPP seat starts with revenue and unsold energy. They use the same engine but are entered from their own directories. §12 maps those other seats without changing the trader workflow taught here.

You are looking at What it contains Your first question
Trader pool Commercial members and contracts Do my buys cover my sales?
Strategy book Executions and decisions for one pool Is this portfolio healthy today?
Market seat BRP registration, where enabled Are bids and imbalance controlled?

You never create the book in a separate setup wizard. Opening a pool workspace creates it if needed. Select Performance to inspect its forecast. That first visit can legitimately have no snapshot yet: it means no forecast has been run, not that the book is broken.

3.2 Open Strategy for the right pool

Start at Wheeling → Trader Pools (/org/trader-pools). Select the pool name to open Operations, then select Performance, Allocation, Commercial or Dashboard. The pool workspace uses /org/trader-pools/pools/:id/:section.

Check the pool name in the header: every number belongs to that pool. Unknown or foreign pool IDs return you to the directory.

Follow along. Seat: trader_1@webill.net (password supersecret). Path: Trader Pools → T1 Renewables Pool → Performance. You should see the same pool name and the latest forecast’s delivery window and generation time.

The demo also contains T1 Industrial Pool. Open it in a second browser tab only if you are comparing portfolios; do not infer a cross-pool total from either book’s KPI cards.

3.3 Read the directory before entering

The table directory and its dated financial verdict are taught in §2. It ranks material financial issues before setup tasks. Empty pools show Not assessed and dashes; an Active status is not a health verdict.

The optional portfolio summary shows the five metrics below. Pool rows always show forecast margin and spill when assessed. A forecast target date describes the model date; the generation timestamp describes when the record was created.

The five portfolio stat cards

Each top card answers one triage question about the whole organisation's trader books. The same labels appear as columns on every pool row — read the card for the portfolio glance, then the matching cell to find which pool is driving it. Full definitions and hour-level proof live in Performance and in the run detail (§4.1, §8).

Coverage — "Can we serve the load we sold?"

What it is. The share of demand that the book actually delivered under the latest forecast run.

Coverage = delivered energy ÷ demanded energy

Plain reading. Of every 100 kWh your offtakers wanted in the snapshot month, how many did wheeled supply cover? The gap is shortfall (see below) — often filled at expensive grid top-up for firm buyers.

Example. Demand = 100 MWh, delivered = 82 MWh → Coverage = 82%.

Demand   |████████████████████| 100 MWh
Delivered|████████████████░░░░|  82 MWh   → Coverage 82%
                     shortfall 18 MWh

Directory alert. Rose when Coverage < 50% — the book is failing to cover most of its sold demand; open that pool's Strategy before anything else.

Margin (fcst) — "What does the expected plan earn?"

What it is. The Rand result of the deterministic snapshot forecast: revenue from sales less the buy cost, wheeling and other forecast costs the engine priced on the allocation lines. The source label identifies the run-period or 30-day equivalent margin; the value is money, not a percentage.

Plain reading. If generation and demand land near the median forecast, does the book make or lose money over the snapshot month? Positive is the plan earning; negative means the expected shape already loses before you consider adverse weather.

Example. Sold energy earns R 1.20 M; buy + wheeling + spill sinks cost R 0.95 M → Margin (fcst) ≈ R 250K (directory cards may show compact R 250K / R 1M forms).

Revenue (sell)     +████████████████  R 1.20 M
Costs (buy+whl+…)  −████████████░░░░  R 0.95 M
                   ─────────────────
Margin (fcst)         ███             R 0.25 M

Directory alert. Rose when Margin < R 0 — the expected plan is already underwater; open Overview, then the run's allocation / spill / shortfall tabs to see which hours destroy value.

Margin@Risk (MaR) — "How much of that margin vanishes if generation is weak?"

What it is. The share of expected (P50) margin that disappears when the engine re-runs the same book on the P90 adverse generation case (firm obligations still priced at replacement cost).

Margin@Risk = (P50 margin − P90 margin) ÷ P50 margin

Plain reading. P50 is "what we usually earn"; P90 is "what we still earn when supply is conservatively low." MaR is the fraction of expected margin at risk if the adverse world shows up — not a second margin amount. A book with the same P50 margin but wind-heavy supply often has a higher MaR than a solar-heavy book, because wind's P50→P90 degradation is steeper (§6.4).

Example. P50 margin = R 1 000 000, P90 margin = R 720 000:

MaR = (1 000 000 − 720 000) ÷ 1 000 000 = 28%

P50 margin |████████████████████| R 1.00 M
P90 margin |██████████████░░░░░░| R 0.72 M
            ←──── MaR 28% ────→   margin destroyed in the adverse case

Directory alert. Rose when MaR > 20% — more than a fifth of expected margin is sensitive to weak generation; do not "fix" it only by chasing a higher P50 — the P90 gap has to improve too (§4.2).

Spill — "How much bought supply has no buyer?"

What it is. The share of total supply in the snapshot that was unsold in its hour — energy you procured (or generated under contract) that nobody took.

Spill = unsold supply ÷ total supply

Plain reading. Midday solar with no matching industrial load, or night wind with no offtake, shows up here. You often still paid for that energy (especially take-or-pay), so spill is usually sunk cost unless a spill value / recovery price softens it (§1.4).

Example. Total supply = 120 MWh, unsold = 9 MWh → Spill = 7.5%.

Supply |████████████████████| 120 MWh
Sold   |██████████████████░░| 111 MWh
                spill 9 MWh → 7.5%

Directory alert. Rose when Spill > 20% — a large slice of supply is orphaned; typical next move is daytime offtake on the Simulation workbench (§9), not more supply.

Shortfall — "How much demand still needs cover?"

What it is. The share of total demand that went unmet by wheeled supply in the snapshot — the mirror image of Coverage's gap.

Shortfall = unmet demand ÷ total demand

Plain reading. Evening firm load after solar drops off, or a book that simply does not have enough contracted supply, shows up here. Firm offtakers then take grid top-up at their Eskom (or replacement) rate — usually your most expensive energy and a direct hit to margin.

Example. Total demand = 100 MWh, unmet = 18 MWh → Shortfall = 18% (and Coverage would be 82% on the same numbers).

Demand  |████████████████████| 100 MWh
Covered |████████████████░░░░|  82 MWh
                 shortfall 18 MWh → 18%

Directory alert. Rose when Shortfall > 20% — a large slice of sold demand is uncovered; add supply, reshape demand or firm cover — the opposite physical fix from high spill (§4.2).

Other signals on each pool row

Signal on the Trader Pools row Where it sits Meaning What you do next
Pool name Left column, bold The commercial book you will open Confirm this is the portfolio you intend to operate
Status badge (ACTIVE, SUSPENDED, …) Under the pool name Registration / trading status of the pool itself — not a Strategy health colour Prefer an ACTIVE pool; investigate before operating a suspended one
Public / private dot Small green check or red × on the pool icon Whether the pool is listed as public Orientation only; does not change Strategy maths
The five KPIs above Centre columns (rose when alert) Latest Strategy snapshot for this pool Rose → open Strategy and diagnose; normal → open only if you need evidence
— in a KPI cell Same columns No snapshot written yet Open Strategy, check membership, then Run Forecast Now
Physical / Virtual circles Two columns before Actions Count of physical vs virtual PPAs on the pool Sanity-check contract shape before entering
Scale icon Actions column (tooltip Strategy) Enters the Strategy book for that row Click when you have chosen the pool

Hover any action icon if its meaning is unfamiliar; Strategy is always the scale icon with the "Strategy" tooltip.

Careful. A directory KPI is only as recent as its latest snapshot. If you have just added a contract or changed a rule, open Strategy and use Run Forecast Now before treating the number as a decision. Spill and shortfall can both look "amber-sized" for opposite reasons — read which card (or column) is stressed before you act.

3.4 The shared Strategy shell

Every trader-book route keeps the same context so you do not lose your place while moving from a problem to its evidence:

These are routes within the selected pool, not global worklists:

Tab · mode Route suffix Use it when
Overview /strategy You need the 30-second health check
Book (default) /book → /pools Opens Rules — the cascade board. Top tab stays Allocation (#strategy-tab-book)
Book · Rules /pools (#book-stage-rules) You must change portfolio structure — the cascade board, with what the latest forecast did to each pool
Book · Outcomes /book?mode=outcomes (#book-stage-outcomes) You need the settled month: procured against sold, the money, the chains (§6A, §6B)
Book · Forecast /book?mode=forecast (#book-stage-forecast) You need a reproducible forward engine execution: the run picker, tiles, flow, margin, caps, the battery fold; Open the run ledger › sits at /allocations/<run id> (§8)
Book · Battery dispatch /bess The battery’s full day view, still under Allocation. Open it from Forecast’s Open full dispatch ›, not from a fifth top tab (§11.11)
Desk /simulations You need to sell what the book is long or buy what it is short — position, candidates, basket, strategy board, commit (§9)
Desk → Commit · Nominations /nominations You must prepare next month’s position or read a past plan — reached from the Desk’s Commit step (plan rows and Open the nominations workbench ›) or from Overview Open Nominations workbench (§4.5, §9.9, §10). ?from= sends ‹ Back to that door.
Dashboard /dashboard You want the long view: the pool’s story since it began — performance, leaks, trading web, health, outlook, moves (§12)
Desk · Counterparty exposure /exposure → forwards to /simulations You need the per-counterparty table (§9.10)

The old Nominations and Exposure tabs are now the Desk’s Commit step and its exposure section (/exposure forwards; /nominations keeps its URL). The old Pools, Runs, Chains and BESS tabs forward into the Book: /allocations → Forecast, /chains → Outcomes, /bess stays as the battery’s full dispatch page under the Book tab.

Careful. Forecast and Outcomes are the two directions of time in one room. They are not extra tabs on #strategy-nav — Allocation stays the top tab. Forecast (…/strategy/book?mode=forecast) is the strategy engine’s forward ledger for one run. The thread strip at the top of each Book view says which stage you are reading.

3.5 Read badges before acting

Badges here are the small labelled tags on Strategy screens — not the directory KPI values in §3.3. There are two kinds; read both before you treat a number as actionable.

Run and scenario badges

These appear mainly in Allocation’s Forecast run picker (§6) and on a run's detail header (§8). Each run row shows its scenario (what inputs the engine used) and its status (whether the execution finished, failed, or was replaced). They tell you whether a value is a plan, a declaration, a settled result or a safe what-if — read them before comparing two numbers.

Badge Meaning Decision consequence
FORECAST Rolling P50 plan Use for the expected book position
NOMINATED Submitted nomination rows Compare with what you declared
ACTUAL Settled meter data Use only when available for outcome review
SIMULATION Isolated what-if Never mistake it for live exposure
PENDING / RUNNING Engine has not finished Wait; do not treat partial rows as a result
COMPLETE Immutable execution succeeded Safe to drill into and compare
FAILED Execution ended with an error Previous current result remains intact
SUPERSEDED Newer run replaced it for its scenario and period Keep it as history, not the current plan

Severity badges

These appear on the Performance KPI cards (§4.2) and on the Dashboard (§12). They use the same language everywhere:

Badge Colour Means
ok Green Within every configured limit
warn Amber A warning threshold is crossed
breach Red A hard limit is crossed

If no limit exists, the metric remains ok; green therefore means "within configured limits," not "commercially perfect."

"Read badges before acting" means: check what kind of run you are looking at, and whether a card is warn or breach, before you act on the number.

3.6 A first five-minute tour

  1. Open T1 Renewables Pool and confirm the header.
  2. Read the Overview cards; if there is no snapshot, select Run Forecast Now.
  3. Open Book · Rules and check that supply and demand members look commercially plausible before changing anything; read the outcome badge on each card.
  4. Open Book · Forecast; the run picker opens on the newest FORECAST P50 run — this is the evidence behind the Overview.
  5. Return to Overview, then use Dashboard only if amber or red needs an hour-by-hour explanation.

Follow along. Seat: trader_1@webill.net (password supersecret). Path: T1 Renewables Pool → Strategy → Runs. You should see a newest-first index where a current completed forecast is not labelled SUPERSEDED.

The next chapter uses the Overview as your daily opening move. When a card points to structural work, go to §5; when it points to a commercial opportunity, go to §9.

4. Overview — run the book

Route: /org/trader-pools/:id/strategy · Tab: Overview

You buy energy from many sellers and sell it to many buyers. Every morning you need one answer for this trader pool: is the book earning, where does the energy go, what can still go wrong, and what should you trade next? Overview is that page. It does not sign a deal. It reads the latest risk snapshot — a sealed forecast result — and turns it into cards you can scan in about a minute.

Think of a merchant’s shop window. The window does not restock the shelves. It shows today’s takings, what is still on the shelf, and the one job to do first. That window is Performance. The storeroom where you wire shelves and baskets is Allocation. The counter where you try a buy or a sell is Commercial. The lifetime accounts are Dashboard.

Where this is taught. How the directory lists every pool: §2. How you create or edit a pool’s licence file: §2B. How you open Strategy for one pool: §3. How you wire members and rules: §5.

How to read the whole page, then what to do

Read top to bottom. Do not start in the middle.

  1. Confirm the chip in the top bar names the pool you meant ({pool name} · Strategy). Overview is one book. A healthy neighbour says nothing about this one.
  2. Read the first card — the big sentence. That is the period result in one line: the book earns or loses, and often why (spill that never sold, or demand left unmet).
  3. Glance at the three tiles under that sentence (Margin@Risk, VaR 95, spill / resale). Then the four Structural position bars beside it. Colour first: rose is a problem, amber is a warning, brand green is inside the tick.
  4. Check Concentration. One supplier or one buyer taking most of the book is a different risk from a bad hour.
  5. Read Where the energy goes left to right: supply pools → demand pools. Thick green ribbons are good trade. Thick rose ribbons lose money. Amber leaving to Spill · bought, unsold is energy you paid for with no buyer. Rose arriving from Shortfall · unmet demand is load you sold and did not cover.
  6. Trust rank 1 on Next best actions, then verify it on the screen the link opens. The list is a first move, not a signed order.
  7. Open Long or short, hour by hour only when you need the clock: which SAST hours are matched (green), long / spill (amber), or short / shortfall (rose). Switch Typical day and Tomorrow (P50 supply) to see whether tomorrow’s weather repeats the shape.
  8. Use Pool health to name the shelf or basket. Then Where the margin is made and lost for the month × hour, and Forecast said, book settled for whether the plan has been honest.

Good on this page: a headline that earns, spill and shortfall inside their ticks, green ribbons, an empty or quiet action list, and Pool health chips that read ok. Bad: a headline that loses because N% of what it buys never sells, rose gauges, a fat amber spill outlet, rank 1 telling you to sell the spill or cover the shortfall, and breach chips on Solar or Industrial.

Where you go next — only exits that exist on this screen:

Exit Where it is What it is for
Allocation Tab Wire pools, see the forecast, read settled outcomes
Commercial Tab (/strategy/simulations) Try a buy or a sell before it is real
Dashboard Tab Limits and the long view
← Trader Pools Back link The directory — not a pool switcher
Action links Inside Next best actions Simulations, Nominations, Pools, Allocations, BESS, or Dashboard — only when that action fires
Open Simulation Workbench Footer of the actions card Always there; same Desk
Open Nominations workbench Footer of the actions card (#overview-open-nominations) Always there — past and next plans, not only when a leak ranks
Plant now chips Under the Long or short legend (#trader-plant-chips), only if a supplier is live Opens Your plant live on this Overview
Run Forecast Now #overview-run-forecast Seal a new snapshot (§4.10)
Explanations #overview-explanations-open How to Read the View, then the A–Z words used on this page

There is no Nominations tab in Performance. Nominations keeps its own URL. Reach it from Open Nominations workbench at the foot of Next best actions (#overview-open-nominations), from a ranked Re-optimise → Nominations card when that leak fires, or from Desk · Commit. The workbench’s ‹ Back to Overview (#nominations-back) returns here when you arrived with ?from=overview.

Follow along. Seat: trader_1@webill.net (password supersecret). Path: Trader Pools → T1 Renewables Pool → Overview (or the scale-icon Strategy chip). You should see the subtitle Run the book — position, flow, risk, and the next trade., the intro What the book earns, where its energy goes, what could go wrong, and what to trade next., Explanations beside Run Forecast Now, then the nine cards below.

Data. full_demo · seed 42 · T1 Renewables Pool · last checked 2026-09-18 against StrategyOverviewLive. A seeded book that is long with almost no offtake headlines The book loses R 12.2 m this period because 96% of what it buys never sells. Snapshot Rand on a given machine moves with the latest forecast; the labels and rules below are the product.

The page title is Strategy · Overview. While a forecast runs, a full-screen overlay says Running forecast… and Stay on this page until the run finishes. Tabs and the back link are not clickable. Success flash: Forecast updated. Failure: Forecast run failed. or Forecast run crashed.

If there is no snapshot yet, the nine cards are hidden. You see a dashed empty panel:

No snapshot yet — run a forecast to populate coverage, margin and risk.

Under that empty panel the page still lists Supply and Demand pools by name and member count (N member(s)), or No supply pools. / No demand pools. Those columns are a roster, not health. Press Run Forecast Now (#overview-run-forecast). The button tooltip: Rerun full forecast: base P50 run plus P90 adverse stress run.

Words for this screen (no foreknowledge)

Word Plain meaning
Allocation This pool’s strategy file: pools, runs, snapshots and limits. Created the first time you open Strategy
Snapshot The sealed forecast result Overview reads. No snapshot → empty cards
P50 The expected case — about half the time generation meets or beats it
P90 The conservative generation case you are still 90% confident of getting. Always ≤ P50 for renewables
P05 / P95 Edges of the sampled margin fan (worse / better), not generation grades
Margin Sales minus buys minus forecast costs, in Rand
Margin@Risk Share of P50 margin lost in the P90 adverse case
VaR 95 Value at Risk at 95% — a tail gap on a one-day or one-month horizon
Coverage Delivered energy ÷ demanded energy
Spill Unsold supply ÷ total supply — bought or generated, no buyer that hour
Shortfall Unmet demand ÷ total demand
Take-or-pay used Share of minimum-take energy you actually used
HHI Herfindahl-Hirschman Index — 1.0 means one supplier or one buyer takes everything
kWh / MWh / GWh Energy units. 1,000 kWh = 1 MWh; 1,000 MWh = 1 GWh. Large books switch unit automatically
c/kWh Cents per kilowatt-hour
SAST South African Standard Time (UTC+2). Clock hours are SAST
Typical day Every hour in the run, averaged by SAST clock hour, then divided by the number of distinct days
Long Supply above demand that hour — spill, amber
Short Demand above supply that hour — shortfall, rose
Matched The overlap of supply and demand — green

4.0 The book as a marketplace — pools in plain language

Before the cards, you need the two sides Overview assumes. A pool is a named group of members on one side only.

Side Plain meaning Typical members
Supply Energy you can place into the book Generator sites, buy-side PPAs, trader blocks selling into you
Demand Energy the book must serve Off-taker sites, sell-side PPAs, trader blocks buying from you

You do not put factories and solar farms in the same pool. You group solar with solar when they share a job (cheap daytime energy), and factories with factories when they share a service (industrial load that should be covered first).

Where this is taught. Creating pools, priorities, limits and members is §5. This section is only the picture Overview’s flow map and Pool health table assume. The hour-by-hour matching diagrams sit with that chart (§4.4).

Four commercial moves. The engine does not invent deals. It only allocates energy inside the deals you already seated.

Move Seat it as… Do this when…
Supply sells into your demand A source in a supply pool and a sink in a demand pool You own both legs and want the engine to match them each hour
You buy from an IPP Generator site or IPP PPA → supply You need a known shape (solar midday, wind overnight, firm block)
You buy from another trader Counterparty block → supply You need volume or firmness faster than building your own IPP book
You sell to an offtaker or trader Site, sell-side PPA, or trader-sales block → demand You have surplus to place, or a firm sale to honour

Layman’s rule. Fill demand in your head first, then buy supply that matches the shape — unless you are deliberately long renewables and hunting offtake. IPP buys own shape and green attributes. Trader buys fill gaps. Offsell to offtakers is the core placement. Offsell to traders is often firm — protect it with Firm supply.


4.1 The position card — what the book earns

On screen: the left card in the first row (#overview-position). There is no folded All five KPIs row and no #overview-kpi-cards. Coverage, spill and shortfall now live on Structural position (§4.2). Margin, Margin@Risk and the spill money live here.

This is the shop-window price. One sentence, a fan if a Monte-Carlo risk run exists, then three tiles.

The headline

The heading (#overview-headline) is chosen in this order from the latest snapshot (MARGIN_R, SPILL_PCT, SHORTFALL_PCT):

When Headline you see
No margin figure No margin figure in the latest snapshot
Margin < 0 and spill > 50% The book loses {Rand} this period because {N%} of what it buys never sells
Margin < 0 and shortfall > 20% The book loses {Rand} this period while {N%} of demand goes unmet
Margin < 0, otherwise The book loses {Rand} this period
Spill > 20% The book earns {Rand} but spills {N%} of its supply
Shortfall > 20% The book earns {Rand} but leaves {N%} of demand unmet
Otherwise The book earns {Rand} this period

Rand is compact: R 412 k, R 12.2 m, −R 12.2 m. On T1 Renewables Pool after the seed forecast, expect the loses … because 96% … never sells line.

Good is earns with no “but spills” / “but leaves unmet”. Bad is loses because — you paid for energy that found no buyer.

The lede and the fan

The grey line under the headline:

The fan (#overview-margin-fan) is a horizontal bar:

Mark Meaning
P05 Worse edge of sampled margin (left label)
P50 Expected margin (centre, bold)
P95 Better edge (right label)
break-even Dashed tick at R 0, only when the fan crosses zero

Green stroke when P50 ≥ 0; rose when P50 < 0. No Monte-Carlo distribution → #overview-no-fan: No margin distribution yet — the fan appears after a Monte-Carlo risk run. The three tiles still show.

The three tiles

Tile label Number How to read it
Margin@Risk · P90 adverse MARGIN_AT_RISK_PCT, or — Share of expected margin that disappears if renewables under-deliver. Rose when the figure is above 25%
VaR 95 · one day or one month From the latest risk distribution, or — / VaR 95 · no distribution Tail gap at 95%. Prefers a one-month horizon when both exist
Margin if the spill sold at {c} c Implied resale at the book’s average sell price Only when there is spill and a sell price. Otherwise Spilled this period shows the spilled energy (or — if the run has no lines)

Margin@Risk = (P50 margin − P90 margin) ÷ P50 margin × 100. Example: P50 = R 412,000; P90 = R 298,000 → 27.7%. A fat expected margin that melts in the P90 case is a risk problem, not a success.


4.2 Structural position

On screen: the middle card in the first row (#overview-gauges). Eyebrow: Structural position.

Four bars, always in this order. There are no gauges for firm backing, price exposure, or escalation on this card — those numbers can still raise a next-best action (§4.5).

Id Label Metric Default tick if you set no limit
#overview-gauge-top-utilisation-pct Take-or-pay used TOP_UTILISATION_PCT target 80% (bad when below)
#overview-gauge-coverage-pct Coverage COVERAGE_PCT band 90–100, or the average of demand-pool coverage targets (bad when below)
#overview-gauge-spill-pct Spill SPILL_PCT max 5% (bad when above)
#overview-gauge-shortfall-pct Shortfall SHORTFALL_PCT max 5% (bad when above)

Each row is: label · bar · value. The bar fills left to right. A black tick marks the limit (labelled limit N%, target N%, or the default words above). Missing value → — and a grey bar (tone: none).

Colours on the bar

Tone Colour When
ok Brand green Inside the tick
warn Amber Close to the tick (above ~80% of an “above” limit, or below ~110% of a “below” limit)
bad Rose Past the tick
none Slate No number

Green means the metric is inside your warning threshold — not that the commercial outcome is automatically good. An amber Spill at 7.5% and an amber Shortfall at 7.5% are opposite jobs: one asks you to place midday supply, the other asks you to add supply or reshape sales.

Note. The Trader Pools directory paints rose at fixed triage cuts (§3.3). Inside the book, these bars use your risk limits (§12.6). Trust Overview for operating decisions on the open book.

Take-or-pay used (ToP utilisation): you agreed to pay for a minimum volume even if you do not take it. Low utilisation means you are paying for energy you then spill. The default “good” side is at or above 80%.

Coverage = delivered ÷ demanded. Spill = unsold supply ÷ total supply. Shortfall = unmet demand ÷ total demand. Coverage and shortfall are two views of the same gap: 82% coverage is 18% shortfall on the same numbers.


4.3 Concentration

On screen: the right card in the first row (#overview-concentration). Eyebrow: Concentration.

How much of the book sits with one supplier or one buyer. A healthy margin with one counterparty is still a single-point risk.

Supply HHI and Demand HHI are two meters. The number is the HHI from the snapshot (SUPPLY_HHI, DEMAND_HHI), shown to two decimals, or —. The bar behind the needle is green → amber → rose; the needle sits at HHI × 100% (1.00 is the far right). The note on the right names the largest pool share from this run (Solar 72%) or the hint 1.0 = one supplier / 1.0 = one buyer.

Counterparty exposure lists up to three counterparties from counterparty_breakdown, largest first, each with compact Rand and a share bar (first bar violet, the rest slate). Empty copy: No counterparty exposure in the latest snapshot.

Good is a mid-to-low HHI and a list that is not one name. Bad is 1.00 — one shelf or one basket is the whole book.


4.4 Where the energy goes

On screen: the wide card in the second row (#overview-flow). Title: Where the energy goes.

This is a flow map (a Sankey): shelves on the left, baskets on the right, ribbons between them. The intro on the card:

Supply pools on the left, demand pools on the right, ribbons sized by MWh allocated in the snapshot run and coloured by margin. Energy that finds no buyer leaves as spill; unmet demand leaves as shortfall.

Read it in this order

  1. Find left and right. Left nodes are supply pools (Solar, Wind, Flexible, Firm — coloured by type). Right nodes are demand pools (Industrial, Commercial, Municipal, Trader Sales — slate). If two pools share a name, the map adds (supply) or (demand).

  2. Read ribbon thickness. Thickness is MWh allocated in the snapshot run (kWh sent ÷ 1,000). A fat ribbon is a big path; a hairline is a small one.

  3. Read ribbon colour against the legend on the card:

    Legend swatch Meaning
    Positive-margin flow Green — sold above what it cost
    Negative-margin flow Rose — bought dearer than it sold
    Spill (bought, unsold) Amber — paid-for energy with no buyer
    Shortfall Rose outline — unmet demand
  4. Hover a ribbon (when the chart has loaded). The label is compact Rand and margin in c/kWh, or bought, never sold / unmet.

  5. Find the two outlets. Spill · bought, unsold sits as an extra node: supply ribbons that leave the book unused. Shortfall · unmet demand feeds into demand pools that were not fully served.

  6. Read the footer totals (only when there are ribbons): Supply {energy} · Demand {energy}; if spill > 0, bold amber Spill {energy} ({N%}) · {Rand}; if shortfall > 0, bold rose Shortfall {energy} ({N%}).

Empty copy (#overview-flow-empty): No allocation lines in the latest run yet — the flow map fills in after a forecast with seated members.

Good is mostly green ribbons, thin or missing spill and shortfall outlets. Bad is a fat amber river into Spill — that is the same story as a loses because N% never sells headline.

4.4.1 How the sides interact each hour

For each forecast hour the engine roughly does this:

  1. Gather available energy in ACTIVE supply members (after caps, nominations, forecasts).
  2. Gather requirements in ACTIVE demand members.
  3. Serve firm demand from firm-capable supply first.
  4. Walk remaining open demand in pool priority, drawing from the supply merit stack.
  5. Leftover supply is spill; leftover demand is shortfall.

The flow map is those lines summed for the whole snapshot window. Hour-level proof lives in run detail (§8). Priorities and defaults are §5.1.

4.4.2 Worked example A — midday: sell renewables into offtake

Provenance. Illustrative hour, same conventions as full_demo trader books (c/kWh, MWh). Network losses ignored so the matching arithmetic stays visible.

Situation. 12:00 SAST. Solar has IPP energy. Industrial has factory load. Flexible holds a small trader-in block.

Side Pool Member Available / need Buy or sell
Supply Solar IPP-A 6 MWh buy 65 c/kWh
Supply Solar IPP-B 4 MWh buy 70 c/kWh
Supply Flexible Trader-in 2 MWh buy 80 c/kWh
Demand Industrial Factory C 8 MWh need sell 120 c/kWh
Demand Commercial Mall D 3 MWh need sell 115 c/kWh

Matching (open demand, no firm this hour)

  1. Industrial takes 6 MWh from IPP-A and 2 MWh from IPP-B.
  2. Commercial takes IPP-B’s remaining 2 MWh and 1 MWh from the trader-in block.
  3. Flexible still holds 1 MWh → spill.

Conservation. Supply offered 6 + 4 + 2 = 12 MWh. Demand served 8 + 3 = 11 MWh. Spill 12 − 11 = 1 MWh ✓.

On the flow map you would see a thick Solar → Industrial ribbon, a thinner Solar → Commercial ribbon, a thin Flexible → Commercial ribbon, and an amber Flexible → Spill · bought, unsold outlet.

Midday hour — what the flow map is adding up (MWh)
Open hour Serve Industrial, then Commercial
Solar · IPP-A · 65c 6 MWh
Solar · IPP-B · 70c 4 MWh
Flexible · trader-in · 80c 2 MWh
1 · Industrial8 / 8 MWh
6 IPP-A 2 IPP-B
2 · Commercial3 / 3 MWh
2 IPP-B 1 trader-in
Solar IPP Trader-in / flexible Spill (1 MWh left on Flexible)

4.4.3 Worked example B — evening: firm offtake and trader offsell

Provenance. Same illustrative book, 19:00 SAST.

Situation. Solar is dark. You still owe a firm evening sale to another trader. Industrial is still running.

Side Pool Member Available / need Notes
Supply Firm Dispatchable block 4 MWh reserved for firm
Supply Wind Wind PPA 3 MWh open merit
Demand Trader Sales Trader-out block 3 MWh firm must be served
Demand Industrial Factory C 5 MWh open after firm

Matching

  1. Firm first: Trader Sales takes 3 MWh from Firm. Remainder 4 − 3 = 1 MWh.
  2. Open: Industrial takes 3 MWh Wind + 1 MWh Firm remainder = 4 MWh served.
  3. Industrial still needs 1 MWh → shortfall.

Conservation. Supply 4 + 3 = 7 MWh. Demand need 3 + 5 = 8 MWh. Served 3 + 4 = 7 MWh; shortfall 1; spill 0 ✓.

On the flow map: Firm → Trader Sales, Wind → Industrial, a thin Firm → Industrial remainder, and a rose Shortfall · unmet demand → Industrial inlet. Buying more solar would not fix 19:00.

Evening hour — protect firm, then industrial (MWh)
Stage 1 Protect firm demand
Firm supply 4 MWh
Trader Sales · firm 3 MWh served
Firm remainder 1 MWh
Stage 2 Open industrial demand
Wind 3 MWh
Firm remainder 1 MWh
Industrial4 / 5 MWh
3 Wind 1 Firm 1 short
Wind Firm Shortfall

4.5 Next best actions · ranked by rand at stake

On screen: the card beside the flow map (#overview-actions). Title: Next best actions · ranked by rand at stake. A pill shows {N} open.

The panel converts common symptoms into a first move, sorted by Rand at stake (highest first). Rank 1 has an amber surround; the rest are white. Each card has a rank disc, a title, a why, an impact pill, and a deep link.

Empty copy (#overview-actions-empty): Nothing pressing — coverage, spill and assignment all look healthy.

The footer links are always there: Open Simulation Workbench → /strategy/simulations (the Commercial tab) and Open Nominations workbench (#overview-open-nominations) → /strategy/nominations?from=overview. The workbench then offers ‹ Back to Overview.

Condition (what the engine checks) Typical title Link label → URL
Spill > 5% Sell the spill: {energy} has no buyer (or Supply is spilling {N%} — add daytime offtake…) Find offtake → Simulations /simulations
Shortfall > 5% Cover the shortfall: {energy} of demand unmet (or Demand shortfall {N%} — add supply or firm cover) Find supply → Simulations
Take-or-pay used < 80% Stop paying for take-or-pay energy you spill Re-optimise → Nominations /nominations
Any allocation leg with negative margin Cut the loss-making {source} → {target} leg See the leg → Allocations /allocations
Firm backing < 1.0× Firm sales exceed firm capacity ({N}×) Review firm pool → Pools /pools
Indexed volume above the price-exposure limit (default 25%) Hedge the {N%} indexed volume Set limits → Dashboard /dashboard
Active contracts not in any pool {N} active contract(s) not in any pool Assign → Pools
Battery ≥ 1.2 cycles/day Battery at {n} cycles/day — near the warranty cap Open BESS /bess (§11.11)
Nomination tolerance breached in > 10% of hours Nominations breach tolerance in {N%} of hours Re-optimise → Nominations

Impact pills show compact Rand when the engine can price the stake (≈ R 12.2 m), otherwise a plain tag (hygiene, deadline, warranty, structural breach).

An action labelled “add daytime offtake” is a shape hypothesis. Open the Desk, inspect the fit, and test terms before you create a proposal (§9).


4.6 Long or short, hour by hour

On screen: the full-width card (#overview-clock). Title: Long or short, hour by hour.

This is not a separate “Next Best Actions Long or Short” card. Long and short are the clock. The actions card is §4.5.

The intro on the card:

Net position on a typical day of the run: matched energy in green, supply above demand is long (spill, amber), demand above supply is short (shortfall, rose). The solid line is demand; the dashed line is tomorrow’s P50 supply from the suppliers’ weather forecasts.

The period toggle

#overview-clock-period is two buttons, not a URL:

Button What it plots
Typical day ({from} – {to} · {N} days) The run’s hours averaged by SAST clock hour, then divided by the number of distinct days. Default
Tomorrow (P50 supply) Same demand line; stacks rebuilt from tomorrow’s weather P50 across up to three seated supply generators

Tomorrow is disabled, at half opacity, with tooltip No supplier weather forecast for tomorrow yet until that extra load arrives. While it loads you may see loading supplier forecast….

How to read Typical day

  1. Daylight / Night wash. The legend (#overview-clock-day-night-legend) marks Daylight (06:30–17:30) (sun, amber wash) and Night (moon, grey wash). Hours are SAST.
  2. Three stacks, bottom to top in the legend: Matched (green #059669), Long (spill) (amber #f59e0b), Short (shortfall) (rose #e11d48).
  3. Solid slate line = Demand (allocated delivered + shortfall that hour, typical-day average).
  4. Dashed slate line = P50 supply (tomorrow) when weather exists — overlaid on Typical day so you can compare today’s shape with tomorrow’s expected supply. It does not replace the stacks until you press Tomorrow.
  5. Plant now (#trader-plant-chips) sits under that legend, above the chart. Each chip names the IPP site and the last sample time. Press it and Your plant live opens as a scrollable modal on this Overview (#overview-plant-live-modal) — it does not send you to /org/generator-sites/…/strategy/plant. Use it to check the live reading against the P50 tomorrow line. Absent when no seated supplier has a live feed; that is normal.
  6. Clip strip (#overview-clip-strip) under the chart: 24 cells, 0h → 23h. Caption: Clip strip · amber = long, the bid desk would clamp · rose = short. Hover a cell: {hh} · long {energy} · short {energy} per typical day. Darker amber means a fatter long hour (the top third of the day’s long peak). Slate means matched with no leftover.

Good on Typical day: a green matched band that follows the demand line, thin amber only at solar noon if you are slightly long, little or no rose. Bad: a tall amber plateau (you bought a shape nobody takes) or a rose evening block (you sold evenings you cannot cover).

How to read Tomorrow (P50 supply)

Press Tomorrow (P50 supply). The stacks are rebuilt as:

The demand line stays. The dashed P50 line is not drawn again (it is the stack). Use this to ask: if tomorrow’s weather is the P50 we already have, do I still spill at noon or go short at 19:00?

If the button stays disabled, you have no supplier weather yet — stay on Typical day.


4.7 Pool health

On screen: the wide card in the last row (#overview-pool-health). Title: Pool health. Intro: Each pool against its own targets: coverage band, spill and shortfall caps, and its share of the margin.

This is a table, not the old locator “pool cards”. Two section rows — SUPPLY then DEMAND — then one data row per pool (#overview-pool-{id}). Empty section: No supply pools. / No demand pools.

Every table header

Header What it shows
Pool Type icon, name, then a grey line: {N} member(s) and, on a firm supply pool, · firm
MWh Energy in the snapshot for that pool (auto kWh / MWh / GWh), or — if none
Coverage vs band Demand only. A bar: green wash is the pool’s coverage band; the dark fill is where coverage sits. Supply rows show —
Spill / short Supply: {N%} spill. Demand: {N%} short (or 0% short / —). Rose when supply spill > 20% or demand short > 5%
Margin Compact Rand, right-aligned. Green if positive, rose if negative
(last column, no title) Status chip: ok · warn · breach · idle

How to read a supply row

MWh is allocated sent + spill for that pool. Coverage vs band is blank — supply has no coverage target. Spill / short is the spill share of that pool’s own energy. Chips:

Chip When
idle No energy in the snapshot
breach Spill % above this pool’s max spill cap
warn Spill % above 20% (even if under the cap)
ok Otherwise

High Solar spill usually means missing daytime demand, not “too much solar forever”.

How to read a demand row

MWh is delivered + unmet. Coverage vs band compares snapshot coverage to the pool’s min–max band (or target ± 10 points, or 90–100). The green wash is the band; the fill is the value (capped at 100% on the bar). Spill / short is the unmet share.

Chip When
idle No coverage figure
breach Shortfall % above this pool’s max shortfall cap
warn Coverage below the band minimum
ok Otherwise

Industrial below its band and Trader Sales at 100% are different jobs. Firm shortfall is rarely acceptable.

The row is a locator, not an editor. Change members and rules on Book · Rules (§5); return here after a new forecast.

How one snapshot window must add up — illustrative midday book
Side Pool MWh in Placed / served Spill / short
Supply Solar 10 10 0
Supply Flexible 2 1 1 spill
Demand Industrial 8 need 8 0
Demand Commercial 3 need 3 0
Conservation 12 offered 11 served 1 spill ✓

Supply offered equals served plus spill. Demand need equals served plus shortfall. The flow map and Pool health are two views of the same lines.


4.8 Where the margin is made and lost

On screen: the upper right card in the last row (#overview-heatmap). Title: Where the margin is made and lost. Intro: Month × hour margin from the run’s allocation lines. Green earns, red loses.

A heatmap (#overview-margin-heatmap): columns are months in the run (labels like Oct. '25), rows are SAST clock hours (0h … 23h). Each cell is the sum of margin_r for that month-hour. The colour scale is centred on zero: green earns, red loses, the ends are equal in size so a big win and a big loss are comparable.

Empty copy: No priced lines in the latest run yet.

How to read it. Find the red cells first — those hours lose money. A red evening column every month is a shape problem (firm sales after solar). A red summer-noon column with a green winter-noon is a seasonal spill story. Then open Book · Forecast or Allocations when you need the lines behind a cell. This card does not edit prices.


4.9 Forecast said, book settled

On screen: under the heatmap (#overview-drift). Title: Forecast said, book settled. Intro on the card:

P50 margin at forecast time against the settled trader book, last 6 months. The gap is forecast error you are paying for.

A weather forecast says it will rain. The wet pavement — or the dry one — is what actually happened. This card is that pair, for money.

Forecast P50 is the plan: what the latest P50 (expected-case) risk snapshot said this book would earn that month. Settled book is the receipt: what settlement actually wrote on the trader statement — or, if no buy and sell legs have settled yet, that month’s ACTUAL snapshot.

The chart (#overview-drift-chart) plots both on one pair of axes for the last six calendar months, including this month.

This card does not sign a deal. It does not re-run the forecast. It only asks: has the plan been honest?

Follow along. Seat: trader_1@webill.net (password supersecret). Path: Trader Pools → T1 Renewables Pool → Overview, then scroll under Where the margin is made and lost. You should see #overview-drift, then either Loading settled months…, the two-line chart, or the empty copy below.

Data. full_demo · seed 42 · T1 Renewables Pool · last checked 2026-09-18 against StrategyOverviewLive. Snapshot Rand moves with the latest forecast. The two teaching charts below use the same month labels and compact Rand the card prints. A seeded book that is long may show a large gap, or No month has both a forecast and a settled statement yet. The labels and rules are the product.

Where this is taught. The month’s buy and sell legs behind Settled book: §6A. How a snapshot is sealed: §4.10. The IPP card Forecast said, settlement did is a different screen — last month’s buyer carve, not this book’s margin (V4 §8.1.8).

Words on this card

Word Plain meaning
Forecast P50 The green line. Expected-case monthly margin from the latest FORECAST snapshot in that month (MARGIN_R)
Settled book The sky-blue line. Net margin on the consolidated trader statement when buy and sell legs exist; otherwise that month’s ACTUAL snapshot
Gap Settled minus forecast, in Rand. The verdict averages this over months that have both numbers
R South African Rand. The Y axis. Up is more profit (or a smaller loss). Below R 0 is a loss
Last 6 months Six month ticks on X, oldest on the left, this month on the right. Labels look like Apr. '26

The gap is error, not a bill on its own. Settled below forecast means you planned on money you did not get. Settled above forecast means you earned more than the plan — still a miss, but a happy one.

How to read the chart

  1. Find the legend under the plot. Two names: Forecast P50 and Settled book.

  2. Read the colours (Overview uses the shared line palette). Forecast P50 is first — brand green #059669. Settled book is second — sky #0ea5e9.

  3. Read left to right. Each tick is one calendar month. Hover a month to see both Rand figures.

  4. Ignore one line alone. A falling settled line is only a problem relative to the forecast. Two lines that fall together mean the plan saw the drop.

  5. Look at the gap. Do the lines travel together, or does one wander off? Does the space grow as you walk toward this month?

  6. Read the verdict under the chart, once extras have loaded:

    Verdict When
    Settled margin runs {Rand} below forecast on average over {N} month(s). Average gap is negative — the plan was optimistic
    Settled margin runs {Rand} above forecast on average over {N} month(s). Average gap is positive — the plan was pessimistic
    No month has both a forecast and a settled statement yet. Lines may exist, but no month has a pair, so there is no average

A missing dot in one series is normal. That month has a forecast or a settlement, not both. The verdict ignores it.

Loading (page just connected): Loading settled months… — the chart is a slow extra. Wait. Empty (#overview-no-drift): No forecast snapshots or settled statements in the last 6 months yet. Press Run Forecast Now, or wait until a month has settled.

A good chart — the forecast was honest

A good chart is not “the book earned a lot.” It is “the plan and the receipt stay close.” Small gaps that flip sign (a little above, a little below) are weather noise. The gap does not grow.

Two teaching charts for the same six months (Apr. ’26 – Sep. ’26). Green = Forecast P50. Sky = Settled book. Illustrative monthly Rand, same compact style as the card.
Forecast P50 Settled book

Good — lines travel together

Honest forecast: two lines stay close Forecast P50 and settled book track within about R 15 k each month from April to September. R 500 k R 250 k R 0 AprMayJunJulAugSep

Why it is good: the sky receipt hugs the green plan. Gaps flip sign. Nothing grows. Verdict would read about R 3 k below — noise, not a lie.

Bad — one-way miss, growing gap

Optimistic forecast: settled falls away Forecast P50 stays near R 400 k while settled book falls from R 80 k through zero to a R 200 k loss. R 500 k R 125 k R 0 −R 250 k AprMayJunJulAugSep

Why it is bad: the green plan stays high. The sky receipt falls, crosses R 0, and keeps dropping. The miss is one-way. The gap grows. You are paying for optimism.

Numbers behind the good chart — gap = settled − forecast
Month Forecast P50 Settled book Gap
Apr. ’26 R 380 k R 365 k − R 15 k
May. ’26 R 400 k R 412 k
  • R 12 k
Jun. ’26 R 390 k R 378 k − R 12 k
Jul. ’26 R 410 k R 405 k − R 5 k
Aug. ’26 R 420 k R 428 k
  • R 8 k
Sep. ’26 R 400 k R 394 k − R 6 k
Average gap (the verdict) − R 3 k ✓

Six small misses that change sign. The plan was honest. Trust the P50 headline for the next look-ahead — then still read spill and shortfall on the other cards.

Numbers behind the bad chart — same months, one-way miss
Month Forecast P50 Settled book Gap
Apr. ’26 R 410 k R 80 k − R 330 k
May. ’26 R 420 k R 40 k − R 380 k
Jun. ’26 R 400 k − R 20 k − R 420 k
Jul. ’26 R 430 k − R 80 k − R 510 k
Aug. ’26 R 450 k − R 150 k − R 600 k
Sep. ’26 R 440 k − R 200 k − R 640 k
Average gap (the verdict) − R 480 k

Every month settled below the plan, and the hole got bigger. That is the sentence Settled margin runs R 480 k below forecast on average over 6 month(s). Do not treat the green line as cash.

Why the good one is good. The weather report was close to the pavement. A May beat and an April miss cancel. You can use the headline on §4.1 as a planning number.

Why the bad one is bad. The report kept promising rain. The pavement stayed dry — then the book crossed R 0 and kept losing. A common cause on a long trader book: the forecast still prices offtake you have not seated, so P50 margin stays fat while the ledger records spill. T1 Renewables Pool’s loses because N% never sells headline is that story in one sentence. This chart is the six-month proof.

What to do next

What you see Do this Do not
Good — lines track, verdict a few thousand either way Keep using the P50 headline. Read spill and shortfall as usual. No extra trade from this card Do not skip the other eight cards. An honest forecast can still describe a book that spills
Bad — settled below, month after month, gap growing Open Book · Outcomes for a settled month (§6A). Check Book · Rules if the forecast prices energy that never settles. Fix members, then §4.10 Do not add sales that need the “air” megawatt-hours on the green line. Do not treat the headline as cash in the bank
Settled above — happy miss Find the extra offtake or cheaper buy before you scale the book on luck. The plan was still wrong Do not assume next month will beat the plan again
Empty / no paired months Run a forecast. Wait for a month to settle. Come back Do not invent a verdict from one line

Book · Outcomes draws a cousin of this chart for the same six months. Dashboard keeps the long view (§12).


4.10 What happens when you run (or re-run) the forecast

Run Forecast Now (#overview-run-forecast) is the on-demand twin of the nightly strategy cycle for this book. It asks the engine:

Given everything seated on this book today — members, prices, caps, rules, forecast shapes, network losses, and the battery if you have one — what does the next year look like in the expected case, and how much of that margin melts away if renewables under-deliver?

The answer is frozen as a risk snapshot. Overview, Dashboard, and the directory chips all read that snapshot. No snapshot → the empty panel in the chapter open. A successful press replaces today’s snapshot for this book.

Same cycle, two triggers. Nightly (about 02:30 SAST, every active book) and Run Forecast Now (this book, now) both call the Margin-at-Risk pass: P50 base + P90 adverse + snapshot. The nightly rhythm is V3 §18.3.

The Book · Rules amber banner Forecast is behind this board is taught in §5.6. A simulation in Commercial is not a forecast re-run (§9).

4.10.1 When you should press it — and when you should not

Situation Press Run Forecast Now? Why
First open / empty Overview Yes Cards cannot light without a snapshot
Pools shows Forecast is behind this board Yes The last seal describes the old book
You changed members, priorities, caps, rules, limits, or BESS Yes The snapshot is stale
You only opened Dashboard to browse No Reading does not change inputs
You are mid-edit with half-built members Wait You would freeze a half-built book
Nightly finished an hour ago and nothing changed Optional Harmless, usually unnecessary

4.10.2 The pass in seven steps

No conveyor-belt diagram — the order is the list.

  1. Window. Today → a rolling 12-month half-open window. Example: press on 23 Jul 2026 → [2026-07-23, 2027-07-23). Each hour is its own match (§4.4.1).
  2. Inputs. Freeze active pools and members, prices and caps, forecast grade, network edges, battery, period. Fingerprint: inputs hash. Same hash → same lines.
  3. P50 pass. Allocate every hour (firm first, then open priority; tag SPILL / SHORTFALL; optional battery pass). Store a FORECAST / P50 run. This becomes the current forecast position.
  4. P90 pass. Same period; every renewable member swaps to P90. Tagged SIMULATION / P90 so it never becomes “the” current forecast.
  5. Margin-at-Risk. MaR (R) = P50 margin − P90 margin; MaR (%) = MaR (R) ÷ P50 margin × 100. That percentage is the Margin@Risk · P90 adverse tile.
  6. Snapshot. One dated row: portfolio metrics, per-pool breakdown, breaches against active limits.
  7. Screens. Overview reloads the nine cards. Dashboard reads the same snapshot. The previous equivalent FORECAST run is marked superseded only after this press completes.

While the overlay is up, keep treating the previous snapshot as the decision record. Only Forecast updated. means steps 1–7 finished.

4.10.3 P50 and P90 in plain language

Renewable forecasts are graded by exceedance:

Grade Plain reading For generation
P50 In a typical year you expect about this much The median / expected case
P90 You are 90% confident of getting at least this much Always ≤ P50 — the conservative case
P10 You only get this much or more in a lucky 10% of years Optimistic (rarely used on this button)

Common mix-up. “P90” is not “ninety percent — a lot.” It is the low case you are still confident of clearing. P90 ≤ P50 ≤ P10 for generation.

Toy plant: declared P50 = 43,800 MWh/yr, solar-like P90/P50 = 0.94 → P90 ≈ 41,172 MWh/yr. On a book, the adverse pass shrinks every renewable hourly shape, then re-matches the whole marketplace. Firm supply is not shrunk the same way.

Snapshot the Overview actually shows

Illustrative trader book on 1 Aug 2026 (rounded whole Rand):

MARGIN_R              = 412 000        ← from P50 run
MARGIN_AT_RISK_PCT    = 27.7           ← (412k − 298k) ÷ 412k × 100
COVERAGE_PCT          = 82.0
SPILL_PCT             = 9.3
SHORTFALL_PCT         = 1.8
pool_breakdown[Industrial].COVERAGE_PCT = 75.0
breaches = [ MARGIN_AT_RISK_PCT warn if limit warn=25 ]

On T1 Renewables Pool after the seed, expect the opposite commercial shape: a loses R 12.2 m headline and spill near 96% — same cards, different numbers.

4.10.4 Re-run vs first run

Object First successful press Second press the same day If the press fails
P50 FORECAST run Created; becomes current New current; prior superseded Prior current unchanged
P90 SIMULATION run Created for MaR only New adverse companion Prior left alone
Risk snapshot for today Created Replaced Prior snapshot still shown
Simulations / nominations Untouched Untouched Untouched

Press twice with no book changes: new run ids, same inputs hash and KPI values. Press after seating a priced PPA: hash, Margin and often MaR move.

4.10.5 Operator checklist

  1. Finish the structural change on Book · Rules, the battery or limits.
  2. Press Run Forecast Now here or on the Pools banner.
  3. Stay on the page while the overlay is up.
  4. When Forecast updated. appears, read the headline and rose gauges first, then rank 1.

Follow the lines. Allocation mechanics: §7. Runs list: §6. Dashboard: §12.


4.11 Explanations and other chrome

Explanations (#overview-explanations-open) opens a right-hand drawer (#overview-explanations-drawer). Eyebrow: Trader Overview. Title: Explanations. Above the terms sits How to Read the View (#overview-how-to-read) — collapsed until you press #overview-how-to-read-toggle. It is the short in-product reading order: position, structural position, concentration, energy flow, actions, hour-by-hour, pool health, margin heatmap, forecast versus settled. Intro: Abbreviations and terms used on the trader-pool Overview, in alphabetic order. Close with the X (#overview-explanations-drawer-close), the backdrop, or Escape. The list is A–Z from BESS (Battery Energy Storage System) through VaR 95 (Value at Risk). It does not include SAWEM — that word is not on this Overview (it lives on the Bid Desk).

Plant now chips (#trader-plant-chips) sit under the Long or short legend, above the chart — not above the intro. They appear only when a seated supplier has a live telemetry feed. Each chip shows the IPP site name and last sample time. Press the chip: Your plant live opens as a scrollable modal (#overview-plant-live-modal, branded header, site name as the title). Close with the X (#overview-plant-live-close), the backdrop, or Escape. You stay in Performance. Absent on a book with no live feeds — that is normal, not an error.

Busy overlay (#strategy-busy-overlay): Running forecast… / Stay on this page until the run finishes.

This is the morning pattern: Overview detects, Book / Desk / Dashboard change, a fresh snapshot confirms. Keep the two-sided picture from §4.0 when Pool health points at Solar spill versus Industrial shortfall — those are opposite shelves.

Where this is taught next. Book has its own Explanations drawer with a different How to Read for Rules, Forecast and Outcomes (§5.8, §6.8, §6A.4).

5. Book · Rules — how the book is wired

Route: …/strategy/book opens here (…/strategy/pools) · Tab: Book (#strategy-tab-book stays active) · Mode: Rules (#book-stage-rules on the thread strip; Outcomes and Forecast are the other stages, not extra #strategy-nav tabs.)

What it is for. Pools are how you tell the engine what your book is. A pool is a named group of members on one side — supply (sources) or demand (sinks) — with a stated purpose, a priority, and side-specific limits. The engine only sees ACTIVE pools; a PPA that isn't a member of any pool doesn't exist as far as allocation is concerned.

Where the marketplace picture is taught. Why supply and demand pools exist, when you buy from an IPP vs another trader, and when you offsell to an offtaker vs a trader — with midday and evening worked examples — is §4.0; the hour diagrams sit with the Overview flow map (§4.4). This chapter is the build and edit screen: create pools, seat members, set priorities and rules.

Why pools at all, instead of just a list of contracts? Because allocation decisions are made between groups: solar as a class serves daytime load first; firm supply as a class is reserved for firm obligations; spill from renewables is routed to the flexible pool for tactical use. Pools carry those group-level policies (priorities, spill destinations, coverage targets, rules) so you never have to encode strategy contract by contract.

The Book’s thread, and what this mode adds to the board

Allocation on the strategy row opens Rules. The top underline (#strategy-nav) stays Operations · Performance · Allocation · Commercial · Dashboard — Allocation stays lit. Rules, Forecast and Outcomes switch on the thread strip under that bar, not as extra room tabs.

Every Book view still opens with the same thread strip: three stages — Rules · how the book is wired → Forecast · what the engine will do → Outcomes · what actually settled — each with a verdict pill (on the demo: 4 caps breached → September P50 · −R 12.2 m · spill 95.8 % → August · −R 381 k · not balanced). Clicking a stage opens that view. Under it the issues rail ranks everything wrong in the book — caps breached, a month that does not balance, a nominated run still running, a failed run, coverage outside its band, draft pools with no members — and each item points at the mode that fixes it.

Then the mode’s headline, written from the numbers: “The cascade sells into 4 demand pools in priority order — and supply outweighs what they can take 24 to 1. Whatever Solar, Wind, Flexible and Firm bring past 4 % will spill.”

The board itself is two columns with a wiring gutter between them. SUPPLY pools sit left in merit order, DEMAND pools right in priority order. Three things are new on the cards:

There is no three-card “next moves” strip under the board. Reorder supply on the left column; coverage bands live on the demand-card badges; spill and shortfall are on the issues rail. When the latest forecast leaves more than 20 % of supply unsold, a single line (#book-offtake-cta) offers Find offtake → Desk — the same Desk door Overview already ranks under Next best actions.

Everything else on this board — creating pools, seating members, rules, book rates, the unassigned-contracts strip and the amber Forecast is behind this board banner — is unchanged and taught below.

Above the board:

5.1 Creating pools — and what the defaults mean

One-hour allocation flow (MWh)
Stage 1 Protect firm demand
Firm supply · P40 4 MWh
Trader Sales · firm 3 MWh served
Firm remainder 1 MWh
Stage 2 Walk open demand by priority
Solar A · P10 · 65c 6 MWh
Solar B · P10 · 70c 4 MWh
Wind · P20 5 MWh
Firm remainder · last 1 MWh
1 · Industrial8 / 8 MWh
6 Solar A 2 Solar B
2 · Commercial5 / 5 MWh
2 Solar B 3 Wind
3 · Municipal3 / 5 MWh
2 Wind 1 Firm 2 short
Solar Wind Firm Shortfall

The result is auditable: firm demand was protected first, open demand followed its priority queue, and each demand drew from the highest-priority (lowest-numbered) eligible supply before more precious Firm energy was released. Within Solar, the cheaper Solar A energy cleared before Solar B.

New pool — fields always on the form

Field What it represents Sample input Why you enter it
Name The human label on the pool card, board, and run detail Rooftop Solar West So operators can tell this shelf/basket apart from others of the same type
Side Whether the pool is a supply source stack or a demand sink Supply Chooses which Type list and which limit fields appear; the engine never mixes sides
Type The commercial archetype (or Custom) for this pool Solar (supply) or Industrial (demand) Drives default member class, type suggestions for limits, and how the board icons the card
Purpose Free-text statement of what this pool is for Cheap daytime PV; spill-tolerant daytime shelf Governance: activation refuses an empty purpose — every ACTIVE pool must say why it exists
Default priority Integer order for this pool in the hour's walk (1–100). Lower runs first 10 Puts this pool ahead of or behind siblings (seeded Solar is 10; a late tactical pool often stays at 100)
Match policy How strictly members must match Accepted member classes Strict Strict = only fitting classes are offered; Approved override = you may seat a mismatch on purpose and keep the rule for audit
Accepted member classes Which strategy classes may join this pool (checkboxes) Tick Solar only Stops a wind PPA or industrial offtaker landing on the wrong shelf; under Strict, the add-member search hides incompatible subjects

The priority strip under Default priority lists other pools on the same side so you can pick a number that slots correctly (e.g. between Solar 10 and Wind 20).

New pool — supply-only fields

Shown when Side = Supply.

Field What it represents Sample input Why you enter it
Max spill % Largest share of this pool's supply that may remain unsold before risk tooling should flag it 15 (Solar archetype) Sets your spill tolerance for Dashboard / Overview alerts — it does not cap generation; every unsold MWh is still recorded as spill
Spill destination pool Optional other supply pool that receives routed spill for tracking Flexible Pool Makes unsold Solar/Wind energy visible where you might nominate, sell, or charge a battery — routing alone does not create revenue

Sample story. Solar produces 100 MWh; 82 MWh are allocated → spill = 18%. With Max spill 15%, the book flags a breach. If Spill destination = Flexible, those 18 MWh appear on Flexible for follow-up while still unsold.

New pool — demand-only fields

Shown when Side = Demand.

Field What it represents Sample input Why you enter it
Coverage target % Operating aim: delivered energy ÷ demanded energy for this pool 75 (Industrial archetype) The headline "did we cover this basket?" target in Performance pool cards and risk snapshots
Coverage min % Lower edge of the acceptable coverage band 70 Below this → under-coverage risk (you are leaving too much load uncovered)
Coverage max % Upper edge of the acceptable coverage band 90 Above this → over-procurement risk (you are covering more heavily than policy allows)
Max shortfall % Largest share of demand that may remain unmet before a flag 5 (Industrial) or 10 (Commercial) Separate shortfall tolerance from the coverage band — unmet MWh can breach shortfall even when coverage looks "close"
Firm Toggle: treat this demand as a firm obligation Unticked for Industrial; ticked for Trader Sales Firm demand is served from FIRM supply before open demand; firm shortfalls price at the member's grid top-up (§7.2)

Sample story. Industrial demand 100 MWh, delivered 65 MWh → coverage 65% (below min 70%) and shortfall 35% (above max shortfall 5%) — both risk conditions fire. These percentages are measurement and alert settings; they do not change the allocator's hourly priority walk.

Required to activate later. After save the pool is DRAFT. Activation still needs purpose, at least one member, and the side's key limit (Max spill % on supply, Coverage target % on demand) — see the card actions in §5.2.

Type suggestions on New pool

When you create a pool by hand, you do not have to invent the risk numbers. Choosing a known Type on + New pool prefills the same archetype limits that Seed default pools uses (the tables at the top of this section). A green hint under Type summarises what was filled.

Side Type examples Fields that are suggested
Supply Solar, Wind, Flexible, Firm Max spill %, purpose, default priority
Demand Industrial, Commercial, Municipal, Trader Sales Coverage target / min / max %, Max shortfall %, purpose, default priority (and Firm on Trader Sales)
Either Custom Nothing — leave limits blank until you set a policy

Worked example — New Solar pool. Side = Supply, Type = Solar → the form fills Max spill 15%, priority 10, and purpose "Cheap daytime energy; spill-tolerant." The hint reads roughly: Suggested for Solar: max spill 15%, priority 10. Editable — change any value to override.

Worked example — New Industrial pool. Side = Demand, Type = Industrial → Coverage target 75%, band 70–90%, max shortfall 5%, priority 10.

Override rules (so suggestions stay helpful, not sticky)

  1. Suggestions run only on New pool, never when you Edit an existing pool (your saved limits stay put).
  2. Edit any suggested field and that value is yours — changing Type later will not overwrite a field you already customised.
  3. If you leave a field on the previous type's suggestion (or still blank / priority still 100), switching Type replaces it with the new archetype.
  4. Custom clears the green hint and does not invent numbers; keep or clear prior values yourself.

Use Seed default pools when you want all eight archetypes at once. Use + New pool + Type suggestions when you only need one more shelf or basket (for example a second Solar-shaped CUSTOM is still blank — pick Solar if you want Solar's spill tolerance).

How to set the supply-side spill fields.

Max spill % is the largest share of a supply pool's energy that may remain unsold before the dashboard flags it. It is a risk tolerance, not a cap on generation: the engine still records every unsold MWh as spill.

Spill destination pool is the pool where that spill is routed for tracking and tactical follow-up. It does not make the energy sold or create revenue; it gives the operator a clear place to see energy that could be nominated, sold, or used to charge a battery.

Example — Solar Pool. A solar pool produces 100 MWh in a period and the engine allocates 82 MWh. Its spill is (100 − 82) ÷ 100 = 18%. If Max spill % is 15%, the 18% result breaches the pool's tolerance. If its spill destination is Flexible Pool, the 18 MWh is shown there for follow-up; it is still unsold energy until an actual commercial or battery action uses it.

How to set the demand-side coverage and shortfall fields.

Coverage target % is the operating aim for the share of demand that the book should deliver. Coverage min % and Coverage max % form the acceptable band around that aim: below the minimum is under-coverage risk; above the maximum signals over-procurement risk. Max shortfall % is a separate limit on unmet demand. These are dashboard and risk thresholds; they do not change the engine's hourly priority walk.

Example — Industrial Pool. Set a coverage target of 80%, an acceptable band of 70–90%, and a maximum shortfall of 30%. For 100 MWh of demand:

Choose the target, band and shortfall limit together so they express one coherent commercial policy for the pool.

5.2 The pool card

Each card shows the pool's type icon, status badge (DRAFT / ACTIVE / ARCHIVED), purpose, side-specific figures (supply: spill ≤ X%; demand: target X% and a 🔒 firm badge), member count and its member list (each with its priority and a remove ×). Every member line starts with the organisation that owns that site or trader block, then the site or pool name, as Organisation · Site (the same pattern as Deal Room counterparties). A contract-only member (saved with physical_ppa_id) still resolves to that counterparty organisation and site or pool. Card actions:

The operational summary also shows the pool's priority. Lower numbers are called first in the allocation stack; 100 is last. The Member compatibility panel shows the accepted member-class chips (for example, Solar, Firm or Industrial) and the match policy configured in the pool form (§5.1): Strict means a member must share at least one accepted class to be offered or added; Approved override permits an intentional exception while retaining the configured classes as the pool's commercial rule. Use the panel to check the admission rule before adding a member (§5.3).

Reorder members from the card. The member list is grouped into priority tiers, with the lowest priority shown first. Within a shared priority tier, members are shown by ascending pro-rata weight; members with a blank weight (which use contracted volume) follow the explicit weights. This makes the allocation order and every pro-rata group visible without opening another screen.

Click Edit order beside a member to change its Priority or Pro-rata weight. Save the change and the card immediately moves the member into the appropriate priority tier and re-sorts that tier by weight. Priority controls which tier is considered first and cannot exceed 100; pro-rata weight controls the split only among members in the same priority tier, must be greater than zero, and cannot exceed 10. Leave the weight blank to use the member's contracted volume instead.

5.3 Adding members

On the trader Pools board, a member is an unassigned executed physical PPA (SIGNED or ACTIVE) that you assign to a pool. Prospect generator sites, offtaker sites and trader blocks are not addable from + member here — conclude the contract first, then assign it.

+ member is enabled only when the trader has at least one unassigned executed PPA (the same set that feeds the unassigned-contracts strip in §5.5). If none exist, the button is greyed out with "No unassigned contracts — conclude a PPA first".

Click + member on the target pool. The modal ranks those unassigned contracts for that pool: side must match, the counterpart must pass the pool's Strict class compatibility, and only matches with a suitability score above 50% are listed. Score chips use amber (fair, >50–75), light green (good, >75–90) and green (strong, >90). Select a row to open the configuration drawer (priority, pro-rata, caps, spill / top-up); save creates a membership with physical_ppa_id only.

If every unassigned contract scores 50% or below for this pool, the list is empty — use the strip's type suggestion, or open + member on a better-matching pool type. The strip's [Accept suggestion] / [Choose pool…] path remains the one-click / pick-pool onboarding for the same contracts.

Path What it is for What gets saved
+ member on a pool card Ranked assign-to-this-pool for unassigned executed PPAs scoring >50% Membership with physical_ppa_id
Unassigned strip Type suggestion and one-click / choose-pool onboarding (§5.5) Same — membership with physical_ppa_id

Per-member fields, and why they exist:

Worked example — priority, then pro-rata. In one hour, the pool has 10 MW of demand to serve. The engine walks priority tiers in ascending order; it does not pro-rate across different priorities.

Member Priority Pro-rata weight MW cap Allocated MW
Solar PPA A (lowest-cost) 10 — 3.00 3.00 — served first, up to its cap
Solar PPA B 20 1 4.00 1.75
Solar PPA C 20 3 6.00 5.25
Solar PPA D 30 — 2.00 0.00 — no demand remains

PPA A takes 3.00 MW first, leaving 7.00 MW for the priority-20 tier. PPA B and C then split that remainder in the ratio 1 : 3: 7.00 × 1 ÷ (1 + 3) = 1.75 MW and 7.00 × 3 ÷ (1 + 3) = 5.25 MW. Their caps do not bind, so the split stands. PPA D is considered only after the priority-20 tier; by then the 10 MW requirement is met. If B and C had blank weights, the engine would use their contracted volumes instead — for example, 2 MW and 6 MW would produce the same 1:3 split.

Priority first; pro-rata only within an equal-priority tier
Demand to serve 10.00 MW
Priority 10
Solar PPA A 3.00 MW served to cap
7.00 MW remains
Priority 20 equal tier
Solar PPA B · weight 1 1.75 MW
Solar PPA C · weight 3 5.25 MW
7.00 MW × 1 : 3 → 1.75 MW : 5.25 MW
Priority 30
Solar PPA D 0.00 MW requirement already met

Members can be removed from the card's member list (trash control, with confirm). Removal destroys the membership and returns the executed PPA to the Unassigned contracts strip (§5.5) so you can place it on another pool. Historical allocation lines keep their kWh and prices; membership tags on those lines are cleared so the contract is free to reassign. Removing a member (or changing its priority / weight / caps) also raises the forecast-needed banner (§5.6).

5.4 Rules

Per pool, an ordered rule list that steers how the allocator serves it. Rules refine the default merit order — you only need them where the default (priority + price) doesn't express your contract or strategy.

Opening Rules. Click Rules on a pool card. The modal lists existing rules (reorder ▲/▼, enable/disable, delete) and a side-filtered picker: only rule types valid for that pool's side appear, and types already on the pool are omitted until you delete them. Each available type is a card with its name and a short description (the same intent as the table below). Pick a card, fill parameters when needed, then add.

Supply-side picker: PRIORITY, PRO_RATA, MW_CAP, NOMINATION, SHAPE_MATCH.

Demand-side picker: PRIORITY, PRO_RATA, MW_CAP, PRICE_OPTIMISE.

(PRICE_OPTIMISE is demand-only in the picker; NOMINATION and SHAPE_MATCH are supply-only.) A supply Shape match that names a Target pool is drawn as a coloured joiner in the gutter — the click path is §5.7.2; how to read the colours is §5.7.

Rule type Parameters What it does, and when to use it
PRIORITY a priority number Overrides the pool's default priority for allocation, without editing the pool. Use for temporary re-ranking — e.g. a month-long commitment that should jump the queue.
PRO_RATA basis: contracted volume or weights Controls how same-priority members share energy. Contracted (default) splits by PPA volume — the settlement-compatible choice. Weights uses the per-member pro-rata weights you set — for deliberate overrides. The split is a weighted "water-fill": a member who needs less than its share hands the surplus back to the others.
MW_CAP the MW cap Hard ceiling on the whole pool (or edge) per hour, on top of any per-member caps. Use to model a connection or offtake limit that individual contracts don't capture.
PRICE_OPTIMISE minimum margin (c/kWh) Skips any allocation whose margin (sell − buy − wheeling) would fall below the floor, letting that demand fall to the grid backstop instead. Firm demand always overrides the floor — a firm obligation is served even at negative margin, because failing to serve costs more. Use on demand pools where you'd rather not serve than serve at a loss.
SHAPE_MATCH TOU periods (peak/standard/off-peak multi-select) + Target pool Dedic ates a supply pool to a demand pool for specific TOU periods — the contractual "wind-backed night-shift energy" pattern (green claims, dedicated blocks). Target pool is labelled optional; leave it at Any and the rule stays on the card only. Name a demand pool and the gutter draws a joiner (§5.7.2). Note: in Phase 1 the ordinary merit order already does coarse shape matching by price; strict enforcement of this rule lands with a later milestone, so treat it as declared intent for now.
NOMINATION none Serve this pool's nominated members at exactly their nominated volume: the engine allocates min(nominated, available). Under-delivery vs nomination shows up as shortfall; over-availability shows up as spill.

5.4.1 Worked rule set — three hours, all six rule types

The following compact book shows how the rules combine. Network losses are ignored so the MWh remain easy to follow. Across the relevant pool Rules modals, the active rows are:

Owner / precedence Rule Scope and parameters
Municipal / 10 PRIORITY Municipal demand pool: priority = 5
Wind / 10 SHAPE_MATCH Wind → Industrial: tou_periods = [offpeak]
Municipal / 20 MW_CAP Municipal demand pool: mw = 8
Flexible / 10 NOMINATION Flexible supply pool; quantities come from submitted nominations
Municipal / 30 PRO_RATA Municipal pool: basis = weights
Commercial / 10 PRICE_OPTIMISE Commercial demand pool: min_margin_ckwh = 5
Three hourly decisions produced by the rule set
12:00standard
Solar available10 MWh
PRIORITY 5→MW_CAP 8
Municipal · PRO_RATA 1:32 Water + 6 Clinic
+
Solar left for Industrial2 MWh
23:00off-peak
Wind available10 MWh
SHAPE_MATCH→
Industrial night shift6 MWh
−5c < +5c floor→
Commercial rejected4 MWh spills
19:00peak
Flexible available9.0 MWh
NOMINATION ceiling→
Submitted quantity7.5 MWh allocated
+
Excess availability1.5 MWh spills

5.4.2 Example 1 — priority, pro-rata and a pool cap

At 12:00, Solar has 10 MWh. Municipal normally follows Industrial (default priorities 30 and 10), but its PRIORITY 5 rule moves it to the front for this run. Municipal contains two members: Water Works needs 4 MWh at weight 1; Clinic District needs 8 MWh at weight 3. The Municipal pool's MW_CAP 8 rule limits the pool before the tier is shared.

Step Calculation Result
PRIORITY Municipal effective priority 5 < Industrial 10 Municipal is considered first
MW_CAP min(12 demand, 8 pool cap) Municipal may receive at most 8 MWh
PRO_RATA 8 × 1 ÷ 4 = 2; 8 × 3 ÷ 4 = 6 Water 2 MWh; Clinic 6 MWh
Continue walk 10 − 8 = 2 2 MWh remains for Industrial

The run therefore records 8 MWh on the Municipal edge, split 2/6, plus 2 MWh to Industrial. Municipal has 4 MWh of unmet demand and Industrial has 6 MWh unmet. If Water Works needed only 1 MWh, weighted water-fill would give it 1 MWh and hand its unused share to Clinic District, subject to Clinic's own requirement.

5.4.3 Example 2 — shape dedication and margin protection

At 23:00, Wind has 10 MWh available at 75 c/kWh and wheeling is 15 c/kWh. Industrial's night shift needs 6 MWh and pays 110 c/kWh; Commercial needs 5 MWh and pays 85 c/kWh. The off-peak SHAPE_MATCH declares Wind → Industrial as the dedicated pairing, so the first 6 MWh goes to the night shift. The remaining 4 MWh reaches the Commercial edge, where PRICE_OPTIMISE tests the margin:

Commercial margin = 85 − 75 − 15 = −5 c/kWh
−5 < required +5 c/kWh → skip the allocation

Commercial therefore takes 0 MWh from Wind and falls to its grid backstop; the unused 4 MWh Wind remains available for another eligible buyer or becomes spill. If Commercial were firm, the margin floor would not block it: firm service overrides PRICE_OPTIMISE.

Current-phase note. The SHAPE_MATCH row stores and exposes the off-peak dedication as auditable intent. Where strict shape enforcement is not enabled in the deployed engine milestone, ordinary merit order still decides the physical allocation; the other calculations in this example remain the rule's intended enforced outcome.

5.4.4 Example 3 — nomination is a ceiling, not a promise

At 19:00, the Flexible member has a submitted nomination of 7.5 MWh, actual available supply of 9.0 MWh, and matched demand of 8.5 MWh:

allocated = min(9.0 available, 7.5 nominated) = 7.5 MWh

The run allocates 7.5 MWh, records 1.5 MWh spill from availability above the nomination, and records 1.0 MWh shortfall against the 8.5 MWh demand. On a poor evening with only 6.0 MWh available, the same rule allocates 6.0 MWh: nomination limits upside but never manufactures energy.

Rules are applied in precedence order — use the ▲/▼ buttons to reorder, the Enable/Disable toggle to switch one off without deleting it (it greys to half opacity), and 🗑 to delete. New rules append at the bottom. Every run line records which rules produced it (the Rules column in run detail, §8.5), so you can verify a rule is actually biting. Adding, removing, reordering or toggling a rule marks the forecast stale until you re-run (§5.6).

5.5 Unassigned contracts (the onboarding strip)

An amber strip below the board lists every executed PPA of yours that is not in any pool. Each row shows a Supply or Demand side badge (buyer vs seller leg for your trader), plus a type suggestion ("wind IPP, as-generated → Wind pool"):

The strip disappears when everything is assigned, and every newly executed contract reappears here until you place it. Removing a member from a pool (§5.3) puts that contract back on the strip. Treat it as a to-do list, not information: an unassigned contract is real money the engine cannot see, so your margin and coverage numbers are wrong until the strip is empty.

5.6 When the Pools board asks you to re-run the forecast

Overview and Dashboard read a sealed risk snapshot. That seal stores a fingerprint of the book's structure (pools, memberships, rules, book rates, pool status). When the live Pools board no longer matches the most recently sealed forecast, an amber banner appears at the top of Pools:

Forecast is behind this board — Members or rules changed since the last run. Overview and Dashboard still show the previous book — run a forecast to refresh them.

[Run Forecast Now] on the banner (and the same control in Performance) starts the Margin-at-Risk pass described in §4.10. While it runs:

When the seal succeeds, the flash "Forecast refreshed." appears, the overlay clears, and the amber banner disappears — Overview / Dashboard now match this board.

The banner returns when you:

It does not stay up merely because an older or future-dated snapshot row exists without a fingerprint — the board compares against the most recently sealed FORECAST.

5.7 The coloured joiners between Supply and Demand

The two-column board is a pair of warehouse aisles: Supply shelves on the left (sources, in merit order), Demand baskets on the right (buyers, in priority order). Between them sits a narrow strip of coloured joiners — the wiring gutter (#book-wires inside #book-cascade-board). Think of jumper cables between shelves. The colour of the cable tells you which supply shelf it left. The tag on the cable tells you the rule that named that destination. A dashed red cable is not a rule: it is leftover energy the latest forecast could not sell — spill.

Follow along. Seat: trader_1@webill.net (password supersecret). Path: T1 Renewables Pool → Strategy → Allocation → Rules. URL: /org/trader-pools/01a0ab54-e46b-7dde-b45f-73d119213c75/strategy/pools. Widen the window past the phone breakpoint — the gutter is hidden on a stacked (mobile) board (hidden until md). You should see at least one solid coloured curve with a short label, and — once a forecast has spilled — a dashed red rest → spill · N %.

What a solid joiner is. The engine only draws a solid curve when a supply pool has an active allocation rule that names a living demand pool (target_pool_id set, and that demand card is not ARCHIVED). One curve per such rule. The arrow-head points at the demand card. The curves are pictures, not buttons: they are aria-hidden SVG. You do not draw them by dragging between cards. You add a Shape match rule on the supply card and name a Target pool — the click path is §5.7.2.

Colour is the supply type, not the rule. This is the usual misread. On T1 an amber curve labelled shape match looks as if amber means shape-match, and a light-blue curve labelled price ≥ 12.5 c looks as if blue means price. Those colours belong to Solar (#f59e0b amber) and Wind (#0ea5e9 light blue). Put the same shape-match rule on Wind and the curve stays light blue; the word still says shape match.

Supply type Colour on the joiner Hex (as drawn)
Solar amber / gold #f59e0b
Wind light blue #0ea5e9
Flexible violet #8b5cf6
Firm dark slate #334155
Hydro teal #0891b2
Biomass olive #65a30d
Grid grey #94a3b8
Custom taupe #a8a29e

Demand cards themselves use a near-black slate (#1e293b); they do not paint the joiners. Archived supply shelves are omitted from the gutter, so their rules do not draw.

The word on the curve is the rule. The label is a short gloss of rule_type (and its parameters):

Label you see Rule on the supply card
shape match SHAPE_MATCH — pin this shelf to that basket for chosen TOU (time of use) periods or clock hours
price ≥ N c PRICE_OPTIMISE with floor N c/kWh — skip a non-firm sale whose margin would fall below N
price optimise PRICE_OPTIMISE with no floor stored
cap N MW MW_CAP — never send more than N MW along this edge
nomination NOMINATION — serve nominated members at min(nominated, available)
priority PRIORITY — temporary re-rank
pro rata PRO_RATA — split an equal-priority tier

Rules without a destination demand pool stay on the card’s Rules modal only. They do not appear in the gutter. Pool-wide PRIORITY / PRO_RATA / MW_CAP / NOMINATION on a demand card likewise stay on that card.

The dashed red joiner is leftover supply. When a forecast allocation run exists and some of that run’s supply was unsold, the gutter adds a dashed rose (#e11d48) curve along the bottom, labelled rest → spill · N %. N is the unsold share of total supply in that run, whole percent. No forecast, or a forecast with zero spill, means no dashed curve. The dashed line does not point at a demand card: spill has no buyer yet. When that leftover is more than 20 % of supply, Find offtake → Desk (#book-offtake-cta) sits under the board — not a trio of coaching cards.

Empty and hidden states.

5.7.2 How to create a solid joiner

A solid joiner is not a separate object. It is the picture of one fact: this supply shelf has a Shape match rule that names that demand basket. You create the fact on the supply card. The gutter then draws the cable.

You cannot paint a joiner from the Demand column. Demand Rules never offers SHAPE_MATCH, and the demand picker has no Target pool field. The dashed red spill curve is also not something you add: it appears only after a forecast leaves unsold supply (§5.6).

Before you start. You need at least one Supply pool and one Demand pool, neither ARCHIVED. You are on Book · Rules (…/strategy/pools). Widen the window so the gutter is visible (it is hidden on a phone).

Follow along. Seat: trader_1@webill.net (password supersecret). Path: T1 Renewables Pool → Strategy → Allocation → Rules. Pick a supply card whose Add a rule grid still shows SHAPE_MATCH — on T1 that is usually not Solar, because Solar already carries a shape-match. Flexible or Firm is the typical free shelf. You will point it at Industrial (or any named demand card).

Six clicks from a supply card to a gutter curve
1Rulessupply card
→
2SHAPE_MATCHpicker card
→
3Target poolname a demand basket
→
4Add rule
→
5Close
→
6See the curve
  1. On the Supply card that should own the cable, click Rules. The branded modal #rule-list-modal opens (Rules eyebrow, the pool name as the title, X at #rule-list-modal-close). Existing rules sit in an ordered list (#pool-rules-list).
  2. Under Add a rule (#available-rules), click the SHAPE_MATCH card (#available-rule-SHAPE_MATCH). The card explains that this type pins the shelf to a buyer for chosen hours. The form heading becomes Configure Shape match. (If the grid is missing and you see All applicable rules are already on this pool at #no-available-rules, this shelf already has every supply type, including Shape match. Delete that SHAPE_MATCH row first, or pick a different supply card.)
  3. TOU periods is a multi-select: Peak, Standard, Off-peak. These are TOU (time of use) windows on the South African tariff clock — pick the hours this dedication should apply. You can select more than one.
  4. Target pool (edge, optional) is the field that creates the joiner. The prompt is Any. Any means the rule applies to the whole shelf and no curve is drawn. Open the list and choose a demand pool by name (Industrial, Commercial, Municipal, Trader Sales, …). That name is the basket the cable will point at.
  5. Click Add rule. A new row appears in the list: type SHAPE_MATCH, a short parameter summary (the TOU periods you picked), and the usual ▲ / ▼ / Disable / trash controls. There is no extra flash — the list updating is the save.
  6. Close the modal (X, Escape, or click outside). On a desktop-width board a solid curve now runs from that supply card to the demand card you named. Its colour is the supply type (Flexible is violet, Firm is dark slate, Wind is light blue, Solar is amber). The word on the curve is shape match.

If nothing appears. Check four things, in order: you named a Target pool rather than leaving Any; that demand card is not ARCHIVED; you are looking at a wide window (#book-wires is hidden on a stacked phone layout); you added SHAPE_MATCH on a supply card, not a demand card.

What the other supply types do. PRIORITY, PRO_RATA, MW_CAP and NOMINATION on the same picker have no Target pool field. Saving them does not draw a joiner. PRICE_OPTIMISE is demand-only in the picker, so you cannot start a price ≥ N c cable yourself; the T1 Wind price joiner is demo seed (§5.7.1).

After you save. Adding a rule is a structural change. The amber Forecast is behind this board banner returns until you press Run Forecast Now (§5.6). The dashed red rest → spill · N % only refreshes after that run.

How to take a joiner away. Open Rules on the same supply card. Trash the SHAPE_MATCH row. Closing the modal removes the curve. Disable greys the row in the list but does not hide the gutter curve today — delete the rule (or archive the destination pool) when you want the cable gone.

T1 on the demo — reading the amber, the blue, and the dashed red

Data. full_demo · seed 42 · T1 Renewables Pool (01a0ab54-e46b-7dde-b45f-73d119213c75) · Book · Rules.

On that seeded book the demo places a SHAPE_MATCH on Solar aimed at a demand basket, and a PRICE_OPTIMISE (floor 12.5 c/kWh) on Wind aimed at a demand basket. After a forecast that cannot sell everything, the gutter therefore typically shows:

What you see How to read it
Solid amber curve, shape match Solar (amber) is dedicated to that demand basket for the rule’s TOU / hours
Solid light blue curve, `price ≥ 12.5 c` Wind (light blue) will not sell into that basket below a 12.5 c/kWh margin
Dashed red rest → spill · N % The latest forecast left N % of supply unsold — not a rule, a leftover

The Rules picker on a supply card does not offer PRICE_OPTIMISE (that type is demand-only when you add a rule yourself). The T1 seed can still store a price-floor rule on Wind with a named buyer, and the gutter will draw it. Treat that as demo wiring you can delete; your own books only get a price joiner from a supply shelf if a rule with a target actually sits there.

Extra shelves (for example a Custom Approved Override pool) can sit in the cascade without adding a curve, as long as they have no destination rule.

T1 Rules gutter — colour is the supply shelf, the word is the rule, dashed red is leftover spill (full_demo · seed 42)
Supplyleft column, merit order
Solaramber joiner
→shape match
Demand basketnamed target
→same gutter, second curve
SupplyWind, next shelf
Windlight-blue joiner
→price ≥ 12.5 c
Demand basketnamed target
↘no buyer
Leftoverafter the forecast
rest → spill · N %dashed red, not a rule

What “done” looks like. You can point at each solid curve and name the supply card, the rule, and the demand card. You do not treat amber as a synonym for shape match. You know the dashed red is unsold forecast energy, and you know a phone-width window will hide the whole gutter.

5.8 Explanations — How to Read Rules

Explanations (#book-explanations-open) sits on the Rules toolbar next to Run Forecast Now. It opens a right-hand drawer (#book-explanations-drawer) — the same chrome as Overview Explanations (§4.11): green header, X top-right, backdrop, Escape.

Eyebrow: Book · Rules. Title: Explanations. Above the terms sits How to Read the View (#book-how-to-read) — collapsed until you press #book-how-to-read-toggle. It is the short in-product reading order for this mode: thread strip, issues rail, headline, Supply · Demand, outcome badges, wiring gutter, book rates, unassigned contracts.

The A–Z list is only the words on the Rules board (ACTIVE through Wiring gutter). It does not include Forecast tiles such as Margin@Risk, or Outcomes warehouse words. Open Forecast or Outcomes and the same control teaches that mode instead.

Close with the X (#book-explanations-drawer-close), the backdrop, or Escape.


Data. full_demo · seed 42 · stage S09 (settlement matrix) · last re-derived 2026-07-18 against the full_demo manifest.

Follow along. Seat: trader_1@webill.net (password supersecret). Path: T1 Renewables Pool → Strategy → Pools. You should see supply and demand structure before assigning or changing a member.

6. Book · Forecast — what the engine will do

You need an answer you can reproduce, not an editable dashboard number. A run is one immutable execution of the allocation engine for a scenario, grade and calendar month. Runs preserve the plan you had when you made a decision, while the index makes the current result easy to distinguish from its history.

Route: /org/trader-pools/:id/strategy/book?mode=forecast · Tab: Book · Mode: Forecast (the old /allocations route forwards here). Forecast is not a #strategy-nav tab — Allocation stays lit. Open it from the thread strip (#book-stage-forecast), a run link, or this URL.

Data. full_demo · seed 42 · stage S09 (settlement matrix) · last re-derived 2026-07-18 against the full_demo manifest.

6.1 The run picker, and what the mode shows

The Forecast mode reads one run at a time. The run picker under the headline is a month input and one chip per run of that month — Forecast P50, Adverse P90, Nominated, Actual — each with its status pill, a Simulations ×n count with any failures, Run backcast when the month is past and has a Forecast but no Actual, and New run. Pick a chip and everything below re-reads for that run; the URL carries &run=<id> so a link reproduces the view. Under the picker, Open the run ledger › drills to the run detail page (§8).

The mode then reads top to bottom. The table is a map. Each block is taught in full from §6.9.

Block What it says
Headline One sentence from the run’s KPIs, in the Overview’s voice: “September P50: every demand hour is covered, but 96.4 % of supply finds no buyer and the month loses R 13.1 m.”
Five tiles Margin (with the grade, contracted ratio, Margin@Risk), Coverage (with shortfall), Spill (with its rand cost at the spill value), Effective price (with realised R/MWh and supply HHI), and the Battery (or take-or-pay utilisation when the book has none)
Where the supply goes Each supply pool’s energy split into what the cascade sold to each demand pool and what it spilled — the demand pools in the same order and colours as the Rules board
Where the margin is made and lost By time of use and by source pool, with the spill line; a sentence says whether the loss is a price problem or a wiring-and-demand problem
Long or short, hour by hour The Overview’s clock per pool: supply stacked against the demand line on a typical day of the run
Pool caps, this run The Rules board’s outcome badges as a table: result, cap or band, and ok · outside · breach
Battery dispatch (fold) Only for books with an active battery: arbitrage margin, cycles a day, spill absorbed, firm hours backed, market arbitrage, and Open full dispatch › to the battery page (§11)
The run’s line ledger (fold) The link to every line of the run, one SAST day at a time (§8)
Find offtake A single line (#book-forecast-offtake-cta) under the ledger, only when this run spills more than 20 % of supply. Find offtake → Desk opens Simulations. Nominations and Outcomes stay on the thread strip — they are not extra cards.
Cover shortfall Same pattern (#book-forecast-cover-cta) when unmet demand is above 5 %. Cover shortfall → Desk.

There is no three-card “next moves” strip under Forecast. The thread strip already opens Nominations and Outcomes. Spill and shortfall that are this large get one Desk door each, the same way Rules offers Find offtake → Desk when leftover supply is above 20 % (§5).

The table below is what each run carries, and how to read it; on the picker the scenario is the chip, the period is the month input, the grade and status are the chip’s label and pill, and the four KPIs are the tiles.

Column What it records How to use it
Scenario Input family used by the engine (FORECAST, NOMINATED, SIMULATION, ACTUAL) Compare like with like. A simulation is a what-if, not the operating plan; a nominated run is the position you declared, not the forecast you hoped for.
Period Whole calendar month the engine solved hour by hour Confirm the month before comparing KPIs — August margin cannot justify a September nomination.
Grade Forecast exceedance assumption on supply: P50 (expected / median) or P90 (adverse — output you are 90% confident of meeting or exceeding). Defaults to P50. Treat P50 as the base plan and P90 as the stress view. Run both for the same scenario and period when you need Margin@Risk: the gap between their margins is the exposure if renewables under-deliver. Do not mix a P50 margin with P90 line items. A newer COMPLETE run supersedes only the same scenario and grade for that period, so the P50 and P90 currents can coexist.
Status Execution state (PENDING → RUNNING → COMPLETE, or FAILED) Read KPIs only from COMPLETE. RUNNING / PENDING are in flight; FAILED changed nothing — keep using the previous completed current.
Coverage Share of demand met by allocated supply over the month (allocated ÷ demand) Use as the first triage signal. Low coverage means hours where the stack could not serve load — open the run and inspect Shortfall hours before changing pools or nominations. Rising coverage toward target is progress; a high average can still hide evening gaps if solar-heavy.
Margin Net rand outcome of every allocation, spill and shortfall line for the month The commercial headline. Compare only within the same scenario and grade. A healthy P50 margin that collapses under P90 is a shape or firmness problem, not a price typo — drill into margin-by-TOU and spill/shortfall tabs before re-contracting.
Spill Share of supply left unsold (spill ÷ supply) High spill means you paid for energy nobody took (painful under take-or-pay). Check whether the shape misses demand, a cap is binding, or you are simply long — then prefer reshaping or BESS absorption over celebrating low shortfall alone.
Shortfall Share of demand left unmet by the stack (shortfall ÷ demand) Firm shortfall is usually your most expensive energy (grid top-up). Prefer fixing shortfall hours over chasing a slightly higher margin that leaves evening gaps. On the detail page, the Shortfall tab names the members and hours.
Superseded Newer equivalent COMPLETE result exists for the same scenario, grade and period Keep for audit history at reduced opacity; do not treat it as the current plan.

The current forecast is the newest non-superseded COMPLETE run for that scenario, grade and period. A nominated run has its own current row; it does not replace your forecast simply because it was created later.

6.2 Row actions — Open and Run backcast

Two actions sit beside the run picker. They are not decoration: the picker is a triage list; these actions are how you prove a number or close the loop against meters.

Open →

Why it is there. KPI columns answer “how did the month look?” They cannot answer “which hour, which member, which rule?” The engine’s proof lives on the run detail page (§8). Open the run ledger › — under the picker and in the ledger fold — is the drill-through from the picker into that audit floor.

What it does. Navigates to /org/trader-pools/:id/strategy/allocations/<run id> for that immutable run — not “the latest for the month”, and not a live recalculation. You see:

Use Open → whenever a Coverage, Margin, Spill or Shortfall figure surprises you, when you need evidence for a dispute or nomination decision, or when you want to compare a superseded row with its successor side by side (open each in turn). Superseded and failed rows remain openable so history stays auditable.

Run backcast

Why it is there. Forecast and nominated runs plan with shapes and declarations. After the month settles, you need a parallel Actual run built from measured meter energy so you can score forecast accuracy, nomination mismatch and dashboard panels that wait on settled actuals. Actual is intentionally not a choice in the New run modal — meters must exist first. Run backcast appears in the picker for a past month that has a Forecast but no Actual yet.

What it does. On a row that qualifies, Run backcast:

  1. Takes that row’s calendar month.
  2. Re-runs the allocation engine with scenario ACTUAL (settled meter inputs instead of forecast shapes).
  3. On success, adds a COMPLETE Actual row for the same period and refreshes forecast / nomination accuracy signals that depend on settled actuals.
  4. If no member has settled meter rows for the month, nothing is written — you get a clear flash that settled data is not available yet.

When the control appears. Only on a Forecast row that is COMPLETE, and only while that period does not already have a non-superseded COMPLETE Actual. Nominated, Simulation and Actual rows do not show it; a forecast that already has its Actual for the month does not show it either (re-backcast is a deliberate later action once a newer Actual supersedes, or via ops schedules).

How to read the result. Filter to Actual (settled) or leave All and find the new ACTUAL row. Open → that Actual: the green Forecast vs settled actual panel (§8.2) shows Margin / Coverage / Spill / Shortfall Δ tiles, the month shape overlay (Forecast line vs Actual line), the same delivery period notice, and any Proxied members. That panel is the commercial forecast-error story; the day chart and tabs underneath then explain the hours.

Worked example — June 2026 backcast on T1 Renewables Pool

Data. full_demo · seed 42 · stage S07 (strategy historical runs) · T1 Renewables Pool · period June 2026 · grades P50. The Forecast and Actual KPI maps below are the sealed gallery pair for that month; shortfall hour lines are the seeded first-weekday slice on each run.

1. Starting point on the Runs index. You already have a completed Forecast for June. Meters for the month have settled, so Run backcast is visible on that row. After it completes, the index shows two current (non-superseded) companions for the same period:

Lane Scenario Grade Status What the engine consumed
Plan FORECAST P50 COMPLETE Forecast shapes / profiles
Settled ACTUAL P50 COMPLETE Measured meter energy

2. Month roll-up — the numbers on each row. Coverage and residual shares are derived from the run KPI map with the same ratios the Runs header tooltips describe. Read them as snapshot dumps — the same card format as §4.10 · Snapshot the Overview actually shows.

How the Runs KPIs are derived
Coverage      = allocated_mwh ÷ total_demand_mwh
Spill %       = spill_mwh ÷ total_supply_mwh
Shortfall %   = shortfall_mwh ÷ total_demand_mwh
Forecast snapshot (June 2026 · P50)
MARGIN_R              = 331 500
MARGIN_R_PER_MWH      = 263
COVERAGE_PCT          = 81.3           ← 1 113 ÷ 1 369
SPILL_PCT             = 3.6            ← 44 ÷ 1 217
SHORTFALL_PCT         = 4.4            ← 60 ÷ 1 369
TOTAL_SUPPLY_MWH      = 1 217
TOTAL_DEMAND_MWH      = 1 369
ALLOCATED_MWH         = 1 113
SPILL_MWH             = 44
SHORTFALL_MWH         = 60
Actual snapshot (June 2026 · settled)
MARGIN_R              = 353 000
MARGIN_R_PER_MWH      = 266
COVERAGE_PCT          = 81.1           ← 1 126 ÷ 1 388
SPILL_PCT             = 3.9            ← 48 ÷ 1 234
SHORTFALL_PCT         = 4.7            ← 65 ÷ 1 388
TOTAL_SUPPLY_MWH      = 1 234
TOTAL_DEMAND_MWH      = 1 388
ALLOCATED_MWH         = 1 126
SPILL_MWH             = 48
SHORTFALL_MWH         = 65
Δ snapshot (Actual − Forecast)
MARGIN_R              = + 21 500       ← commercial headline improved
MARGIN_R_PER_MWH      = + 3
COVERAGE_PCT          = − 0.2 %        ← demand (+19) slightly outran allocation (+13)
SPILL_PCT             = + 0.3 %
SHORTFALL_PCT         = + 0.3 %
TOTAL_SUPPLY_MWH      = + 17           ← resource beat the P50 shape
TOTAL_DEMAND_MWH      = + 19           ← load ran above the profile
ALLOCATED_MWH         = + 13
SPILL_MWH             = + 4
SHORTFALL_MWH         = + 5
Conservation check (must hold before you trust the delta)
Forecast demand side : allocated + shortfall = 1 113 + 60 = 1 173
Forecast supply side : allocated + spill     = 1 113 + 44 = 1 157
Actual   demand side : allocated + shortfall = 1 126 + 65 = 1 191
Actual   supply side : allocated + spill     = 1 126 + 48 = 1 174

The residual gap to total demand / total supply is network loss and pool-level routing — open the run to see it on the lines.

Pattern to expect on your own page: one Forecast row and one Actual row for the same period; Δ is Actual minus Forecast. A healthier margin with slightly worse spill/shortfall means prices and mix helped more than volume residuals hurt — confirm on the detail tabs before changing contracts.

June 2026 backcast at a glance — volume stacks and margin bars (T1 · seed 42)
Allocated Spill Shortfall Margin

Supply disposition (MWh)

Allocated and spill — Forecast vs Actual Two stacked bars: Forecast 1,113 allocated + 44 spill; Actual 1,126 allocated + 48 spill. Forecast Actual 1,113 +44 1,126 +48 0MWh

Read it: both months are mostly allocated energy; the thin top band is spill. Actual is only slightly taller — the +17 MWh supply shows up as +13 allocated and +4 spill.

Margin (R)

Margin bars — Forecast vs Actual Forecast bar R 331,500; Actual bar R 353,000; delta callout + R 21,500. Forecast Actual R 331.5k R 353k Δ + R 21.5k 0Rand

Read it: the commercial bar rises even though coverage slipped 0.2 %. Open both runs before assuming the book is “fine” — residual hours may still need firming.

3. Prove the residual on one hour (Open → → Shortfall tab). The seeded first weekday (1 Jun 2026) carries a shortfall line every hour. Three anchors show how Actual diverges from Forecast on the same clock:

Hour (SAST) Forecast shortfall Actual shortfall Δ kWh Plain reading
00:00 1,197 kWh 1,244 kWh +47 Overnight unmet demand ran ~4% hotter
12:00 1,569 kWh 1,674 kWh +105 Midday gap widened — load and/or solar miss vs plan
18:00 1,755 kWh 1,899 kWh +144 Evening peak is where shortfall hurts most
Shortfall hour deltas (seeded first weekday)
00:00 gap growth      = 1 244 − 1 197 = + 47 kWh
12:00 gap growth      = 1 674 − 1 569 = + 105 kWh
18:00 gap growth      = 1 899 − 1 755 = + 144 kWh
Month SHORTFALL_MWH Δ = 65 − 60 = + 5 MWh   (= 5 000 kWh)

The evening hours dominate the month’s +5 MWh shortfall delta — that is why a nearly flat coverage % can still hide a procurement problem. On the Actual detail page, filter the Shortfall tab to 18:00 and note which demand membership owns the line; that membership is the candidate for firmer supply or a nomination change next month.

4. What you do next.

  1. Keep the Forecast row as the plan you made; keep the Actual row as what meters proved.
  2. If margin Δ is positive but shortfall Δ is also positive (as here), fix evening firmness before celebrating the rand outcome.
  3. If you needed the opposite story (Actual weaker on margin), open Margin by TOU on both runs and find which period inverted.
  4. Nomination Performance and forecast-error panels that were “awaiting settled actuals” can now light up for June — the backcast is their input.

Note. A scheduled monthly backcast also runs after settlement reconciliation (see the operations catalogue). Run backcast on the index is the on-demand control when you need the Actual lane before the calendar job, or for a month you have just finished settling.

6.3 Choose the scenario deliberately

New run opens the modal. The scenario chooses inputs, not a cosmetic label.

Scenario Inputs Use it when
FORECAST Supply forecast shapes and demand profiles You need the operating plan
NOMINATED Submitted nomination rows You need the position you declared
SIMULATION Hypothetical inputs You are testing an isolated case
ACTUAL Settled meter data, when available You are reviewing realised performance — created via Run backcast (§6.2), not from New run

Use the Simulation Workbench for commercial candidates instead of manually creating a simulation run. It creates the required baseline and variant pair, keeps the candidate out of your live pool, and presents the deltas together.

6.4 Set period and grade

Inside New run, the Month picker covers a complete calendar month, hour by hour. Choose the month you intend to decide about; a high margin in August cannot justify a September nomination. Forecast grade chooses the supply confidence view (P50 expected or P90 adverse).

Technology / source P50 → P90 ratio What the adverse case assumes
Solar 0.94 6% below the P50 shape
Hybrid 0.92 8% below P50
Hydro 0.90 10% below P50
Wind 0.86 14% below P50
BESS 1.00 Dispatch is not reduced by a generation ratio

For a solar P50 interval of 10.00 MWh, the derived P90 is 10.00 × 0.94 = 9.40 MWh. For a wind interval of 10.00 MWh it is 10.00 × 0.86 = 8.60 MWh. That larger wind gap is why two books with the same P50 margin can carry materially different Margin@Risk.

Careful. P90 is an adverse planning view, not a guarantee that every interval will produce exactly 90% of P50. Use the pair to understand sensitivity, then inspect the allocation hours that cause the difference.

6.5 Worked New run — forecast August

Suppose you have adjusted a member in T1 Renewables Pool and need evidence now rather than at the next nightly cycle.

Input Selection
Pool T1 Renewables Pool
Scenario FORECAST
Month August 2026
Grade P50 (expected)
Purpose Confirm the revised expected operating plan
  1. Open Book · Forecast and select New run in the run picker.
  2. Choose FORECAST, choose August 2026 and retain P50 (expected).
  3. Start the run. Its chip appears as pending, then running.
  4. When it becomes COMPLETE, select Open → and confirm the pool, period and grade on the detail page.
  5. Repeat with P90 (adverse) only if you need the risk pair; compare the two run-level margins rather than mixing their line items.
  6. When meters for that month have settled, return to the Forecast row and select Run backcast to create the Actual companion; open the Actual for the Forecast-vs-settled panel (§8.2).

If the book has an active battery, its dispatch is included automatically using the two-pass method in §7.3. The completed detail page consequently includes the BESS evidence tab.

6.6 Understand superseding before you rerun

A successful newer run replaces the current row only within the same scenario, grade and period. The older row remains readable at reduced opacity so you can show what changed and when. Open → still works on superseded rows.

One forecast run’s lifecycle — the newest successful equivalent becomes current
PENDING
→worker starts
RUNNING
→engine succeeds
COMPLETE
→new equivalent completes
SUPERSEDED
From RUNNING: FAILED

A failed run changes nothing: the previous completed current run remains current.

This is an audit feature. It prevents a manual rerun from rewriting yesterday’s decision evidence, while still ensuring one unambiguous current result.

6.7 Follow along — inspect, run, verify

Follow along. Seat: trader_1@webill.net (password supersecret). Path: Trader Pools → T1 Renewables Pool → Strategy → Runs. You should see newest-first rows with scenario, grade, status, KPI columns and, on the right, Open → (every row) and Run backcast on completed Forecast rows that do not yet have an Actual.

Filter to Forecast. Select Open → on the newest completed non-superseded row and skim the day chart and Shortfall tab, then return to the index. Create a P50 run for a month you are testing via New run. Wait for COMPLETE before comparing it with the prior row. If a completed Forecast shows Run backcast, use it only when you know meters for that month have settled — otherwise expect the “no settled meter data” flash. If a new run fails, read the error and keep using the previous completed result; no cleanup is required.

Runs answer “what did the engine decide?” The next chapter explains how the engine reaches those allocation decisions; §8 shows how to prove a particular result after you select Open →.

6.8 Explanations — How to Read Forecast

Explanations (#book-explanations-open) sits to the right of the Forecast headline. Same drawer shell as §5.8. Eyebrow: Book · Forecast.

How to Read the View is a different fold from Rules: this mode is one sealed run, not the wiring diagram. The reading order is thread strip, headline, run picker, five tiles, where the supply goes, where the margin is made and lost, long or short hour by hour, pool caps, battery fold, then Find offtake (only when this run spills more than 20 % of supply) or Cover shortfall (only when unmet demand is above 5 %).

The A–Z list is the words on Forecast (Actual through Where the supply goes). Wiring gutter is not here — that word lives on Rules. Warehouse rule is not here — that word lives on Outcomes.

The in-product drawer is a one-screen reminder. The rest of this chapter walks the same blocks with the T1 September numbers.


6.9 How to read Forecast, block by block

A dashboard number you can edit is a wish. Forecast is a sealed run — one pass of the engine for one scenario, one grade and one calendar month. You cannot type a new margin onto the tiles. You pick another run, or you start a new one.

This mode does not change the wiring. That is Book · Rules. It does not settle meters. That is Book · Outcomes. It answers: if this book ran for this month at this grade, where would the energy go and what would the money do?

Think of a bakery that already bought the day’s flour. Forecast is the bake sheet for one oven setting: how much bread sold, how much dough was leftover, and whether the till ended up or down. The recipe is Rules. The till tape after the shop closed is Outcomes.

Follow along. Seat: trader_1@webill.net (password supersecret). Path: Trader Pools → T1 Renewables Pool → Strategy → Allocation → Forecast on the thread strip (#book-stage-forecast). Deep link: /org/trader-pools/01a0ab54-e46b-7dde-b45f-73d119213c75/strategy/book?mode=forecast&month=2026-09&run=01a0b951-b50d-76c2-bfd8-840b7e. You should see the eyebrow Book · Forecast, a headline that names September P50, five tiles, then the two-by-two of charts and tables.

Data. full_demo · seed 42 · T1 Renewables Pool · run 01a0b951-b50d-76c2-bfd8-840b7ecc12cd · scenario FORECAST · grade P50 · period 1 Sep 2026 → 1 Oct 2026 · status COMPLETE · not superseded. Numbers below are that run’s KPI map and allocation lines, last read 2026-09-19. Compact Rand follows the product (R 13.1 m, R 786 k). Energy labels follow the product too (35.7 GWh, 979 MWh).

On screen, top to bottom

Order Block DOM id
Shell Heading Book — Forecast. Subtitle: How the book is wired, what the engine will do with it, and what actually settled — one thread across three views. Busy overlay: Running the book…. First paint: Loading the book…. #org-page-heading, #trader-book[data-mode=forecast]
1 Thread strip, then the issues rail #book-thread, #book-stage-forecast, #book-issues
2 Eyebrow Book · Forecast, headline, lede, Explanations #book-forecast-headline, #book-explanations-open
3 Run picker, then the meta line with Open the run ledger › #book-run-picker, [data-role=run-meta]
4 Five tiles #book-forecast-tiles
5–8 Where the supply goes · Where the margin is made and lost · Long or short, hour by hour · Pool caps, this run #book-flow, #book-margin, #book-day, #book-caps
9 Battery dispatch (fold) — only when the run stored battery KPIs #book-battery
10 The run’s line ledger (fold) #book-ledger-fold
11 Find offtake → Desk and/or Cover shortfall → Desk #book-forecast-offtake-cta, #book-forecast-cover-cta

There is no #book-moves strip on Forecast. Nominations and Outcomes stay on the thread strip. The three ranked cards live on Outcomes only (§6A.14).

What “looks good” vs “looks bad” on this whole page. Good: coverage high, spill inside its cap, margin positive, caps read ok, no Find-offtake line. Bad — and this is T1 September — every demand hour is covered and almost all supply spills and the month loses tens of millions. Covered customers are not the same as a healthy book.


6.10 Thread strip, issues rail and headline

The problem. You can open Forecast from three doors (the strip, a run link, this URL) and lose the rest of the Book. The strip is how you stay on the same tab.

Thread strip (#book-thread). Three stages, left to right:

Stage Eyebrow Id What the body shows
Rules Rules · how the book is wired #book-stage-rules Live pool and member counts. Pill: cap verdict (4 caps breached on the demo).
Forecast Forecast · what the engine will do #book-stage-forecast Month, grade and compact margin. Pill prefers spill when spill > 20 %, else shortfall when shortfall > 5 %, else coverage. No run yet: No forecast run yet and pill run one.
Outcomes Outcomes · what actually settled #book-stage-outcomes Last settled month and net. Pill balanced / not balanced. Nothing settled: Nothing settled yet.

Forecast is ringed (data-on=true) on this mode. A negative margin prints rose; a positive one prints brand green. Clicking a stage navigates; it does not rerun the engine.

On this T1 September run the Forecast stage reads September P50 and −R 13.1 m, with pill spill 96.4 %. The note under it is 100 % covered · 96.4 % of supply unsold.

Where the strip is taught. The three-stage Book thread — §5. This section only names what Forecast lights and what the pill prefers.

Issues rail (#book-issues). Ranked cards under the strip, each with a colour dot (rose = bad, amber = warn, slate = info), a title, a body, and a door (Rules › / Forecast › / Outcomes ›). On T1 September the first card is Spill at 96.4 % of supply. The body lists the supply pools that broke their cap (Solar, Wind, Flexible, Firm) and ends Whatever the rules cannot sell, the forecast spills at the spill value. Next, Coverage outside its band on 2 demand pools — Commercial and Municipal sit at 100 % against narrower bands; the body adds Over-covered is over-bought. There is no shortfall card: unmet demand is 0 %.

Headline (#book-forecast-headline). One sentence from the run’s KPIs. The recipe, in order:

  1. Empty KPI map: {Month} {Grade}: the run has no figures yet ({status}).
  2. Spill > 50 % and margin negative (T1 September): {Month} {Grade}: every demand hour is covered, but {spill} % of supply finds no buyer and the month loses {abs margin}.
  3. Shortfall > 20 %: unmet-demand sentence.
  4. Margin negative (without that huge spill): loses / coverage / spill.
  5. Spill > 20 % with a profit: earns but spills.
  6. Otherwise: earns at coverage and spill.

T1 September hits rule 2:

September P50: every demand hour is covered, but 96.4 % of supply finds no buyer and the month loses R 13.1 m.

Lede (the grey line under the headline). Always: The engine’s month, one run at a time. Pick the run at the top; everything below re-reads. The same pool colours as the Rules board, so the bar that spills here is the card that breaches there.

Explanations sits to the right of that pair (§6.8).


6.11 The run picker and the doors around it

The problem. A month can hold a Forecast, an Adverse P90, a Nominated plan, several simulations and — once meters settle — an Actual. Mixing them on one canvas would lie. The run picker (#book-run-picker) makes you choose.

Month input. type=month, aria-label="Run month". Changing it patches ?month=YYYY-MM and reloads the chips. September cannot explain August.

Chips. At most four, in this order, and only when that slot has a run:

Chip label Who it is Id
Forecast P50 (or Forecast P90 if that is the current forecast slot) Newest complete non-P90 FORECAST in the month #run-row-{id}
Adverse P90 Complete FORECAST or SIMULATION with grade P90 #run-row-{id}
Nominated A NOMINATED run #run-row-{id}
Actual A complete ACTUAL #run-row-{id}

Each chip carries data-role="run-chip", data-scenario and data-status, plus a status pill: complete (green), pending / running (amber), failed (rose). The selected chip is ringed. Clicking it patches &run={id} so a shared URL reproduces the view.

September 2026 on T1 also shows a dashed Simulations ×n count (nine simulation rows in this dataset, including hypothetical candidates) and an amber n failed pill when any run failed. The count is not a chip — it does not re-read the tiles.

This URL pins a run. The walkthrough uses …&month=2026-09&run=01a0b951-b50d-76c2-bfd8-840b7e. That is the full-month P50 (01 Sep 2026 → 01 Oct 2026). The picker’s Forecast P50 slot can point at a different complete September forecast if a later one exists. Confirm the meta line under the picker before you quote a tile.

Meta line (data-role="run-meta"):

Run 01 Sep 2026 → 01 Oct 2026 · FORECAST · COMPLETE Open the run ledger ›

The link is /org/trader-pools/{id}/strategy/allocations/{run id} — the same door as §6.2 Open and §8.

New run (#book-new-run). Opens the branded modal #book-new-run-modal (header #book-new-run-header, title #book-new-run-modal-title, close #book-new-run-close or Escape or the backdrop #book-new-run-modal-backdrop). Fields: Scenario (FORECAST / NOMINATED / SIMULATION), Month, Forecast grade (P50 (expected) / P90 (adverse)). Helper: Actual (settled) runs are not started here; they are rebuilt from measured energy once meters settle. Run starts the worker; the button reads Running… while it is in flight. Scenario, period and grade are taught in §6.3–§6.5.

Run backcast (#book-run-backcast) appears only when the picker month is before today’s month, a Forecast exists, and no Actual exists yet. September 2026 on a 19 Sep 2026 clock is the current month — the button is hidden. How backcast works: §6.2.


6.12 The five tiles

The problem. A month of hourly lines is too long to scan. The five tiles (#book-forecast-tiles, each data-role="forecast-tile" with data-key) are the roll-up. Rose numbers are the leak. Green numbers are the ones that held.

They sit in one row from md up (two columns on a phone). Each tile is a label, a big value, and a note. They do not click through.

On this T1 September P50 run:

data-key Label Value (tone) Note
margin Margin · P50 −R 13.1 m (rose) 4 % contracted ratio · MaR 0 %
coverage Coverage 100 % (green) 0 % shortfall · 2 demand pools
spill Spill 96.4 % (rose) of supply unsold · −R 16.5 m at the spill value
price Effective price 157 c (slate) realised R 57 / MWh · HHI supply 0.41
battery Battery R 0 (green) 0.00 cycles/day · absorbs 0.0 % of spill

Tones: margin is rose when the month loses, green when it earns; coverage is amber under 70 %, else green; spill is rose over 20 %, else green; effective price is always slate; the battery tile is always green. The fifth tile is Take-or-pay (data-key=top) only when the run has no bess_arbitrage_margin_r key — see §6.17.

Margin · P50

Why it exists. This is the commercial headline: every allocation, spill and shortfall line of the month, netted.

The label carries the run’s grade so you do not mix a P50 margin with a P90 one. The value is compact Rand (R 13.1 m = about R 13,065,000). Full figure on the run: −R 13,064,676.

The note has two words:

Looks good: a green value, contracted ratio near the share you meant to sell, MaR filled from a real P90 companion. Looks bad: a rose tens-of-millions loss while coverage is 100 % — you paid for energy nobody took.

Coverage

Why it exists. Did the buyers get served? Coverage is allocated ÷ demand. Shortfall is the leftover demand (Shortfall %).

T1 September: 100 % coverage, 0 % shortfall, 2 demand pools with energy in the run (Commercial and Municipal). Industrial and Trader Sales sat idle — they do not count here.

Tone turns amber under 70 %. 100 % is green. That is not the same as a healthy book: you can cover two small baskets and still drown in spill.

Looks good: high coverage and shortfall inside the demand cards’ bands. Looks bad: a green 100 % that hides a missing buyer class, or a high average that still leaves evening gaps (open §6.15 before you celebrate).

Spill

Why it exists. How much flour never became a loaf? Spill is unsold supply ÷ all supply (Spill %).

T1 September: 96.4 % of 59,600 MWh supply was leftover — 57,437 MWh. The note prices that leftover at the book’s spill value: −R 16.5 m. That is the spill lines’ margin (buy price minus the dump price), not the month’s net. The month’s net is the Margin tile; spill is the leak inside it.

Tone is rose over 20 % — the same threshold that shows Find offtake (§6.19).

Looks good: spill inside each supply card’s cap (15 % Solar, 12 % Wind, 20 % Flexible, 5 % Firm — §5.1). Looks bad: 96.4 %. You cannot nominate your way out of a book that bought ~24 times the demand it can serve.

Effective price

Why it exists. Two prices live on one tile because “what did we earn?” has two honest answers.

The tile is slate on purpose: a high cents figure on a thin sold slice can look healthy while the month loses R 13.1 m.

Looks good: realised and effective sit close (little unsold energy) and HHI is not a single-member spike. Looks bad: 157 c next to R 57 / MWh.

Battery — or Take-or-pay

T1’s book seats Rosslyn BESS — 5 MW / 20 MWh on Firm. The run stored battery KPIs, so the fifth tile is Battery, not Take-or-pay. The value R 0 and the note 0.00 cycles/day · absorbs 0.0 % of spill mean the battery was present and did not work this month — it did not soak the 57 GWh leftover.

ToP utilisation for this run is 2.5 % (almost none of the Firm take-or-pay volume earned). That figure is not on a Forecast tile while the battery key exists. When a book has no battery KPIs, the fifth tile reads Take-or-pay and that utilisation is the value.

Looks good (battery): a positive arbitrage value and a real cycles/day number. Looks bad: R 0 beside 96.4 % spill — the battery did not save the bake.


6.13 Where the supply goes

The problem. The Spill tile says how much leftover you have. It does not say which shelf leftover it, or which basket bought the slice that sold.

On screen: #book-flow. Title: Where the supply goes. Intro on the card:

Each supply pool’s energy for the run, split into what the cascade sold to the demand pools and what it spilled. The demand pools are the same cards, in the same order, as on the Rules board.

This is a server-drawn SVG (no hover, no separate legend). Colours are the legend: they match the Rules cards.

Side Colour Who
Supply · Solar amber #f59e0b Solar Pool
Supply · Wind sky #0ea5e9 Wind Pool
Supply · Flexible violet #8b5cf6 Flexible Pool
Supply · Firm slate #334155 Firm Pool
Demand bars ink #1e293b Commercial, then Municipal (priority order)
Spill outlet amber #d97706 at half opacity Leftover

How to read it, left to right.

  1. Left stack. One bar per supply pool that moved energy, tallest first. The label is {name} {energy}.
  2. Ribbons. A coloured band from a supply bar to Sold is that pool’s allocated energy. An amber wash from the same bar to Spill is that pool’s leftover.
  3. Right stack. Demand bars in Rules priority order (not by size). T1 only draws Commercial and Municipal — Industrial and Trader Sales had no demand in the run.
  4. Right labels. Sold {energy} · {sold %} %. Under it, in rose: Spill {energy} · {spill %} % and {rand} at the spill value. A Shortfall {energy} line appears only when unmet demand is above zero — T1 has none.

Empty copy, when the run has no allocation lines: No allocation lines in this run.

Where the Overview cousin is taught. Overview §4.4 is a ribbon map of the snapshot run, coloured by margin, with hover. This Forecast chart is the picked run, coloured by pool type, with no hover. Same marketplace, different job.

Worked reading — T1 September P50

Conservation first. The chart must add up before you argue a ribbon.

Supply (alloc + spill)     = 59,600 MWh
Sold (allocated)           =  2,163 MWh   →  3.6 %   → label “Sold 2.2 GWh · 3.6 %”
Spill                      = 57,437 MWh   → 96.4 %   → label “Spill 57.4 GWh · 96.4 %”
Shortfall                  =      0 MWh
Demand (sold + shortfall)  =  2,163 MWh
Sold + spill               = 59,600 MWh = supply ✓

Left stack, tallest first:

Supply pool Energy on the bar Sold Spill Spill share
Wind Pool 35.7 GWh 629 MWh 35.1 GWh 98.2 %
Solar Pool 17.8 GWh 1,424 MWh 16.4 GWh 92.0 %
Firm Pool 4.3 GWh 110 MWh 4.2 GWh 97.5 %
Flexible Pool 1.8 GWh 0 1.8 GWh 100 %

Flexible has no sold ribbon — the whole bar washes into Spill. Approved Override Supply is ACTIVE on Rules and sent nothing this run, so it is absent.

Where the 2.2 GWh actually landed (the five allocation legs):

From To Energy Sold-leg margin
Solar Pool Commercial Pool 760 MWh +R 1.2 m
Solar Pool Municipal Pool 665 MWh +R 1.4 m
Wind Pool Municipal Pool 520 MWh +R 650 k
Firm Pool Commercial Pool 110 MWh +R 94 k
Wind Pool Commercial Pool 109 MWh +R 136 k

Demand bars, Rules order: Commercial 979 MWh, Municipal 1.2 GWh. No shortfall notch.

Looks good: fat coloured ribbons into Sold, a thin amber spill outlet, every live demand bar present. Looks bad: a left stack that is almost entirely amber wash — T1.

Where to go next. A fat leftover from one shelf: open that card on Rules and the joiners in the wiring gutter. Need a buyer for the leftover: Find offtake → Desk (§9). Need the hour: §6.15 then the ledger (§6.18).


6.14 Where the margin is made and lost

The problem. The Margin tile is one number. You still need to know whether you lost money on prices (sold energy was cheap) or on leftover dough (sold energy was fine; unsold energy sank the month).

On screen: #book-margin. Title: Where the margin is made and lost. Intro:

By time of use and by source pool. Sold energy earns; spilled energy loses buy price minus the spill value.

Two small tables, then one verdict sentence.

By TOU (data-role="margin-tou"). Rows in clock order: Peak, Standard, Off-peak, then Battery / untimed when a line has no TOU. Positive margins print green with a leading +; negative ones print rose with −. Empty body: No margin breakdown in this run.

By source (data-role="margin-source"). One row per supply pool that sold, with the pool colour chip, the name, and the word sold. Sorted richest sold-margin first. A final Spill · all pools row (data-role="margin-spill") is the amber chip and the leftover’s rand. Flexible does not appear on T1 — it sold nothing.

The verdict under the tables (margin_note):

When Sentence
Month loses, spill loses, every sold source is ≥ 0 Sold energy makes money in every hour. The loss is entirely the energy that never sells — a wiring and demand problem, not a price problem.
Month loses, but some sold source is also negative The book loses money on what it sells as well as on what it spills; check the buy prices against the sell side.
Month earns, spill still loses Sold energy carries the book; spill is the leak.
Otherwise Margin is positive across the board.

T1 September is the first sentence. Remember: the product says “every hour” while the test is every source pool’s sold margin. The TOU table is allowed to be red — it includes spill.

Where the Overview cousin is taught. Overview §4.8 is a month × hour heatmap of the snapshot. This card is two tables for the picked run.

Worked reading — T1 September P50

By TOU (these rows include spill):

By TOU Margin
Peak −R 2.1 m
Standard −R 5.1 m
Off-peak −R 5.9 m
Battery / untimed +R 12 k

Off-peak is the worst clock band because that is when the book is longest and the leftover is cheapest to dump. The +R 12 k is BESS reserve lines, not a dispatch profit.

By source (sold legs only) plus the spill row:

By source Margin
Solar Pool · sold +R 2.5 m
Wind Pool · sold +R 786 k
Firm Pool · sold +R 94 k
Spill · all pools −R 16.5 m
Sold sources          =  2.5 m + 786 k + 94 k  ≈ +R 3.4 m
Spill                 =                         −R 16.5 m
BESS reserve (untimed)=                         +R 12 k
Month (Margin tile)   =                         −R 13.1 m
3.4 m − 16.5 m + 0.012 m ≈ −13.1 m ✓

Looks good: green TOU rows, green source rows, a small or missing spill row. Looks bad: green sold rows and a spill row that is five times larger — a wiring-and-demand problem. Rewire or sell offtake; do not first cut the sell price.

Where to go next. Price problem → member buy/sell on Rules. Wiring-and-demand problem → gutter and Find offtake. Hour proof → §8 Margin tab.


6.15 Long or short, hour by hour

The problem. A month total can hide a noon glut and an evening gap. You need the shape of a typical day.

On screen: #book-day. Title: Long or short, hour by hour. Intro:

A typical day of the run: supply stacked by pool against the demand line. Above the line is long (spill), below it short (shortfall). The Overview’s clock, now per pool.

A typical day is every line of the run grouped by SAST clock hour (the stored UTC hour + 2), then divided by the number of days in the period. This run is 1 Sep → 1 Oct, so each point is the month’s that-hour total ÷ 30.

How to read the SVG (no hover, no clip strip, no Tomorrow toggle — those belong to Overview §4.6):

  1. X axis. 0h … 23h SAST, labelled every four hours (0h, 4h, 8h, 12h, 16h, 20h).
  2. Y axis. Energy. Ticks use the same compact units as the flow chart (kWh / MWh / GWh). On T1 the noon stack is about 136 MWh, so the axis is in MWh.
  3. Stacked areas. One band per supply pool, coloured like Rules. The engine draws the smallest shelf at the bottom and the largest on top: Flexible, Firm, Solar, then Wind.
  4. Solid ink line = demand that hour (allocated delivered + shortfall). The word demand sits at 23h.
  5. Long vs short. Stack above the line = long (you will spill). Line above the stack = short (you will buy top-up).

Empty copy: No hourly lines in this run.

Worked reading — T1 September, three clock hours

Every hour is long. Demand is a thin ink thread under a tall stack.

SAST Typical-day supply Typical-day demand Long (spill) Plain reading
00:00 50 MWh 2.2 MWh 48 MWh Night wind and firm still dwarf the two live baskets
12:00 136 MWh 3.8 MWh 132 MWh Solar noon is the tallest leftover of the day
18:00 88 MWh 3.0 MWh 85 MWh Evening is still long — there is no shortfall notch

Looks good: the stack follows the demand line; a little amber only at solar noon if you are slightly long; a rose evening only if you sold firm hours you cannot cover. Looks bad: a stack that never touches the line — T1. You are not “a bit long at noon”; you are long for 24 hours.

Where to go next. Noon leftover → sell daytime offtake on Desk, or stop seating more solar until the gutter has a buyer. An evening short (not present here) → firm shelf or Cover shortfall. Hour proof → the ledger.


6.16 Pool caps, this run

The problem. Rules shows a badge on each card. Forecast repeats those badges as a table for this run, so you can quote them next to the tiles.

On screen: #book-caps. Title: Pool caps, this run. Intro: The Rules board’s outcome badges, as a table.

Columns: Pool, Result, Cap / band, and a pill.

Pill Tone Meaning
ok green Inside the spill cap or the coverage band
outside amber Coverage below the min or above the max
breach rose Spill above the cap, or shortfall above the demand card’s max shortfall
— slate No reading

A supply row is {colour chip}{name} spill. Result is the run’s spill %. Cap / band prints ≤ {cap} %. A demand row is {chip}{name} coverage. Result is coverage %. Cap / band prints {min}–{max} % when both ends exist.

Only ACTIVE pools that actually took part (active?) appear. Drafts, archives, and live pools with no energy in the run are omitted. Empty table: No pool took part in this run.

Worked reading — T1 September P50

Pool Result Cap / band Pill
Solar Pool spill 92 % ≤ 15 % breach
Wind Pool spill 98 % ≤ 12 % breach
Flexible Pool spill 100 % ≤ 20 % breach
Firm Pool spill 98 % ≤ 5 % breach
Commercial Pool coverage 100 % 50–60 % outside
Municipal Pool coverage 100 % 60–70 % outside

(97.5 % Firm spill rounds to 98 % on the table.) Industrial and Trader Sales have bands on Rules and no demand in this run, so they are absent. The four breach rows are the same four names on the issues rail. The two outside rows are the over-covered baskets: every hour was served, which is more cover than those cards asked for.

Looks good: every pill ok. Looks bad: a column of breach plus outside — you both dumped most of the flour and over-fed the two baskets that showed up.

Where to go next. Press Rules › on the issues card, or open the named pool on the board. Do not edit a cap to hide a 96 % spill; seat a buyer or take less supply.


6.17 Battery dispatch

The problem. A battery can soak leftover noon energy and give it back in the evening. You need to see whether this run used it.

When the fold exists. #book-battery renders only when the run’s KPI map has bess_arbitrage_margin_r — even if the value is zero. It is a <details> that opens by default. Summary:

Battery dispatch · {member label} · from this run shown only for books with an active battery

T1’s member label is Rosslyn BESS — 5 MW / 20 MWh.

Five mini tiles (data-role="battery-tile"):

Label T1 value Note on T1
Arbitrage margin R 0 for the run
Cycles 0.00 / day degradation priced
Spill absorbed 0.0 % of the book’s spill
Firm hours backed 0 % discharges into arbitrage, not firm shortfall (amber)
Market arbitrage — day-ahead spread (no bess_market_arbitrage_r on this run)

Under the tiles: The dispatched day, the hourly schedule, the rejected-pairs trust device and the asset settings live on the full dispatch page. Open full dispatch › goes to /org/trader-pools/{id}/strategy/bess. The link does not carry ?run= — the destination page loads the book’s latest complete Forecast that already has battery intervals (§11.11).

Where this is taught. This section is the Forecast fold — five tiles and a door. The full /strategy/bess page (header, which run it opens, facts, chart, moves, hour table, empty states) is §11.11. How the engine decides charge, hold and discharge is §11.2.

When the fold is absent. A book with no battery KPIs does not render #book-battery. The fifth tile then becomes Take-or-pay. That is honest: there is nothing to fold.

T1’s honest empty-ish state. The fold is there. The battery did not dispatch. One BESS_CHARGE line (2.3 MWh) and +R 12 k of BESS_RESERVE sit on the run; they do not move the arbitrage tile off R 0 and they do not absorb the 57 GWh spill.

Looks good: cycles above zero, spill absorbed above zero, or firm hours backed above zero. Looks bad: a named BESS and a row of zeros next to a 96 % spill tile.


6.18 The run’s line ledger

The problem. Charts argue. Lines prove.

On screen: #book-ledger-fold — a dashed fold, closed until you open it. Summary:

The run’s line ledger · Allocations · Spill · Shortfall · Margin · Audit one SAST day at a time

The body: Every allocation, spill and shortfall line of this run with its provenance, priced hour by hour. Then Open the run ledger › — the same allocations URL as the meta line under the picker. The destination heading has ← Pool · Forecast (#allocation-back-to-forecast) back to this Forecast for the same pool, month, and run.

This fold does not inline the day table. It is a door.

Where this is taught. The destination /org/trader-pools/:id/strategy/allocations/:run_id — header, ← Pool · Forecast, day picker, every tab, empty states, and the T1 September walk — is §8. Start at §8.6 for the click path.

Use it when a tile surprises you, when you need a line for a dispute, or when you want to compare this run with a superseded companion.


6.19 Find offtake, Cover shortfall, and empty states

The problem. After you have read the leak you still need one obvious next click. Forecast does not invent a third “moves” gallery.

Find offtake (#book-forecast-offtake-cta) is a single line under the ledger, only when this run’s spill is above 20 %:

Spill has no buyer in this run. Find offtake → Desk

The link (#book-forecast-offtake-desk) opens Simulations (/strategy/simulations) — §9. T1 September is 96.4 %, so the line is present.

Cover shortfall (#book-forecast-cover-cta) is the twin, only when unmet demand is above 5 %:

Demand is served at the top-up price. Cover shortfall → Desk

T1 September is 0 % shortfall, so the line is absent. Both lines can appear together on a book that is long in one hour and short in another.

Nominations and Outcomes are not repeated here. They stay on the thread strip.

Empty and partial states you will actually see

State What the page does
No complete forecast yet Headline: No forecast run yet. Run one to see what the engine would do with this wiring. Tiles, charts and tables do not render. Picker still offers New run.
Run in flight Status pill pending / running. Headline may say the run has no figures yet. Read KPIs only from complete.
Failed run Rose failed pill. The previous complete current is unchanged (§6.6).
Run with no allocation lines Flow: No allocation lines in this run. Day: No hourly lines in this run.
No TOU breakdown No margin breakdown in this run.
No pool took part Caps: No pool took part in this run.
No battery KPIs No #book-battery. Fifth tile is Take-or-pay.
Battery KPIs all zero Fold is present; tiles read R 0 / 0.00 / 0.0 % — T1.
Spill ≤ 20 % No Find-offtake line.
Shortfall ≤ 5 % No Cover-shortfall line — T1.
Current calendar month No Run backcast.

What to do next on T1 September

  1. Believe the headline: the customers who showed up were served; the month still loses R 13.1 m on leftover supply.
  2. Open Rules and sit a buyer on the gutter, or press Find offtake → Desk and price a sell-side candidate.
  3. Do not start from the 157 c effective price — that is the thin sold slice.
  4. When you need a line, open the run ledger. When the month has settled, read Outcomes — Forecast will not rewrite itself into a warehouse.

6A. Book · Outcomes — what actually settled

Route: /org/trader-pools/:id/strategy/book?mode=outcomes&month=YYYY-MM · Tab: Book (#strategy-tab-book) · Mode: Outcomes (#book-stage-outcomes on the thread strip; BookLive). The old …/book?month= link and the old …/chains route open here.

A trader buys from several sources and sells to several sinks in the same month. Forecast (§6) answers “what would the engine do?” Outcomes answers “what actually cleared?” — every buy leg and sell leg on which this pool sat, the warehouse rule that you cannot have sold more than you procured, the chains that make the month up, and how far the forecast missed the ledger.

Think of Book as a warehouse stocktake. Forecast is the bake sheet you wrote before the month. Outcomes is the till tape after the shop closed: who delivered flour, who left with bread, and whether you sold more loaves than you ever took in.

6A.1 The trader’s problem

Opening one PPA’s settlement detail shows one leg. Your commercial question is the book: who gave me energy, who did I give it to, does Σ sell ≤ Σ procured still hold, and did the plan I ran a month ago look anything like this?

6A.2 What you see

The table is a map. Each block is taught in full from §6A.5.

Region Job
Thread strip · issues rail The same strip as the other modes; Outcomes is the lit stage. On T1 today that pill is September · −R 469 k · not balanced — not the older August · −R 381 k figure
Headline One sentence from the ledger. Pick August and you get a buy-only month. Pick September and you get the 7.2 GWh paper sale
Month picker The last six months as chips, each with balanced · not balanced · nothing settled; a month input and arrows for anything older
Procured against sold Two bars: what came in from suppliers, what went out to buyers, with the honest ceiling marked and any sold energy that has nothing behind it in red. Under it the book check
The month’s money Bought (buy legs), network borne, sold (sell legs), gross and net margin — own seat only — with a note comparing the forecast’s P50 for the month against the settled net
Procured (buy legs) · Sold (sell legs) Counterparty + kWh for every period where this pool is the buyer-trader or the seller-trader, with Σ totals
Chains The month’s chains with balance badges, an Unbalanced only filter, and one chain opened to its rail and volume bridge (§6B)
Forecast said, book settled P50 margin at forecast time against the settled net margin, last six months, with a verdict sentence. A snapshot on a twelve-month run is scaled to one month before it is compared
Three moves Cover or cancel the uncovered sale, reconcile forecast to ledger, read the six-month story on the Dashboard. Outcomes keeps this strip. Forecast dropped it

Data is assembled by Statement.TraderBook.build/3 and ChainExplorer — the same projections statements use. No settlement maths is redone; line amounts and period totals are read off the ledger.

Follow along. Seat: trader_1@webill.net (password supersecret). Path: Trader Pools → T1 Renewables Pool → Strategy → Allocation → Outcomes. Deep link: /org/trader-pools/01a0ab54-e46b-7dde-b45f-73d119213c75/strategy/book?mode=outcomes&month=2026-09. You should see the thread strip, the headline, the two bars and the book check, the money ledger, the buy/sell panels, the chains and the three move cards.

6A.3 How to read it

  1. Read the badge before you argue a month commercially. A red badge means a sell leg has no supply behind it — a paper commitment, or supply legs missing from settlement.
  2. Buy legs are “who gave me what”; sell legs are “who I gave it to”.
  3. The upper bar is the most that can honestly be sold. Sold energy past it is the red segment, and the same energy shows as uncovered out-legs in the book check.
  4. Net margin is your seat’s P&L (sell revenue − buy cost − network you bore). Counterparty prices never appear.
  5. The drift panel is the reconciliation: if the forecast prices thirty times the supply that settles, fix the wiring on the Rules board before trusting the forecast money.

6A.4 Explanations — How to Read Outcomes

Explanations (#book-explanations-open) sits to the right of the Outcomes headline. Same drawer shell as §5.8. Eyebrow: Book · Outcomes.

How to Read the View is the warehouse order: thread strip, headline, month picker, procured against sold, the month’s money, buy legs · sell legs, chains, forecast said versus book settled.

The A–Z list is the words on Outcomes (Balanced through Warehouse rule). It does not repeat the Rules gutter or the Forecast flow chart.

The walk below is that same order, with every control and the T1 numbers.


6A.5 How to read Outcomes, block by block

A dashboard number you can edit is a wish. Outcomes is a warehouse stocktake for one settled month. You cannot type a new net onto the money card. You pick another month, or you open a chain and prove a leg.

This mode does not change the wiring. That is Book · Rules. It does not run the engine. That is Book · Forecast. It answers: who gave me energy, who did I give it to, and did I sell more than I bought?

Follow along. Seat: trader_1@webill.net (password supersecret). Path: Trader Pools → T1 Renewables Pool → Strategy → Allocation → Outcomes on the thread strip (#book-stage-outcomes). Deep link: /org/trader-pools/01a0ab54-e46b-7dde-b45f-73d119213c75/strategy/book?mode=outcomes&month=2026-09. You should see the eyebrow Book · Outcomes, a headline that names September’s 7.2 GWh sale, then the conservation chart beside the money card.

Data. full_demo · seed 42 · T1 Renewables Pool (01a0ab54-e46b-7dde-b45f-73d119213c75) · last read 2026-09-19 from TraderBook.build/3 and settlement_periods on wb_wheeling_dev. Compact Rand follows the product (−R 469 k, R 12.9 m). Energy labels follow the product too (460 MWh, 7.2 GWh). The live Outcomes URL was not opened in a browser this pass — Phoenix was up; the login door blocked automation. The numbers are the same projections the page renders.

On screen, top to bottom

Order Block DOM id
Shell Heading Book — Outcomes. Subtitle: How the book is wired, what the engine will do with it, and what actually settled — one thread across three views. First paint: Loading the book…. #org-page-heading, #trader-book[data-mode=outcomes]
1 Thread strip, then the issues rail #book-thread, #book-stage-outcomes, #book-issues
2 Eyebrow Book · Outcomes, headline, lede, Explanations #book-outcomes, #book-outcomes-headline, #book-explanations-open
3 Month arrows, month input, six chips, recomputed stamp #book-month-picker, [data-role=chains-computed-at]
4–5 Procured against sold · The month’s money #book-conservation, #book-money
6–7 Procured (buy legs) · Sold (sell legs) #trader-book-buy, #trader-book-sell
8 Chains list and the opened chain #trader-chains, #chains-list, #chains-detail
9 Forecast said, book settled #book-drift
10 Three next-move cards #book-moves

#book-moves is Outcomes-only. Forecast has no three-card strip (§6.9). Rules has none either. Nominations stay off this page — they are not a #strategy-nav tab. The three ranked cards stay here so a broken warehouse has an obvious next click.

What “looks good” vs “looks bad” on this whole page. Good: green Σ sell ≤ procured, chains balanced, forecast and settled net sit close, the issues rail is quiet on this month. Bad — and this is T1 September — the lower bar runs 15.7× past the upper one, three sell legs sit outside any linear chain, and the month loses R 469 k on a 7.2 GWh paper sale.


6A.6 Route, Book tab, thread strip and issues rail

The problem. You can open Outcomes from four doors and lose the rest of the Book. The strip is how you stay on the same tab.

#strategy-nav. Overview · Allocation · Desk · Dashboard. Allocation is lit (#strategy-tab-book.tab-active). Outcomes is not a fourth room tab. There is no #strategy-tab-book-outcomes and no #book-mode-switch on this page. Book stays the tab; the thread strip switches the mode.

How you get here.

Door What it does
Thread strip Outcomes (#book-stage-outcomes) Opens …/book?mode=outcomes with no month — the LiveView then defaults to last calendar month (August on a 19 Sep 2026 clock)
This URL with &month=YYYY-MM Pins the warehouse to that month. A shared link reproduces the view
Old …/book?month=YYYY-MM (no mode) Still Outcomes. The month query is enough
Old …/chains?month=&chain= Forwards into Outcomes with the same month and chain

The default month and the strip’s month are not the same clock. The page without ?month= lands on today minus one month. The strip names the last month that has any received or supplied energy, walking back at most six months from today. On T1 that last month is September, even if you then pick August in the chips.

Thread strip (#book-thread). Three stages, left to right:

Stage Eyebrow Id What the body shows
Rules Rules · how the book is wired #book-stage-rules Live pool and member counts. Pill: cap verdict.
Forecast Forecast · what the engine will do #book-stage-forecast Month, grade and compact margin.
Outcomes Outcomes · what actually settled #book-stage-outcomes Last month with settlement energy, compact net, pill balanced / not balanced. Nothing settled: Nothing settled yet.

Outcomes is ringed (data-on=true) on this mode. A negative net prints rose; a positive one prints brand green. Clicking a stage navigates; it does not re-settle a period.

On T1, 19 Sep 2026, the Outcomes stage reads September · −R 469 k with pill not balanced. The note under it is 7.2 GWh sold against 460 MWh bought · 3 sell legs with no supply behind them.

That is not the older August · −R 381 k · not balanced line. August is a different warehouse: 186 MWh bought, nothing sold, the warehouse rule holds, net −R 196 k. Do not paste an Overview figure onto this strip. Confirm the month word and the pill before you quote the net.

Where the strip is taught. The three-stage Book thread — §5. This section only names what Outcomes lights and which month it prefers.

Issues rail (#book-issues). Ranked cards under the strip, each with a colour dot (rose = bad, amber = warn, slate = info), a title, a body, and a door (Rules › / Forecast › / Outcomes ›). The September-unbalanced card is the Outcomes one:

September book does not balance 7.2 GWh sold against 460 MWh bought. 3 out-legs uncovered. Outcomes ›

T1 also carries the Forecast/Rules cards the other modes already taught: spill around 96 % of supply, coverage outside its band on Commercial and Municipal, and a draft pool with no members. Those doors open Rules or Forecast. They do not change the warehouse.

When no month in the last six has energy, the rail adds Nothing has settled yet and points at Outcomes.


6A.7 Headline, lede and Explanations

The problem. The charts are true and still easy to argue past. The headline is the one sentence the ledger wants you to believe first.

Eyebrow. Small brand-green caps: Book · Outcomes. Same pattern as Forecast’s Book · Forecast.

Headline (#book-outcomes-headline). One sentence from the month’s statement and book check. The recipe, in order:

  1. No statement at all: {Month Year} has no settled legs yet.
  2. Statement exists, but both sides are zero: {Month} settled nothing: no buy leg and no sell leg reached FINAL.
  3. Book check is not balanced (T1 September): {Month} settled {bought} bought and {sold} sold — the book does not balance: {N} sell leg(s) have no supply behind them, and the month lost (or made) {abs net}.
  4. Something bought, nothing sold (T1 August): {Month} settled {bought} bought and nothing sold — the book carried {abs net} of supply cost with no revenue against it.
  5. Otherwise: bought, sold, balanced, and a net loss or margin.

T1 September hits rule 3:

September settled 460 MWh bought and 7.2 GWh sold — the book does not balance: 3 sell legs have no supply behind them, and the month lost R 469 k.

T1 August hits rule 4:

August settled 186 MWh bought and nothing sold — the book carried R 196 k of supply cost with no revenue against it.

T1 June hits rule 2 (a statement with empty legs):

June settled nothing: no buy leg and no sell leg reached FINAL.

Lede (the grey line under the headline). Always: What the ledger says happened, one settled month at a time. The statement first, the chains that make it up underneath, and the forecast that predicted it beside it. A month that does not conserve energy is flagged before any money is read.

Explanations (#book-explanations-open) sits to the right of that pair. The drawer, the How to Read fold, and the A–Z list are §6A.4. Eyebrow inside the drawer: Book · Outcomes. Close with #book-explanations-drawer-close, the backdrop, or Escape. The walk you are reading is the How to Read order written out.

Outcomes does not open the Forecast New run modal. There is no #book-new-run on this mode.


6A.8 The month picker

The problem. A book has several closed months. Mixing them on one canvas would lie. The picker makes you choose.

Arrows. Ghost chevrons (phx-click="shift_month", by="-1" / by="1"). Each click patches ?month= one calendar month and clears any selected chain.

Month input. type=month, aria-label="Settlement month", phx-change="select_month". Changing it patches ?month=YYYY-MM. September cannot explain August.

Chips (#book-month-picker). The last six calendar months from today, newest first, each a patch link:

…/book?mode=outcomes&month=YYYY-MM

Chip What it carries
Label Mon YYYY — Sep 2026, Aug 2026, …
Selected Dark ring (selected?)
Settled and balanced Green pill balanced
Settled and not balanced Rose pill not balanced
No received or supplied energy Slate pill nothing settled

A month is settled on a chip when the book check sees received kWh or supplied kWh above zero. Status FINAL is not required. T1 September is still DRAFT on every September period — the chip still reads not balanced, because the energy is there.

On a 19 Sep 2026 clock the six chips are Sep, Aug, Jul, Jun, May, Apr:

Chip T1 pill
Sep 2026 not balanced (460 MWh in, 7.2 GWh out)
Aug 2026 balanced (186 MWh in, nothing out)
Jul 2026 balanced (187 MWh in, nothing out)
Jun 2026 nothing settled
May 2026 nothing settled
Apr 2026 nothing settled

Recomputed stamp ([data-role=chains-computed-at]). When the chain index has a clock: recomputed {dd Mon HH:MM}. Honest “as of now”, not an issued report. Empty when the index has no timestamp.

The URL also keeps &chain= and &unbalanced=1 when those filters are on. Changing the month drops the chain. Toggling the filter keeps the month.


6A.9 Procured against sold — the conservation chart

The problem. Two tables of counterparties do not show, at a glance, whether you sold more than you bought. The chart is the warehouse door.

Card (#book-conservation). Title Procured against sold. Helper: Energy conservation for the month. In-legs are what the book received from its suppliers; out-legs what it delivered to buyers. Sold cannot exceed bought unless a sell leg is a paper commitment with no chain behind it.

How to read the SVG (role="img", Procured against sold energy):

  1. Bought · in — the upper green bar. Length is procured kWh (delivered on buy legs). The number to the right is the compact label (186 MWh, 460 MWh).
  2. Sold · out — the lower demand-coloured bar. Length is sold kWh (supply on sell legs), clipped to what was bought.
  3. Red tail — only when sold > procured. It starts at the bought ceiling and runs to the sold tip. The label adds · {energy} with nothing behind it.
  4. Dashed vertical — drops from the bought tip. Caption: what was bought · the most that can honestly be sold.
  5. Sentence under the bars. Over: A balanced month has the lower bar no longer than the upper one. This month is {ratio}× over. Inside: Sold energy sits inside what was bought. Empty: Nothing sold this month.

T1 August — nothing sold, so no red tail:

Bought · in → 186 MWh Sold · out → 0 kWh Sentence: Nothing sold this month. (the sold bar is empty; the ceiling still marks 186 MWh.)

T1 September — the picture you open the page to see:

Bought · in → 460 MWh Sold · out → 7.2 GWh · 6.7 GWh with nothing behind it Sentence: A balanced month has the lower bar no longer than the upper one. This month is 15.7× over.

7.2 GWh is 7,200,000 kWh on one OffTaker A period. 460 MWh is 459,740 kWh delivered on the IPP3 buy legs. 7,200,000 ÷ 459,740 ≈ 15.7. The red tail is the paper sale.

Book check ([data-role=book-check]), under the SVG:

Book check · {fan-out · }{N} in-legs · {N} out-legs · {N} uncovered

Word Plain meaning
In-legs Buy periods this month — this pool is the buyer-trader
Out-legs Sell periods this month — this pool is the seller-trader
Uncovered Uncovered out-legs — sells that sit on no linear chain
fan-out · Prefix when uncovered > 0. The book sold to a sink the chain walk did not keep (fan-out)
Badge ([data-role=book-balance-badge]) Green Σ sell ≤ procured or rose Sold more than procured

August: 2 in-legs · 0 out-legs · 0 uncovered and green Σ sell ≤ procured.

September: 5 in-legs · 4 out-legs · 3 uncovered and rose Sold more than procured. The chain walk keeps one next hop; the other three September sells never join a linear path. Book still owns them. That is why the statement and the chain list can disagree on count — §6B.8.

Empty card. When there is no statement, the two-column grid is replaced by a dashed panel: No settled statement for {Month Year}. June on T1 still has a statement (empty legs), so you get the chart at zero rather than this dashed empty. The dashed empty is the “Ash could not build a statement” state.


6A.10 The month’s money

The problem. Energy conservation is not a P&L. You can pass the warehouse test and still lose money — or fail it and still invoice a sliver.

Card (#book-money). Title The month’s money. Helper: From what was bought to what was kept, own seat only.

Five rows ([data-role=money-row], data-key on each). Costs print with a minus; revenue with a plus. Gross and net are extrabold. The net cell is [data-role=net-margin].

Key Label What it sums T1 August T1 September
buy Bought · {N} buy leg(s) Your trader_buyer energy lines, as a cost. Note: energy at PPA prices −R 158 k (2 buy legs) −R 391 k (5 buy legs)
network Network borne Your buy-side wheeling, transmission, distribution and ancillary. Note: wheeling, use-of-system and losses on the buy side −R 37 k −R 92 k
sell Sold · {N} sell leg(s) Your trader_seller energy lines. Note: only covered legs invoice R 0 (no sell legs) +R 14 k (4 sell legs)
gross Gross margin Sell − buy, before network −R 158 k −R 377 k
net Net margin Gross − network. Note: after network −R 196 k −R 469 k

Exact cents behind the compact labels, August: buy 15,841,730 · network 3,727,466 · sell 0 · net −19,569,196. September: buy 39,077,875 · network 9,194,793 · sell 1,384,933 · net −46,887,735.

Imbalance, curtailment credits, trader-margin lines and levies sit on the ledger. They do not appear on this card. The card is the seat’s energy-and-network story, not a restatement of every category.

Forecast note under the list, when the drift series has a P50 for a month: The forecast for {Month} said {P50} at P50; the ledger settled {net}. See the drift panel. On T1 September that is The forecast for September said −R 12.9 m at P50; the ledger settled −R 469 k. The plan priced leftover supply the warehouse never bought.

Counterparty prices never appear. You see your cost, your network, your revenue.


6A.11 Procured (buy legs) and Sold (sell legs)

The problem. The bars collapse counterparties. You still need the names.

Two tables, side by side from lg up.

Procured (buy legs) (#trader-book-buy). Columns Source and kWh. One row per buy period ([data-role=buy-leg]). Footer Σ buy ([data-role=procured-kwh]) when the list is not empty. Empty body: No settled buy legs this month.

kWh is a whole number, no compact MWh label — 186373, not 186 MWh. The compact label lives on the conservation chart.

T1 August

Source kWh
IPP1 Sandton Solar 0
IPP3 Midrand Hybrid 186373
Σ buy 186373

T1 September

Source kWh
IPP1 Sandton Solar 0
IPP3 Midrand Hybrid 228335
IPP3 Midrand Hybrid 0
IPP3 Midrand Hybrid 0
IPP3 Midrand Hybrid 231405
Σ buy 459740

IPP1’s DEMO-SUPPLY period is a live buy PPA that delivered nothing. It still counts as an in-leg. IPP3 is the thread-cast generator (IPP3 Midrand Hybrid). Several September rows share one agreement because settlement stored more than one period start in the month.

Sold (sell legs) (#trader-book-sell). Columns Sink and kWh. Rows [data-role=sell-leg]. Footer Σ sell ([data-role=sold-kwh]). Empty body: No settled sell legs this month — that is August.

T1 September

Sink kWh
OffTaker A Rosebank Mall 0
OffTaker A Rosebank Mall 0
OffTaker A Rosebank Mall 0
OffTaker A Rosebank Mall 7200000
Σ sell 7200000

OffTaker A Rosebank Mall is the thread-cast sink. 7,200,000 kWh on one period is the paper sale the red tail is made of. Delivered on that same period is only 16,293 kWh — the table shows supply kWh on sell legs, not delivered. That is deliberate: the warehouse asks what you committed, not what the customer took.

There is no sort, no filter, and no row click on these tables. To study a path, use Chains.


6A.12 Chains — pick a path

The problem. The statement is the whole warehouse. A break usually lives on one route. Chains is the map of those routes.

Where this is taught. Every card on an opened chain — rail, volume bridge, money, legs, book-check strip — is §6B. This section is the Outcomes chrome around that detail: the list, the filter, the click, and what T1 shows.

Layout (#trader-chains). List on the left (#chains-list, four columns from xl). Detail on the right (#chains-detail, eight columns) when a chain is selected. When none is selected: a dashed panel, Select a chain to study the volume bridge and margin.

List header. Chains · {total} ([data-role=chains-verdict]). When unbalanced > 0, a rose pill {N} unbalanced ([data-role=chains-unbalanced-count]).

Unbalanced only (#chains-unbalanced-toggle). Ghost border when off; rose btn-error when on. Click patches &unbalanced=1 (or drops it). The list then hides balanced paths. The URL is shareable.

Empty list (#chains-empty). No chains for this month — or No chains for this month (unbalanced filter on) when the toggle hid everything. August on T1 is the first form: buy-only months have no linear IPP → you → sink path of two or more legs. Turn the filter on in June and you get the second form (the LiveView test asserts that copy).

A row. Button #chain-row-{head_period_id}, data-role="chain-row", data-balanced="true|false". Body:

Click patches &chain={head_period_id}. The selected row is lightly highlighted. A deep link may pass any leg’s period id; the screen still opens the whole chain.

What opens on the right (#chains-detail → <.chain_detail>):

Block Id What you do with it
Lifecycle mismatch #chains-lifecycle-mismatch Amber, only when one leg is FINAL and another is still DRAFT / PRELIMINARY. September on T1 is all DRAFT, so this card usually stays down. Do not compare a future re-run to an immutable close
Investigation order #chains-investigation Numbered checklist when the chain is broken. Red steps are the ones that look relevant. It does not press buttons for you
The rail #chains-rail Left-to-right hops with kWh, a status chip, and Σ=0 / Σ≠0
Volume bridge #chains-bridge First-leg supply, minus loss / spill / banked, equals expected delivery, versus last-leg delivered. Unexplained must be ~0 ✓. A red residual is the named volume break
Money #chains-money sell − buy − network borne = margin. Your margin is your seat. Chain margin appears only when it differs
Legs #chains-legs One hop per row. Period and Ledger open the contract rooms. hidden replaces the links on a silhouette hop
Book check strip #chains-book-check The month’s warehouse (received ≥ supplied), plus an amber fan-out notice when sells sit outside any chain. Book → (#chains-to-book) patches Outcomes for the same month — you are already there

T1 September should open the IPP3 → You → OffTaker A path. Expect a BREAK or a loud unexplained residual: the sell supply is 7.2 GWh and the buy delivered is hundreds of megawatt-hours. That is the same 15.7× the conservation chart already shouted.

August has no chain to click. The dashed Select a chain… panel stays up.


6A.13 Forecast said, book settled

The problem. A plan that prices energy the ledger never saw will keep sending you to Desk. The drift panel is the six-month argument.

Card (#book-drift). Title Forecast said, book settled. Helper: P50 margin at forecast time against the settled net margin, last six months. The gap is forecast error you are paying for. This is the trader cousin of IPP Allocation’s Forecast vs settled card — same idea, different ids and a book-level net rather than a buyer carve.

How to read the SVG (Forecast margin against settled margin by month):

  1. X axis — six month ticks (Mar … Sep when September is selected), ending on the picker month.
  2. Y axis — compact Rand, including below zero.
  3. Dashed grey line — forecast P50 (forecast_r). A twelve-month snapshot is scaled to one month (margin × 30 / days when the run is longer than 45 days) before it is plotted.
  4. Solid green line + dots — settled net (settled_r), only for months that have procured or sold energy.
  5. Legend (top right): dashed · forecast P50   solid · settled net.

Verdict ([data-role=drift-verdict]). No pair: No month has both a forecast snapshot and a settled statement yet. Otherwise: The forecast misses the ledger by about {average absolute gap} a month across {N} month(s). Fix the wiring before trusting the forecast money.

T1 September has a forecast snapshot around −R 12.9 m (the same order as the Forecast headline’s −R 13.1 m / −R 12.2 m) and a settled net of −R 469 k. The gap is about R 12.5 m. The plan assumed leftover supply would keep losing money at forecast scale; the ledger only bought 460 MWh and then booked a 7.2 GWh paper sale. Neither number is the one you want — and they are not the same number.

Empty SVG. When no month in the window has a snapshot or a statement: No forecast snapshots or settled statements in the last six months yet.

Pick August and the window is March–August. September’s snapshot drops off the right. July and August then have settled nets (about −R 196 k each) and usually no matching P50 snapshot — the verdict falls back to No month has both… until a snapshot lands in that window.


6A.14 The three moves — Outcomes only

The problem. After you have read the warehouse you still need one obvious next click. Forecast solved that with a single Desk line. Outcomes keeps a three-card strip.

#book-moves. Three columns from lg. Each card is [data-role=book-move] with data-key. The first card has the brand border. Open › is the door. The worth figure sits on the right.

This strip does not render on Forecast or Rules. Do not look for it under the Forecast ledger. Do not remove it from Outcomes to “match” Forecast.

Key Title Body (product copy) Worth Open › goes to
cover_sale Cover or cancel the uncovered sale {sold} sold on paper against {bought} bought. Either supply legs are missing from settlement or a sell leg should not be active. The month’s compact net. Note: the month’s net Same Outcomes month (…/book?mode=outcomes&month=YYYY-MM) so you can open a BREAK chain
reconcile Reconcile forecast to ledger Check which supply members have settlement periods; the Rules board shows the ones that never settle. — · wiring Book · Rules (…/strategy/pools)
dashboard Read the six-month story The Dashboard carries these months forward: margin, spill, and who the counterparties were. — · history Dashboard (…/strategy/dashboard, #strategy-tab-dashboard)

cover_sale is omitted when the book check is missing or the month is balanced. August on T1 therefore shows two cards (Reconcile, Dashboard) in the three-column grid. September shows all three. The first September card is the cover-or-cancel one, worth R 469 k.

There is no fourth card for Nominations. Nominations is not a strategy-nav tab. The thread strip already sits above the page.


6A.15 Empty states, refusals and what this page is not

The problem. A quiet page is easy to misread as “the book is fine.” These are the empty and partial states the LiveView actually paints.

State What the page does
No statement for the month Dashed panel: No settled statement for {Month Year}. No conservation chart, no money card, no buy/sell tables. Chains and drift still render
Statement with zero legs Headline rule 2. Bars at zero. Nothing sold this month. Buy/sell tables show their empty copy. T1 June
Buy-only month Green warehouse badge. Sell table: No settled sell legs this month. Chains empty. Two move cards. T1 August / July
Unbalanced month Rose badge, red tail, three move cards. T1 September
No chains #chains-empty: No chains for this month
Unbalanced filter hides every row #chains-empty: No chains for this month (unbalanced filter on)
No chain selected Dashed Select a chain to study the volume bridge and margin.
No drift points No forecast snapshots or settled statements in the last six months yet.
DRAFT periods Still in the statement. Chips can read balanced / not balanced before anyone presses FINAL. September on T1 is this state — do not treat it as a closed warehouse
REVERSED periods Dropped. A reversed re-run is not a trade
Nothing in the last six months Thread: Nothing settled yet. Issues rail: Nothing has settled yet

What Outcomes does not do

What to do next on T1

  1. Believe the strip: the last month with energy is September, −R 469 k, not balanced. Do not quote August · −R 381 k from an older Overview pass.
  2. Pick August when you want a clean FINAL buy-only month (186 MWh, −R 196 k, warehouse holds).
  3. Pick September when you want the 7.2 GWh paper sale. Read the red tail, then open the BREAK chain, then press Cover or cancel the uncovered sale.
  4. If Forecast still prices −R 12.9 m against a −R 469 k ledger, open Reconcile forecast to ledger and fix members on Rules before you trust the plan.

Where this is taught next. End-to-end path health on the same pool — §6B Chains. Per-contract settlement detail — V8 §12. The forward view — §6. Chain / trader P&L concepts — V8 §10.

6B. Settled Chains — end-to-end path health

Route: …/trader-pools/<id>/strategy/book?mode=outcomes&month=YYYY-MM&chain=<period_id> · Tab: Book · Mode: Outcomes, the chains section (the old /chains route forwards here with its month and chain)

The statement at the top of Outcomes (§6A) answers one warehouse question for the whole month: did I sell more than I bought? The Chains section under it answers a different question: for each path from a generator, through me (and maybe another trader), to an off-taker — does the energy story and the money story still make sense?

Think of Book as your warehouse stocktake. Chains is walking each delivery route on the map and checking that what left the plant can explain what arrived at the customer, after the losses and spill the deal allows — and that your margin on that route is the one you expect.

6B.1 The trader’s problem (in plain words)

You often have two (or more) PPAs that are each fine on their own:

Opening either contract’s settlement page only shows that one deal. Nothing on that page proves the two legs still form one coherent trip. Energy can “leak” between them (more left the plant than can be explained by delivery + loss + spill), or one leg’s books can fail the sum-to-zero test while the other looks clean.

Chains finds those linked legs for the month, lays the path out, and lets you study a break without rebuilding a spreadsheet.

Follow along. Seat: trader_1@webill.net (password supersecret). Path: Org → Trader pools → T1 strategy → Allocation → Outcomes; the chains sit under the statement. Pick a month that has settled legs (e.g. July 2026 on full_demo). You should see the verdict strip, a chain list, and — after selecting a row — the rail, volume bridge, money, legs table and book check.

6B.2 How Chains differs from Book and from Runs

Room Question it answers
Book · Forecast (…/book?mode=forecast) What would the forward strategy engine do?
Book · Outcomes — the statement (…/book?mode=outcomes) For the whole month, did Σ sell ≤ Σ procured?
Book · Outcomes — the chains (…&chain=) For each linear path, does volume + ledger still hold?

Chains only discovers linear paths (IPP → trader → … → off-taker). If you sell to two sinks from one buy, the engine may show one chain and leave the other sell for Book — that is called out in the book-check strip (§6B.8).

Deep theory (balanced meaning, investigation order, lifecycle mismatch) lives in V8 §10 and the screen walk in V8 §10.6. This chapter is the trader Strategy-tab guide: every card and every field.

6B.3 Page chrome (above the cards)

Control What it is What it means
Title Chains — {Month Year} Which calendar month you are reconciling
Subtitle Pool name · “linear paths IPP → trader → … → off-taker · as recomputed now” Reminds you these results are calculated when you open/change the month — not a saved audit file
‹ › and month input Step or pick YYYY-MM Changes ?month= and reloads chains
Unbalanced only Toggle (turns red when on) Hides healthy chains so you only hunt breaks

The strategy shell tabs are Overview · Allocation · Simulations · Nominations · Dashboard · Exposure — same pool context as everywhere else in Strategy; the chains are a section of the Book's Outcomes mode, not a tab of their own.

6B.4 Verdict strip (month health)

White card under the title. Read it before you pick a chain.

Field Plain meaning
N chains How many end-to-end paths the system found for your pool this month
N balanced Paths that pass both checks: every leg’s ledger sums to R 0.00, and first-leg supply is at least last-leg delivered
N unbalanced Paths that fail one or both checks (shown in red when > 0)
recomputed {date time} When this page last ran the numbers — honest “as of now”, not an issued report

If total is 0, the empty list explains: no multi-leg chains for that month (or the unbalanced filter hid everything).

6B.5 Chain list (left / master)

Field on each row Plain meaning
Path label Who → who → who (e.g. generator name → You → off-taker). “You” is this trader pool
N legs How many PPA settlement periods sit on that path (usually 2)
balanced / BREAK badge Green = path OK; red BREAK = investigate this row

Click a row to select it (?chain= becomes that chain’s head period id). The selected row is lightly highlighted. Deep links from a period detail page may pass any leg’s period id; the screen still opens the whole chain.

When nothing is selected (empty month), the right side says: Select a chain to study the volume bridge and margin.

6B.6 Detail column — cards in reading order

Once a chain is selected, read top to bottom: warnings → picture of the path → volumes → money → per-leg table → warehouse cross-check.

Lifecycle mismatch (amber, only when needed)

Shows when one leg is FINAL and another is still DRAFT / PRELIMINARY (or similar). Plain meaning: do not treat those two closes as the same kind of truth. Fix or understand status first (V8 §10.5).

Investigation order (when the chain is broken or mismatched)

Numbered checklist (volume before money). Steps that look relevant to this break can highlight in red. It does not run actions for you — it is the order to work through.

The rail

A left-to-right cartoon of the path:

Piece Data Plain meaning
Start node Party label Who energy enters from (often the IPP; may say You if you are the seller on a later hop)
Edge ── {kWh} ──▶ Energy on that hop (delivered kWh for the leg)
Status chip DRAFT / FINAL / … How hard that leg’s settlement is
Σ=0 / Σ≠0 Tick or red fail Does that leg’s own ledger sum to zero?
Next node Party label Who receives that hop (You, off-taker name, or italic silhouette if you are not a party to that hop)

Silhouette / italic nodes mean: you may see the kWh for the bridge, but not that stranger’s money — same privacy idea as statements.

Volume bridge

This is the study table: can supply explain delivery?

Row Plain meaning
First-leg supply kWh that entered the chain at the first PPA (plant / source supply)
− permitted loss (x%) Network loss allowed along the chain (factor shown when known)
− contract spill Surplus the deal treats as spill, not delivery
− banked Energy parked in banking adjustments instead of delivered now
= expected delivery What should remain after those deductions
Last-leg delivered What the final buyer actually received
Unexplained Expected minus delivered. 0 ✓ (within 1 kWh) means the bridge closes. A non-zero red number is the named volume break — nothing is quietly swept under the carpet (g-unexplained-kwh)

Money

Row Plain meaning
Formula line Always: sell − buy − network borne = margin
Buy cost What you paid on buy legs (shown as a cost)
Sell revenue What you earned on sell legs
Network borne (you) Network / UoS-style charges on your seat
{agreement} connection Per-leg network amount (evidence only — not a “no double-count ✓” verdict)
Your margin Your seats only on this chain — the number you care about commercially
Chain margin (optional) All trader seats on the path; shown when it differs (e.g. trader–trader hop). Never treat chain margin as your P&L on a multi-trader path

Legs table

One row per hop, in chain order:

Column Plain meaning
# Order on the path (1 = head)
Leg From → to labels
Agreement PPA agreement reference (monospace)
Status Settlement status chip
Supply That period’s supply kWh
Delivered That period’s delivered kWh
Σ ledger Sum of line items on that period; ✓ if zero, ✗ if not — names a broken leg
Period / Ledger Drill into existing contract rooms (only on legs you are party to)
hidden Shown instead of links when the leg is a silhouette for your seat

Book check strip

Field Plain meaning
received … ≥/< supplied … ✓/✗ Your whole-month warehouse check (same spirit as Book): energy you took in vs energy you pushed out
Fan-out notice (amber, when needed) “N sell leg(s) are not part of any linear chain — book view covers them.” Linear discovery missed a fork; open Book
Book → Jump to §6A for the same month

6B.7 How to use the screen when something is red

  1. Read the verdict — how many breaks this month?
  2. Turn on Unbalanced only if the list is long.
  3. Open a BREAK row.
  4. If Lifecycle mismatch shows, stop comparing FINAL to draft numbers.
  5. Read the rail — which hop shows Σ≠0?
  6. Read Unexplained on the bridge — that quantity is the volume story.
  7. Only then trust Your margin on the money card.
  8. Use Period / Ledger links to prove a single leg in the full settlement UI (V8 §12).
  9. Confirm Book check still agrees with the warehouse.

6B.8 Book check strip and fan-out

Chains never pretends to list every commercial relationship you have. It lists linear discovered paths. Book still owns fan-in / fan-out aggregates. When the strip warns that sell legs sit outside any chain, that is expected for some books — not a silent failure of Book.

6B.9 What this screen does not do

Where this is taught next. Mechanism and worked bridge numbers — V8 §10. Screen blocks in settlement vocabulary — V8 §10.6. Warehouse aggregate — §6A.

7. How the engine allocates (what a run actually does)

Before reading a run detail, it helps to know the walk the engine performs for every hour of the period. It is deterministic — same inputs, same result, always — and it has two hardwired stages followed by the configurable merit order:

7.1 The allocation walk

  1. Build the hour's supply stack. Every active supply member contributes its forecast (or nominated) kWh for this hour, capped by MW caps. The stack is merit-ordered: pool priority first (Solar 10 before Wind 20 before Flexible 30 before Firm 40 in the seeded book), then cheapest buy price first within a pool, then member priority.

  2. Serve firm demand first — hardwired. Demand pools flagged firm are served before anything else, and they draw on FIRM-pool supply first, then whatever else remains. This is not a rule you can reorder or delete; it is the invariant that your contractual must-serve obligations are always covered before discretionary sales. It is also why the seeded Firm supply pool sits last in the open merit order — it is being held in reserve for exactly this step.

  3. Serve open demand in priority order. Remaining demand pools are walked by priority (Industrial 10, Commercial 20, Municipal 30…). Each pool drains the supply stack in merit order; members at the same priority share pro-rata (§5.4). Pool rules (MW_CAP, PRICE_OPTIMISE, NOMINATION…) apply as each edge is drained.

  4. Whatever supply is left is spill; whatever demand is left is shortfall. Spill is routed to the pool's spill destination and valued at the member's spill value (zero if unset) — for take-or-pay supply that margin is negative: you paid for energy with no buyer. Shortfall on firm demand is priced as a grid top-up: buy at the member's shortfall top-up c/kWh, sell at the contract rate — usually a locked-in loss that the engine makes visible rather than hiding.

7.2 How each flow is priced

Every allocation line prices its energy the way settlement would:

The scenarios below use one-hour slices so every quantity can be followed from the allocation decision to the line price. Together they cover the five line kinds you will meet most often: normal allocation, firm shortfall, spill, battery charge and battery discharge. Each scenario opens with a one-sentence plain reading; the maths underneath is unchanged. After the fourth scenario, §7.2.5 puts all four on one simple picture.

7.2.1 Scenario 1 — midday solar with network losses

In plain words. You buy cheap midday solar, lose a little on the wires, sell what arrives to a factory for more — and keep the difference as profit.

A Solar-pool PPA is first in merit order at 12:00. It buys at 65 c/kWh; the Industrial-pool factory pays 120 c/kWh; wheeling is 15 c/kWh; and the edge DLF is 0.966. The factory needs at least the available solar quantity, so the whole 16,710 kWh is sent.

Allocation flow and price — 12:00 solar → factory
12:00standard
Solar PPA · Solar priority 1016,710 kWh sentbuy 65 c/kWh
DLF 0.966→568 kWh lost
Factory · Industrial priority 1016,141.86 kWh deliveredsell 120 · wheel 15 c/kWh
RevenueR 19,370.2316,141.86 × 120 ÷ 100
Energy cost− R 10,861.5016,710 × 65 ÷ 100
Wheeling− R 2,421.2816,141.86 × 15 ÷ 100
Line marginR 6,087.4537.7 c per delivered kWh

The important detail is that revenue and wheeling use delivered kWh, while the PPA cost uses sent kWh. The run therefore records kwh_sent = 16710, kwh_delivered = 16141.86, buy = 65, sell = 120, wheeling = 15 and margin = R 6087.45. The 568.14 kWh network loss is not a separate spill line; its cost is already visible in the lower delivered quantity and effective buy price of 65 ÷ 0.966 = 67.29 c/kWh.

7.2.2 Scenario 2 — partial firm cover and grid top-up

In plain words. A must-serve buyer needs more than your reserved firm supply. You still cover them — the gap comes from expensive shortfall top-up — so the customer is served but the hour can lose money.

At 19:00 a firm buyer needs 5,000 kWh, but the reserved Firm-pool block has only 3,000 kWh. The contracted block costs 140 c/kWh, sells at 160 c/kWh and wheels at 8 c/kWh with DLF 1.0. Because the destination is firm, the remaining 2,000 kWh becomes a priced grid top-up at the member's 225 c/kWh shortfall top-up rate.

Allocation flow and price — 19:00 firm demand served from two sources
19:00peak
Reserved Firm block3,000 kWhbuy 140 c/kWh
contract allocation→margin +R 360
Firm evening buyer3,000 kWh coveredsell 160 · wheel 8 c/kWh
19:00shortfall
Shortfall top-up2,000 kWhbuy 225 c/kWh
firm backstop→margin −R 1,300
Same firm buyer2,000 kWh replacedsell 160 c/kWh · no wheel
Contract lineR 3603,000 × (160 − 140 − 8) ÷ 100
Shortfall line− R 1,3002,000 × (160 − 225) ÷ 100
Combined hour− R 940service preserved, margin sacrificed

The run writes two lines: an ALLOCATION line for the 3,000 kWh contracted flow, and a SHORTFALL line for 2,000 kWh with buy = 225 and sell = 160. A non-firm demand shortfall has no automatic replacement purchase and therefore records zero realised margin rather than this top-up loss. This distinction is why the firm flag and the shortfall top-up rate must be correct.

7.2.3 Scenario 3 — a profitable sale with loss-making spill

In plain words. You sell some of the night wind at a profit, but the rest has no buyer. You still paid for that leftover energy, so the hour loses money overall.

At 02:00 a take-or-pay Wind member produces 8,000 kWh at 82 c/kWh. Open demand can take only 5,000 kWh at 125 c/kWh; wheeling is 12 c/kWh and DLF is 1.0. The remaining 3,000 kWh has a spill value of only 10 c/kWh.

Allocation flow and price — one supply block splits into a sale and spill
02:00off-peak
Wind PPA8,000 kWh availablebuy 82 c/kWh
merit allocation↗5,000 kWh
Night-shift demand5,000 kWh soldsell 125 · wheel 12 c/kWh
remainder↘3,000 kWh
Spill destination3,000 kWh unsoldrecovery 10 c/kWh
Allocation marginR 1,5505,000 × (125 − 82 − 12) ÷ 100
Spill margin− R 2,1603,000 × (10 − 82) ÷ 100
Net hour− R 610profitable sale, loss-making position

The first 5,000 kWh creates a normal ALLOCATION line. The remainder creates a SPILL line with no destination and no wheeling: recovery of R300 less the R2,460 energy cost gives −R2,160. This is why a positive allocation margin does not guarantee a profitable hour. It also explains why spill limits, ToP utilisation (§12.3) and a useful battery charge outlet matter.

7.2.4 Scenario 4 — the book holds a battery

In plain words. Soak up free leftover midday solar into the battery, then use it in the evening instead of buying expensive top-up — move free waste into expensive need.

This book has an active 4 MW / 10 MWh battery at its minimum SoC, 90% round-trip efficiency, 8 c/kWh degradation cost and a 20 c/kWh minimum spread. Pass A finds 4,000 kWh of zero-valued solar spill at 12:00 and a firm shortfall worth an avoided 220 c/kWh at 19:00. The dispatcher tests:

spread = 220 − 0 ÷ 0.90 − 8 = 212 c/kWh ≥ 20 — dispatch.

Two-pass allocation flow and price — free midday spill becomes evening firm cover
12:00charge
Pass-A solar spill4,000 kWhforegone value 0 c/kWh
BESS_CHARGE→margin R 0
Book-held battery4,000 kWh charge input≈ 3,795 kWh added to SoC
19:00discharge
After round-trip losses3,600 kWh dischargedstored marginal cost 8 c/kWh
BESS_DISCHARGE→avoids top-up
Firm shortfall outlet3,600 kWh backeddischarge value 220 c/kWh
Charge lineR 0 margincharging positions energy; it does not earn
Avoided top-up valueR 7,9203,600 × 220 ÷ 100
Stored/degradation cost− R 2883,600 × 8 ÷ 100
BESS marginR 7,6323,600 × (220 − 8) ÷ 100

The charge produces a BESS_CHARGE line with buy = 0 (the foregone spill value) and zero margin; charging only positions the battery. The absorbed 4,000 kWh is removed from the original spill quantity. The evening BESS_DISCHARGE line uses a stored marginal cost of charge cost ÷ η_rt + degradation = 8 c/kWh, a discharge value of 220 c/kWh and margin R7,632. If the same energy had been bought from surplus PPA supply at 60 c/kWh rather than zero-valued spill, stored cost would be 60 ÷ 0.90 + 8 = 74.67 c/kWh and the 3,600 kWh discharge margin would fall to approximately R5,232.

This is the pricing view of the book-level two-pass. The next section explains how Pass A, dispatch and merge produce these battery lines over the whole month; the BESS screen then shows the same movements as an SoC schedule.

7.2.5 Four scenarios at a glance

Strip away the c/kWh arithmetic and the four stories are one simple loop: match supply to demand → price what matched → name what was left over → (optional) move leftovers in time with a battery.

Four pricing stories in one glance — what the engine is doing
112:00 · sold
Cheap solarBuy low
wires lose a bit→
FactorySell higher
=
ALLOCATIONYou keep the gap
219:00 · firm gap
Firm blockNot enough
must serve→
Firm buyerStill covered
+
SHORTFALLExpensive top-up
302:00 · leftover
Night windToo much
some sold→
Night loadProfit on part
+
SPILLPaid-for waste
4battery bridge
Midday spillFree leftover
charge→
BatteryHold until evening
discharge→
Firm gapAvoid top-up
1 · Sold cleanly — ALLOCATION
Buy cheap  →  lose a little on the wires  →  sell higher
Result     =  profit on the matched energy
2 · Must serve, not enough — SHORTFALL
Firm buyer needs more than reserved supply
Result     =  customer still served · hour may lose money on top-up
3 · Bought, nobody took it — SPILL
Part sold at a profit · leftover still paid for
Result     =  good sale can sit inside a losing hour
4 · Move waste to need — BESS
Charge free midday leftover  →  discharge into evening firm gap
Result     =  avoid expensive top-up · earn the spread
If you see… Plain meaning Line kind
Energy matched buyer ↔︎ seller A normal wheeled sale ALLOCATION
Firm buyer still hungry after the stack Grid (or replacement) filled the gap SHORTFALL
Supply left with no buyer You paid for energy nobody took SPILL
Battery soaking midday / helping evening Waste moved to need across hours BESS_CHARGE / BESS_DISCHARGE
Line kind Quantity shown Buy / value provenance Margin treatment
ALLOCATION Sent and delivered kWh Source contract buy; destination contract sell; edge wheeling Delivered revenue − sent energy cost − delivered wheeling
SHORTFALL Unserved demand kWh Firm: shortfall top-up buy and contract sell Firm replacement loss/profit; non-firm records zero realised margin
SPILL Unallocated sent kWh Source buy versus configured spill recovery Recovery − sunk supply cost; no wheeling
BESS_CHARGE Battery input kWh Foregone spill value, surplus-PPA cost or allowed grid cost Zero on charge; economics are realised on discharge
BESS_DISCHARGE Battery output kWh Stored marginal cost versus avoided top-up or sale value Output × (discharge value − stored marginal cost)

7.3 When the book holds a battery — the two-pass

In plain words. First measure the book without the battery — where energy is wasted and where buyers are short. Then ask the battery to move that waste into those shortages. Then write the schedule into the run as charge and discharge lines.

A battery's value is time: charge when energy is cheap or leftover, discharge when it is expensive or missing. That decision is only honest if the engine already knows what the rest of the book would do alone. So when the book has an active BessAsset (§11.3), each run becomes a two-pass (three steps: discover → schedule → merge). Without a battery, the engine still takes the single walk in §7.1 — nothing changes.

The two-pass in three beats — discover opportunities, schedule the battery, merge into the run
APass Aallocate without the battery
→
BDispatchday-by-day charge / discharge
→
CMergeBESS lines + trim spill
A · Pass A — value discovery
Run the full month as if no battery existed
Output     = hour-by-hour spill and shortfall “price tags”
Purpose    = show the battery what it can trade against
B · Dispatch — the schedule
Day by day, pick charge→discharge pairs that clear the spread rule
Output     = SoC walk + every move (and every held pair)
Purpose    = turn opportunity into a physical plan
C · Merge — write it into the run
Add BESS_CHARGE / BESS_DISCHARGE lines; shrink absorbed spill
Output     = final run lines + dispatch intervals (the battery fold in Book · Forecast, and the dispatch page)
Purpose    = one auditable result the KPIs can sum

Why the battery is left out of Pass A

If the battery sat in the ordinary merit stack, it would compete for the same kWh it is later asked to absorb — circular and unstable. Pass A therefore allocates with the battery excluded. What remains is the book's raw shape:

Those two vectors are the charge-cost and discharge-value ladders the dispatcher reads (§11.2). Pass A does not invent battery economics; it only paints the opportunity surface.

What dispatch does with that surface

For each calendar day in the run period the dispatcher:

  1. Builds candidate charge hours (cheapest sources first: spill → surplus PPA → grid if allowed) and discharge hours (highest outlets first: firm shortfall → peak sale → standard sale).
  2. Tests charge→discharge pairs with the spread rule — only pairs that clear efficiency, degradation and your minimum spread are taken, highest spread first.
  3. Respects physics: power limits, SoC floor/cap, round-trip losses, and the daily cycle cap.
  4. Rolls end-of-day SoC into the next morning so a month is one continuous battery story, not 30 isolated days.

Pairs that look profitable but fall under the minimum are held and later listed on the rejected-pairs strip — the audit of what the battery declined. Deep arithmetic and a full weekday walk live in §11.2; here the point is only that dispatch consumes Pass A, it does not re-allocate the book from scratch.

What merge changes on the line list

Merge is bookkeeping with consequences:

After merge… What changes
New BESS_CHARGE lines Energy into the battery; margin 0 (positioning only); buy = charge cost (often 0 from free spill)
New BESS_DISCHARGE lines Energy out; buy = stored marginal cost; sell = discharge value (e.g. avoided top-up); margin = realised arbitrage
Existing SPILL lines Quantity reduced by whatever the battery absorbed — stored energy is no longer counted as waste
Pass-A SHORTFALL lines Left as the discovery record; the economic cover appears on BESS_DISCHARGE, not by rewriting the shortfall row
Dispatch intervals Every active hour persisted for the run's battery fold and the BESS screen (§11.4)

Ordinary ALLOCATION lines from Pass A stay; the battery does not rewrite sales that already matched. It adds storage movement, subtracts absorbed spill, and realises the shortfall-avoidance value on the discharge line.

Same day, before and after the two-pass — Pass A opportunity becomes BESS lines
APass A only
12:00 SPILL4,000 kWh wasted
same day…
19:00 SHORTFALLexpensive top-up
Cafter merge
12:00 CHARGE4,000 kWh stored
battery bridge→
19:00 DISCHARGE3,600 kWh firm cover

Worked example — one day through all three beats

Same numbers as §7.2.4: 4 MW / 10 MWh battery, η_rt 90%, degradation 8 c/kWh, min spread 20 c/kWh, starting at the SoC floor.

Pass A finds (battery absent):

Hour Kind Quantity Price tag the battery sees
12:00 SPILL 4,000 kWh solar leftover foregone value 0 c/kWh (free charge)
19:00 SHORTFALL firm gap avoided top-up 220 c/kWh (valuable discharge)

Dispatch decides: spread = 220 − 0 ÷ 0.90 − 8 = 212 ≥ 20 → take the pair. Charge 4,000 kWh at 12:00 (≈ 3,600 kWh recoverable after round-trip); discharge 3,600 kWh at 19:00 into the firm gap.

Merge writes:

Line Sent / moved Buy Sell Margin
BESS_CHARGE @ 12:00 4,000 kWh in 0 c/kWh — R 0 (positions only)
BESS_DISCHARGE @ 19:00 3,600 kWh out 8 c/kWh stored 220 c/kWh R 7,632
SPILL @ 12:00 reduced by 4,000 kWh — — that leftover is no longer waste
Pass-A SHORTFALL @ 19:00 still on the books as discovery — — cover value sits on the discharge line
Merge ledger for the example day — charge positions, discharge earns
Pass A problemSpill + shortfallwaste at noon · expensive gap at 19:00
Charge lineR 04,000 kWh @ 0 c · margin never earned on charge
Discharge lineR 7,6323,600 × (220 − 8) ÷ 100
Net battery contributionR 7,632plus lower spill KPI · firm backing shown on the BESS tab

That is the whole two-pass story for one day. Over a month the same loop repeats, with SoC carrying from day to day. The run detail's BESS tab shows that run's frozen schedule (§8.4). The /strategy/bess page walks the latest Forecast that already has intervals (§11.11); the chart-reading guide stays in §11.4.

Properties worth knowing

Where the dispatcher is taught. Spread rule, charge/discharge ladders, SoC walk and rejected pairs: §11. This section only explains how that schedule is produced inside a run.


Data. full_demo · seed 42 · stage S09 (settlement matrix) · last re-derived 2026-07-18 against the full_demo manifest.

Follow along. Seat: trader_1@webill.net (password supersecret). Run a forecast for T1 Renewables Pool, then open run detail → BESS (or Strategy → BESS) to see Pass-A opportunities turned into charge/discharge intervals for that run.

8. Run detail — the engine made visible

The trader’s problem. A Forecast tile can say the month loses R 13.1 m. That number is a sum. You need the floor where every kilowatt-hour that made the sum is written: who supplied whom, in which SAST hour, at which buy / sell / wheeling price, under which rule.

Route: /org/trader-pools/:trader_pool_id/strategy/allocations/:run_id · Tab: Book (#strategy-tab-book stays lit on #strategy-nav). This is not a fifth top tab. The page subtitle is Run detail — hourly allocations, spill, shortfall and margin.

How you arrive. From Book · Forecast, Open the run ledger › under the run picker or inside #book-ledger-fold (§6.18). Overview does not open this URL; it sends you to Forecast first (§4). The click path is §8.6.

← Pool · Forecast (#allocation-back-to-forecast) returns to Forecast for this pool, this run’s month, and this run id. Clicking Allocation on the nav bar does not do that — it opens Rules.

What it is for. This is the run ledger — the audit floor. Every KPI anywhere in the module is a sum over the lines shown here; when a number surprises you, this screen is where you find out why — down to the hour, the member pair, the price components and the rules that fired. On an Actual run that has a paired Forecast, the green Forecast vs settled actual panel (§8.2) sits above the day chart so you score the plan before you dive into a single day. How the engine decides a line is §7; this chapter only teaches the page that shows those lines.

8.1 Header

Above the badges, ← Pool · Forecast (#allocation-back-to-forecast) opens Book · Forecast for this trader pool, the run’s month, and this run — you do not need the browser Back button. The href is …/strategy/book?mode=forecast&month=YYYY-MM&run=<run id> (month is the first day of the run period as YYYY-MM). Scenario + status badges, the run period, and the inputs hash — the reproducibility fingerprint (inputs hash, §1.3). It covers the book, scenario, period, every pool and member with all their pricing terms and caps, the forecast versions, the network edges — and the battery parameters when one is present. Change any of those and the hash changes; two runs with the same hash produce identical results. The short hash (#run-hash-short) toggles the full value (#run-hash-full) on click (#run-hash-toggle); the clipboard icon (#copy-run-inputs-hash) copies the full hash in one action (tooltip: Copy full inputs hash). A superseded run shows an amber banner (“This run is superseded by a newer run for the same period.”); a failed run shows the error in red (§8.7). An ACTUAL run also shows the Settled chip. The header period prints period_start through the last calendar day of the window (period_end minus one day), for example 01 Sep 2026 – 30 Sep 2026. The Audit tab prints the raw period_start → period_end (2026-09-01 → 2026-10-01).

8.2 Forecast vs settled actual

In plain words. After meters settle and you run a backcast (§6.2), open the Actual run. A green panel asks one question: how did reality differ from the forecast we used for the same month?

This panel appears only on a complete Actual run that still has a matching current Forecast for the same delivery period (same period_start / period_end, non-superseded, complete). Forecast-only and Nominated runs do not show it — there is nothing settled to score against. If the Forecast for that month was superseded and never replaced, the panel is absent until a current Forecast pair exists again.

When the green panel appears — Actual opens, Forecast of the same month is found
1Forecastplan for the month
→
2Backcastmeters → Actual run
→
3CompareActual − Forecast on this screen

Same delivery period (top-right notice)

The small label same delivery period is not decoration. It confirms the engine paired this Actual with a Forecast whose calendar window is identical — June with June, not June with May. Without that guarantee the Δ tiles would mix different months and look like "forecast error" when they are really period mismatch. If you ever doubt the pair, check both rows on the Runs index: same month label, one FORECAST, one ACTUAL.

The four Δ tiles — what each number means

Each tile is Actual KPI minus Forecast KPI for the whole month. A leading + means Actual was higher; a minus means Actual was lower. Units are R for margin and % for the three ratio deltas (the change in each percentage KPI — e.g. 81.3% → 81.1% shows as −0.2 %).

Margin Δ (R)
Actual margin_r − Forecast margin_r
+ means the settled month earned more Rand than the plan expected
− means the plan overstated commercial outcome

Use it as the commercial headline: did meters leave you richer or poorer than the operating forecast?

Coverage Δ (%)
Actual coverage_pct − Forecast coverage_pct
+ means a larger share of demand was met by allocated supply
− means a smaller share was met (more relative gap)

Coverage is allocated ÷ demand. Both numerator and denominator can move when meters arrive, so a tiny Coverage Δ can hide big volume moves — always read it with Spill and Shortfall.

Spill Δ (%)
Actual spill_pct − Forecast spill_pct
+ means a larger share of supply went unsold
− means less relative waste than the plan

Spill is spill ÷ supply. Higher Actual spill often means generation beat the shape or demand under-ran — the overlay chart and Spill tab say which hours.

Shortfall Δ (%)
Actual shortfall_pct − Forecast shortfall_pct
+ means a larger share of demand was left unmet by the stack
− means the book covered relatively more of load

Shortfall is shortfall ÷ demand. Firm hours with higher Actual shortfall are the expensive top-up story; open the Shortfall tab after you spot the shape on the charts.

How to read a mixed signal. The June 2026 T1 gallery pair (§6.2) is the pattern to expect: Margin Δ +R 21,500 while Coverage Δ −0.2 %, Spill Δ +0.3 %, Shortfall Δ +0.3 %. Plain reading: the month made more money even though residual shares were slightly worse — prices and mix helped more than volume residuals hurt. The tiles give that verdict in four numbers; the charts and tabs prove it.

The overlay chart — why it exists

Under the tiles sits a two-line chart: Forecast vs Actual, hour-of-day 00h–23h on the x-axis. A chart legend at the top of the panel names the colours before you read the picture:

Two charts on Actual run detail — different jobs
Athis panel
Forecast linePlanned allocated
vs↔︎
Actual lineMetered allocated
=
Whole monthShape score
Bchart below
Pool stacksWho supplied
one day→
Demand lineWho needed
=
Spill / gapHour anatomy
Forecast vs settled overlay (this panel) Day stacked chart (§8.3)
When you see it Only on Actual runs with a paired Forecast Every complete run
Time scope Whole run period, rolled into 24 hour-of-day buckets One selected SAST day (◀ day ▶)
What is plotted Two totals: Forecast allocated sent kWh vs Actual Supply pools stacked + demand line
Question it answers Did the shape of wheeled energy match the plan? In this day, who filled whom, and where did spill/shortfall sit?
Use it to Score forecast accuracy; find systematic hour biases Debug a day; open tabs for the lines behind the picture

They are complementary, not duplicates. Read the overlay first for "was the month's shape honest?"; then page the day chart to "show me Tuesday 19:00 inside the Actual run."

Proxied members (amber line)

When the Actual engine cannot find settled meter rows for a member, it falls back to that member's forecast energy and marks the member proxied. Those membership ids are stored on the run KPIs and listed under the overlay in amber:

Proxied members: Solar · IPP-A, Industrial · Factory, …

In plain words. Some sites in this Actual still used plan shapes because meters were missing — treat those sites' "actual" as incomplete.

What to do with the panel

  1. Confirm same delivery period and that the Settled chip is on.
  2. Read the four Δ tiles for the commercial and residual verdict.
  3. Scan the overlay for hour bands where Actual peels away from Forecast.
  4. Note any Proxied members before trusting the miss.
  5. Use ◀ day ▶ and the stacked chart below — plus Spill / Shortfall tabs — to turn a hour-of-day bias into concrete lines.

Follow along. Seat: trader_1@webill.net (password supersecret). Path: T1 Renewables Pool → Strategy → Runs → filter Actual (settled) → June 2026 → Open →. You should see the green Forecast vs settled actual panel above the day chart, with Δ tiles matching the §6.2 snapshot arithmetic.

8.3 Day selector + chart

Runs cover a month; the screen shows one SAST day at a time (◀ day ▶). On Actual runs this chart sits under the Forecast-vs-settled overlay (§8.2) — different job: the overlay scores month shape; this chart anatomises one day. The stacked-area chart shows each supply pool's delivered kWh stacked per hour, with the demand line overlaid — you can literally see the solar hump fill the daytime load and the gap left in the evening. Reading it takes three seconds: stack above the line = spill hours; line above the stack = shortfall hours; the vertical order of the bands is the merit order at work.

The examples below show how the chart represents each pricing scenario in §7.2. They are deliberately small slices of a day: the live chart shows the same relationship across all 24 SAST hours. Hover the relevant hour in the application to see the exact kWh and the allocation lines behind it.

How the run-detail chart reads the four §6.2 scenarios
Solar / contracted supply Firm or BESS supply Demand line Supply above demand (spill)

  1. Midday solar with network losses

Solar allocation at noon Solar delivered energy rises to meet the factory demand line at noon. The chart plots delivered, not sent, energy. 12:00 · 16,142 kWh delivered 08h12h16h

Read it: the solar band meets the demand line. The 568 kWh loss is already excluded because the chart stacks delivered kWh; inspect the Allocation row for sent kWh and DLF.

  1. Partial firm cover and grid top-up

Firm demand shortfall at 19:00 The firm supply stack reaches 3000 kWh while the demand line reaches 5000 kWh, leaving a 2000 kWh shortfall. 19:00 demand 5,000 3,000 supplied 2,000 top-up 17h19h21h

Read it: the line clears the stack by 2,000 kWh. For firm demand, that gap produces the priced SHORTFALL top-up line; it is not another coloured supply band.

  1. Profitable sale with loss-making spill

Wind spill at 02:00 Wind supply reaches 8000 kWh while demand is only 5000 kWh. The red cap represents 3000 kWh of spill. 02:00 supply 8,000 demand 5,000 3,000 spill 00h02h04h

Read it: the stack sits above the demand line. The 5,000 kWh below the line is the normal sale; the red cap is the 3,000 kWh SPILL line with its separate recovery value.

  1. Battery turns midday spill into evening cover

Battery charge at noon and discharge at 19:00 Four thousand kilowatt hours of solar spill charges the battery at noon. A 3600 kilowatt hour battery band covers the firm shortfall at 19:00. 12:00 · 4,000 charge 19:00 · 3,600 BESS 08h12h19h21h

Read it: the dashed gold wedge is solar spill sent to BESS_CHARGE; the purple band at 19:00 is BESS_DISCHARGE covering the firm outlet. The fine gold line is the SoC direction, not energy delivered.

8.4 Tabs

Tab What you see What to use it for
Allocations The tagged flows: SAST hour (sun/dark), source and destination as colour-coded pool · member badges (line-kind icon on Source), kWh sent and delivered, buy/sell/wheeling c/kWh, margin (R), rules, and a day total footer. Empty: *No allo cations this day.* The "who supplied whom at what price" record. Check a specific contract is being drained in the order you intended; verify a rule fires (Rules column).
Spill Supply hours nobody bought: Hr, source, unsold kWh, spill value, sunk cost, margin, and a day total footer. Empty: No spill this day. Find when and from which member you're losing money on unsold energy — the shape you'd take to the workbench to sell (or feed to a battery).
Shortfall Demand hours nobody supplied: Hr, destination, unserved kWh, firm Yes/No badge, top-up cost, margin, and a day total footer. Empty: No shortfall this day. Find the hours you're buying from the grid at top-up rates — the shape you'd take to the workbench to buy against (or back with a battery).
Margin Two side-by-side cards: Margin by TOU and Margin by source pool (each with Margin, Share %, and a Total footer). Answer when the book earns or loses (TOU), and which supply pool earned the allocation margin — the two cuts answer different workbench questions.
Audit Provenance card: inputs hash (with copy), scenario badge, grade, period, requested by, started, completed, duration, margin (R) and coverage. The frozen identity of the run for governance and disputes — not a second KPI dashboard.
BESS (only when the run dispatched a battery) The same day view as /strategy/bess (§11.11): facts, dispatch chart (§11.4), moves, hourly schedule and rejected pairs — frozen t o this run's intervals. Audit exactly what the battery did inside this specific run — the schedule that produced this run's BESS_* lines. Use this tab when the standalone page bound a different Forecast.

Annotated samples. Every label in the views below has a red numbered marker. Match it to the red-arrow callout immediately beneath the sample; these are illustrative values, not a second run.

Allocations sample view

Hr 1 Source 2 Dest 3 Sent 4 Delivered 5 Buy 6 Sell 7 Whl 8 Margin 9 Rules 10
☀ 12 ⇄ Solar · IPP-A Industrial · Factory 16,710 kWh 16,142 kWh 65.0c 120.0c 15.0c R 6,088 merit_order
  1. 1Hr is the SAST settlement hour, with a sun or moon mark for daylight (06–17) vs dark (00–05 and 18–23).
  2. 2Source is the supplying pool and member as colour-coded badges; the small icon before the badges is the line kind (there is no separate Kind column).
  3. 3Dest is the receiving pool and member as colour-coded badges.
  4. 4Sent is injected energy; the buy cost is charged on it.
  5. 5Delivered is energy after DLF losses; sell and wheeling use it.
  6. 6Buy is the source or stored-energy cost in c/kWh.
  7. 7Sell is the destination contract or discharge value in c/kWh.
  8. 8Whl is the edge wheeling charge in c/kWh.
  9. 9Margin is the line’s realised Rand contribution.
  10. 10Rules records the allocation provenance. A Total footer sums Sent, Delivered and Margin; Buy / Sell / Whl show volume-weighted averages for the day.

Spill sample view

Hr 1 Source 2 Unsold kWh 3 Spill value 4 Sunk cost 5 Margin 6
☾ 02 Wind · PPA-W 3,000 10.0c R 2,460 −R 2,160
  1. 1Hr pinpoints when the supply could not be placed (SAST hour with the same sun/dark mark as Allocations).
  2. 2Source identifies the affected pool and member.
  3. 3Unsold kWh is the remaining sent energy after allocation.
  4. 4Spill value is the configured recovery price per kWh.
  5. 5Sunk cost is the source-energy cost already incurred.
  6. 6Margin is recovery less sunk cost; no wheeling applies.

Shortfall sample view

Hr 1 Destination 2 Unserved kWh 3 Firm 4 Top-up 5 Margin 6
☾ 19 Firm · Evening Buyer 2,000 Yes 225.0c −R 1,300
  1. 1Hr is the SAST hour with sun/dark marking (same legend as Spill).
  2. 2Destination is the pool and member still needing energy, as colour-coded badges.
  3. 3Unserved kWh is the gap after normal allocations.
  4. 4Firm says whether the gap must be replaced.
  5. 5Top-up is the member’s Eskom replacement cost in c/kWh.
  6. 6Margin is realised only for a firm replacement; non-firm remains zero. A Total footer sums Unserved kWh and Margin; Top-up shows a volume-weighted average.

Margin sample view

The Margin tab is two cards, not one cross-tab. Each cuts realised Rand margin on a different axis so you can answer two questions without mixing them.

  • Margin by TOU answers when money is made or lost — off-peak, standard, or peak. It includes every line kind (allocations, spill, shortfall, and curtailment when present), so evening top-up losses and unsold-energy write-downs appear in the period that caused them. Its Total matches the run’s headline margin.
  • Margin by source pool answers which supply book earned the allocation margin. It groups allocation lines only by the supplying pool — spill and shortfall are left out of this card on purpose, because they are residual shapes you take to the workbench, not supply that cleared a buyer.

We keep the cuts separate because a single pool×TOU matrix hides the headline: most books earn the bulk of margin in standard hours off solar and lose money in peak on top-ups. The TOU card makes that time shape obvious; the source-pool card makes the portfolio shape obvious. Share % on each card is that row’s contribution to the card’s Total (100% in the footer when the total is non-zero).

Why the two Totals can differ. They are not required to match. TOU Total = sum of all line margins for the run. Source-pool Total = sum of allocation line margins only. Whenever spill, firm shortfall, or curtailment carries non-zero margin (common for spill: recovery less sunk cost), that Rand appears in the TOU card and not in the source-pool card. In the sample below the gap is spill (−R 2,160) plus firm shortfall (−R 940): TOU Total R 85,540 versus source-pool Total R 88,640. Equal totals only mean those residuals happened to contribute zero.

Margin by TOU

TOU 1 Margin 2 Share 3
standard R 88,640 103.6%
peak −R 940 −1.1%
offpeak −R 2,160 −2.5%
Total 4 R 85,540 100.0%

Margin by source pool

Source pool 5 Margin 6 Share 7
Solar R 86,240 97.3%
Firm R 2,400 2.7%
Total 8 R 88,640 100.0%
  1. 1TOU is the tariff period bucket (offpeak, standard, peak).
  2. 2Margin (left card) is realised Rand for that period across all line kinds.
  3. 3Share (left card) is that period’s percentage of the TOU Total — negative shares mean the period lost money against a positive total.
  4. 4Total (left card) is the run’s full headline margin (all line kinds). It can be lower than the source-pool Total when residuals lose money.
  5. 5Source pool is the supplying pool for allocation lines.
  6. 6Margin (right card) is realised Rand attributed to that supply pool’s allocations only.
  7. 7Share (right card) is that pool’s percentage of the source-pool Total.
  8. 8Total (right card) sums allocation margins by source pool. It excludes spill, shortfall and curtailment — so it need not equal callout 4. Here R 88,640 − R 85,540 = R 3,100 of residual margin sitting only in the TOU card.

Audit sample view

A two-column provenance card — the same fields as the Audit tab, in order. There is no Run ID row here (the URL already identifies the run); scenario is a colour badge, separate from grade; started and completed are separate rows with a derived duration between them; headline outcome is only Margin (R) and Coverage.

Inputs hash 1
8b7f3c…a21d ⎘
Scenario 2
FORECAST
Grade 3
P50
Period 4
2026-08-01 → 2026-08-31
Requested by 5
A. Ndlovu
Started 6
2026-08-01 06:01:12Z
Completed 7
2026-08-01 06:14:03Z
Duration 8
12.9 min
Margin (R) 9
R 412,000
Coverage 10
94.0%
  1. 1Inputs hash is the reproducibility fingerprint for book, terms, forecasts and network (§8.1). The clipboard control copies the full hash (tooltip: Copy full inputs hash) — same action as on the run header.
  2. 2Scenario is shown as the scenario badge (FORECAST, ACTUAL, or nominated) — not combined with grade.
  3. 3Grade is the forecast grade used for the run (e.g. P50 / P90), or blank when not applicable.
  4. 4Period is the delivery window as period_start → period_end.
  5. 5Requested by records who initiated the run (or — if unset).
  6. 6Started is when execution began.
  7. 7Completed is when execution finished.
  8. 8Duration is derived from started → completed (minutes, or < 1 min with seconds when under a minute).
  9. 9Margin (R) is the run’s headline realised margin from KPIs.
  10. 10Coverage is the run’s coverage percentage from KPIs. Spill and shortfall are not repeated on this card — use those tabs or the run header KPIs.

BESS sample view · appears only after dispatch

Below the KPI strip and dispatch chart sits the schedule table — one row per active hour for the selected day, with the same sun/dark hour marks and row hover as Spill / Shortfall. Source uses colour-coded badges (Spill, Contract, Market). Every column except Hour carries an i info tip (white tooltip) in the live UI; every column is listed below.

Day margin 1Realised discharge margin for selected dayR 7,632 Cycles/day 2Discharged energy ÷ usable capacity ÷ days (vs warranty max cycles/day)0.36 Spill absorbed 3Spill converted to stored energy42% Firm backing 4Output serving firm shortfall18% End SoC 5Energy carried into next day0.4 MWh
Dispatch chart 6 · charge below zero, discharge above · SoC and price lines
Hour 7 Action 8 kWh 9 Source 10 Outlet 11 Forecast 12 Cost 13 Value 14 Spread 15 SoC 16 Rationale 17
☀ 12 charge 4,000 Spill — — 0 — — 3.80 charge 4.0 MWh from spill @ 0c
☾ 19 discharge 3,600 — firm a1b2c3d4 · P50 17.0 210.0 193.0 0.40 discharge 3.6 MWh @ 210c to firm

Rejected pairs 18 · 13h → 21h · spread 16.1c < minimum · held

  1. 1Day margin — realised discharge margin for the selected day (Rand).
  2. 2Cycles/day — equivalent full cycles for the run: total discharged energy ÷ usable battery capacity ÷ days in the run period. One cycle means you discharged a volume equal to the usable capacity once. Compare it to the asset’s Max cycles/day (often 1.5) — the warranty ceiling the dispatcher will not exceed, even if more pairs look profitable (§11.1). Readings near that cap with pairs still held on the rejected-pairs strip argue for more capacity or less aggressive discharge, not for ignoring the warranty (§11.4, §12.6).
  3. 3Spill absorbed — share of spill converted into stored energy.
  4. 4Firm backing — share of output serving firm shortfall.
  5. 5End SoC — usable energy carried into the next day (MWh).
  6. 6Dispatch chart — charge bars below zero, discharge above, with SoC and price lines. Full reading guide: §11.4 · How to read the dispatch chart.
  7. 7Hour — SAST settlement hour with sun (06–17) or moon (00–05 and 18–23) mark; same legend as Spill.
  8. 8Action — charge when energy enters the battery this hour, discharge when it leaves.
  9. 9kWh — energy moved this hour (charge-in on charge rows, discharge-out on discharge rows).
  10. 10Source — where charge energy came from, as a badge: Spill (unsold book energy), Contract (contracted supply), or Market (grid / market buy). Blank (—) on discharge rows.
  11. 11Outlet — where discharge energy went: contract, firm, or market. Blank (—) on charge rows.
  12. 12Forecast — short price-forecast id and confidence lane (e.g. P50) when the hour used a market price forecast; otherwise —.
  13. 13Cost — charge cost in c/kWh (0 for zero-rated spill). On discharge rows this is the stored marginal cost carried into the hour.
  14. 14Value — discharge value in c/kWh. Blank on charge rows (charging positions; it does not earn).
  15. 15Spread — value minus cost in c/kWh for the economics that cleared the min-spread rule (§11.2). Often blank on pure spill-charge rows.
  16. 16SoC — state of charge after the hour, in MWh (end-of-hour usable energy).
  17. 17Rationale — human-readable reason the dispatcher moved energy this hour (the audit sentence).
  18. 18Rejected pairs — charge→discharge pairs that looked profitable but were held because spread was below the configured minimum.

8.5 Reading a line

In plain words. Open a complete run → leave the Allocations tab selected (it is the default). Use ◀ day ▶ until you see the day you care about. Each row in the table is one tagged energy flow for one SAST hour: who supplied whom, how much left the injector, how much arrived after losses, the three price legs in c/kWh, the Rand that flow contributed, and which engine rules produced it. If a KPI on the Runs index surprised you, this is the place that proves the number.

This section walks the Allocations table exactly as the screen shows it (§8.4 sample). Spill and Shortfall are separate tabs — they are not mixed into this table.

What you see before the columns

Column by column — what each cell means

Column on screen What it is How to read it
Hr SAST hour of the flow (0–23), with a sun or moon icon Same hour can have several rows (different source→dest pairs). Match the hour to the day chart above.
Source Who supplied the energy A small line-kind icon, then two colour badges: pool (filled) then member (outline). Tooltip titles say Pool · … and Member · …. There is no separate Kind column — the icon is the kind.
Dest Who received the energy Same badge pattern as Source (pool + member). Blank or — only when the line kind has no destination (unusual on this tab).
Sent kWh injected / leaving the source Buy cost is charged on this volume. Info tip: Injected Energy.
Delivered kWh that arrived after network losses (DLF) Always ≤ Sent when DLF < 1. Sell and wheeling are priced on this volume. Info tip: Injected energy less DLF.
Buy Source (or stored) cost in c/kWh What that kWh cost the book to use. On battery discharge rows this is the stored marginal cost, not the live grid price.
Sell Destination contract (or discharge) value in c/kWh What the book earns / avoids per delivered kWh.
Whl Edge wheeling charge in c/kWh Network use-of-system on the path from source to dest; charged on Delivered.
Margin Realised contribution of this row in Rand Not c/kWh — Rand for the whole flow. See the worked sum below.
Rules Engine tags that produced the line e.g. merit_order, firm_reservation, bess_dispatch. Provenance for disputes — not a second KPI.

Worked example — one ordinary allocation row

Take the sample row from §8.4 (same numbers as the Allocations sample view):

Hr Source Dest Sent Delivered Buy Sell Whl Margin Rules
☀ 12 ⇄ Solar · IPP-A Industrial · Factory 16,710 kWh 16,142 kWh 65.0c 120.0c 15.0c R 6,088 merit_order

Read it left to right:

  1. When. Hour 12 SAST (sun = daylight band).
  2. Who → whom. The Solar pool member IPP-A supplied the Industrial pool member Factory. The ⇄ icon marks a normal ALLOCATION (supply that cleared a buyer).
  3. How much. 16,710 kWh left the plant; 16,142 kWh arrived after DLF losses (~3.4% lost on the wire in this example).
  4. At what prices. Buy 65.0 c/kWh on what was sent; sell 120.0 c/kWh and wheeling 15.0 c/kWh on what was delivered.
  5. What it earned. Margin is calculated in Rand as:
Margin (R) — this row
revenue   = Delivered × Sell     = 16,142 × 120.0 = 1,937,040 c
cost      = Sent × Buy           = 16,710 ×  65.0 = 1,086,150 c
wheeling  = Delivered × Whl      = 16,142 ×  15.0 =   242,130 c
margin_c  = revenue − cost − wheeling            =   608,760 c
margin_R  = margin_c ÷ 100                       = R 6,087.60 ≈ R 6,088

Same pricing story as §7.2 — the Allocations tab makes that arithmetic visible per hour and per pair.

  1. Why this pair. Rules = merit_order means the engine placed this flow under ordinary cheapest-first / demand-stack logic. No firm reservation or battery rule intervened.

Line-kind icons on Source (there is no Kind column)

The small icon before the Source badges tells you what kind of line you are looking at:

Icon meaning Line kind Typical Rules tag What the money columns mean
Arrows (⇄) ALLOCATION merit_order, firm_reservation, … Normal wheeled sale: Buy = source cost, Sell = contract, Margin as above.
Battery full BESS_CHARGE bess_dispatch Energy into the battery. Buy = charge cost (often 0.0 from zero-rated spill). Margin is 0 — charging does not earn; it only positions energy for later.
Battery empty BESS_DISCHARGE bess_dispatch Energy out of the battery. Buy = stored marginal cost (charge cost ÷ round-trip efficiency + degradation — §11.2). Sell = discharge value. Margin = realised arbitrage.

Spill, shortfall and curtailment lines live on their own tabs (or BESS schedule), not as Dest rows here. If you expected an unsold or unmet hour in Allocations and cannot find it, open Spill or Shortfall.

How this ties back to the headline KPIs


Data. full_demo · seed 42 · stage S09 (settlement matrix) · last re-derived 2026-07-18 against the full_demo manifest.

Follow along. Seat: trader_1@webill.net (password supersecret). Path: T1 Renewables Pool → Book · Forecast → Open the run ledger › → Allocations tab → page to a sunny midday hour. You should see Source / Dest badges, Sent larger than Delivered when DLF applies, and a Margin you can recompute from Buy / Sell / Whl as above. For the Forecast-vs-Actual panel, open the matching Actual run instead (§8.2). The T1 September numbers on this destination page are §8.8.

8.6 How you get here

The problem. Forecast’s fold says Open the run ledger ›. You need to know which URL that is, that Allocation stays lit, and how you walk back without losing the run.

The address

/org/trader-pools/{trader_pool_id}/strategy/allocations/{run_id}

That {run_id} is the immutable allocation run you opened — not "the latest forecast for the month". A shared URL always shows the same lines. The old /strategy/allocations index (no run id) forwards to Book · Forecast (§6).

T1 Renewables Pool, September 2026 P50:

/org/trader-pools/01a0ab54-e46b-7dde-b45f-73d119213c75/strategy/allocations/01a0b951-b50d-76c2-bfd8-840b7ecc12cd

#strategy-nav — Book stays lit

The room tabs stay Operations · Performance · Allocation · Commercial · Dashboard. This page mounts under Book (#strategy-tab-book is active). There is no "Runs" tab any more. Clicking Allocation on the bar opens …/strategy/book — that is Rules, not Forecast. That is why the page has its own return link.

Three doors in

You start on What you press What opens
Book · Forecast, under the run picker Open the run ledger › on the meta line (data-role="run-meta") This run’s ledger
Book · Forecast, #book-ledger-fold The same Open the run ledger › inside the dashed fold (§6.18) The same URL
Overview There is no ledger link. Open Book · Forecast first (§4), then use either door above. Forecast, then this page

A run that belongs to a live Scenario Lab cook also shows an amber SIMULATED ribbon at the top (#simulated-ribbon-{id}) — a door into Lab, not a second ledger. Ordinary T1 Forecasts do not show it.

The walk back — ← Pool · Forecast

#allocation-back-to-forecast is already on the product. Label: ← Pool · Forecast. Href:

/org/trader-pools/{id}/strategy/book?mode=forecast&month=YYYY-MM&run={run_id}

On T1 September P50 that is …/book?mode=forecast&month=2026-09&run=01a0b951-b50d-76c2-bfd8-840b7ecc12cd. The month is the first day of the run period as YYYY-MM. You land on the same Forecast fold you left, with the same run still selected. Browser Back also works; the link is the one you can bookmark.

Careful. Allocation on #strategy-nav is Rules. ← Pool · Forecast is Forecast. They are not the same door.

8.7 Empty, failed, and incomplete runs

The problem. Not every run has a chart. You need to know when the floor is closed, when a day simply has no lines, and what the page does if the id is wrong.

The header (badges, period, hash, back link) always renders when the run exists. The comparison panel, day picker, Day supply vs demand chart (#run-day-chart) and the tabs render only when status is COMPLETE.

What you see What it means What to do
Amber banner This run is superseded by a newer run for the same period. A newer complete run of the same scenario, grade and period exists. Lines here are history. Read them for audit. Open the current Forecast chip if you want the operating plan.
Rose banner Run failed: plus the stored error Status is FAILED. No chart, no tabs. Keep using the previous complete current (§6.6).
Header only — no day picker, no tabs Status is PENDING or RUNNING. The worker has not written lines yet. Wait; refresh. Read KPIs only from COMPLETE.
Flash Run not found. then Forecast The run id is missing or belongs to another book. Check the pool and the run chip.
Allocations: No allocations this day. This SAST day has no ALLOCATION lines. Other days of the same run may. Page ◀ / ▶. Open Spill — leftover often lives there.
Spill: No spill this day. Every sent kWh that day found a buyer. Unusual on T1. Check neighbouring days.
Shortfall: No shortfall this day. Every demand hour that day was served. T1 September is this state on every day — coverage is 100 %.
Margin cards with Total R 0.00 and Share — The KPI maps are empty (or truly zero). Confirm the run completed and has lines.
No BESS tab The run persisted no battery intervals. Honest. A book with a battery that never dispatched still hides the tab.

A complete run with a battery that did persist intervals shows the BESS tab even when the Forecast fold’s arbitrage tile is R 0. That is T1 September — one charge line and reserve hours, taught on the battery page (§11.11).

8.8 Worked walk — T1 September P50

Data. full_demo · seed 42 · stage S09 (settlement matrix) · last re-derived 2026-09-19 against the seeded T1 book (September P50 01a0b951-b50d-76c2-bfd8-840b7ecc12cd).

Follow along. Seat: trader_1@webill.net (password supersecret). Path: Trader Pools → T1 Renewables Pool → Book · Forecast (?mode=forecast&month=2026-09&run=01a0b951-…) → Open the run ledger ›. You should land on …/strategy/allocations/01a0b951-b50d-76c2-bfd8-840b7ecc12cd with Allocation lit and the day reading Tuesday 01 Sep 2026.

What the header says

On screen T1 September P50
Back link ← Pool · Forecast → …/book?mode=forecast&month=2026-09&run=01a0b951-b50d-76c2-bfd8-840b7ecc12cd
Scenario FORECAST
Status COMPLETE (no Settled chip — that is Actual only)
Period 01 Sep 2026 – 30 Sep 2026
Inputs hash (short) #7e4d7cf6 (#run-hash-toggle reveals the rest)
Grade (Audit tab) P50
Requested by —
Duration under a minute (< 1 min (2 s))
Headline KPIs (Audit) Margin −R 13 064 676.47 · Coverage 100.0%

Those KPIs are the same month you already read on Forecast: every demand hour covered, 96.4 % of supply unsold, the month loses R 13.1 m (§6.12). The ledger proves the sum.

The green Forecast vs settled actual panel is absent. This is a Forecast. Open a June Actual if you want the Δ tiles (§8.2, §6.2).

Tuesday 01 Sep 2026 — the first day

The picker starts on the first SAST day of the period. Caption on the chart: Supply pools stacked by hour (MWh delivered), with the demand line overlaid — stack above the line is spill; line above the stack is shortfall. Id #run-day-chart.

On T1 the stack sits far above the demand line in every hour. That is the 96.4 % spill story drawn as a day, not as a tile.

Allocations — one night hour, then the day total

Default tab. Sun/dark legend: Sun hours 06–17 · Dark hours 00–05 and 18–23. Cells are rounded whole kWh; prices drop trailing zeros (85 not 85.0).

Hour 00 SAST (moon) opens the month with three merit_order sales. Read the Wind → Municipal row left to right:

Hr Source Dest Sent Delivered Buy Sell Whl Margin Rules
☾ 00 Wind Pool · Durban Coastal Wind · DEMO-SUPPLY-1247843 Municipal Pool · OffTaker C Midrand DC 1,668 1,668 85 210 0 R 2 084.57 merit_order
revenue   = 1,667.659 × 210.0 = 350,208.39 c
cost      = 1,667.659 ×  85.0 = 141,751.02 c
wheeling  = 1,667.659 ×   0.0 =       0.00 c
margin_R  = (350,208.39 − 141,751.02) ÷ 100 = R 2,084.57

Sent equals Delivered on this row — no DLF bite. Buy 85 c/kWh is the wind contract; sell 210 c/kWh is what the municipal buyer pays. The same hour also sells Wind and Firm into Commercial Pool (275 kWh each). A member badge can print an em dash when the membership has no label or site name; the pool badge still names the book.

Day footer for 01 Sep 2026 (Allocations only):

Sent Delivered Margin
Total 74,992 kWh 74,992 kWh R 117 646.12

Seventy-five allocation rows. Buy / Sell / Whl in the footer are volume-weighted averages for the day, not a simple mean of the cells.

Spill — why the month loses money

Same day, Spill tab. Empty copy would be No spill this day. T1 is the opposite: 111 leftover rows, 1,661,761 kWh unsold, day margin −R 414 635.79.

The largest hour-00 leftover:

Hr Source Unsold kWh Spill value Sunk cost Margin
☾ 00 Wind Pool · Durban Coastal Wind · DEMO-SUPPLY-1247843 38,581 40 R 32 794.21 −R 17 361.64
sunk     = 38,581.429 × 85.0 ÷ 100 = R 32,794.21
recovery = 38,581.429 × 40.0 ÷ 100 = R 15,432.57
margin   = recovery − sunk         = −R 17,361.64

No wheeling on spill. That is the same wind that sold 1,668 kWh to Midrand in the same hour — the rest of the plant had no buyer.

Shortfall — the honest empty

No shortfall this day. The tab is not broken. Coverage is 100 % for the month; every demand hour was served. The leak is unsold supply, not unmet load. Find offtake → Desk on Forecast is the next click (§6.19).

Margin — two card totals that must not match

The Margin tab is the whole run, not the selected day.

Margin by TOU (every line kind, including spill):

TOU Margin Share of −R 13.1 m
peak −R 2 063 872.30 15.8%
offpeak −R 5 868 384.13 44.9%
standard −R 5 144 740.03 39.4%
nil R 12 320.00 −0.1%
Total −R 13 064 676.47 100.0%

The nil bucket is a real KPI key the engine stored — hours that did not land in peak / standard / off-peak. It is small. Do not ignore a named TOU because of it.

Margin by source pool (allocation lines only):

Source pool Margin
Solar Pool R 2 516 592.66
Wind Pool R 786 497.62
Firm Pool R 93 552.23
Total R 3 396 642.51

The two Totals differ on purpose (§8.4). Sold-leg allocation earns about +R 3.4 m. Spill write-downs (and the tiny nil / reserve noise) pull the headline to −R 13.1 m. Same conservation as Forecast’s margin tables (§6.14).

BESS tab — present, not the home

The BESS tab is on this run because 29 dispatch intervals were persisted (one BESS_CHARGE, twenty-eight BESS_RESERVE). The Forecast battery fold still reads R 0 arbitrage (§6.17). Do not re-learn charge, hold and spread here.

Where this is taught. The full /strategy/bess page — which run it opens, facts, chart, moves, hour table — is §11.11. This tab is the same day view frozen to this run (#run-bess).

8.9 Screen ids

What Id or selector
Strategy tab bar #strategy-nav
Book (stays lit) #strategy-tab-book
Back to Forecast #allocation-back-to-forecast
Inputs hash toggle #run-hash-toggle · #run-hash-short · #run-hash-full
Copy hash (header) #copy-run-inputs-hash
Forecast vs Actual overlay #forecast-actual-overlay (Actual + paired Forecast only)
Day chart #run-day-chart
Day pager button[phx-click="shift_day"][phx-value-by="-1"] / "1"
Tab buttons button[phx-click="select_tab"][phx-value-tab="allocations\|spill\|shortfall\|margin\|audit\|bess"]
Copy hash (Audit) #copy-audit-inputs-hash
BESS day view #run-bess
Simulated ribbon #simulated-ribbon-{sim_run_id} (Lab cooks only)
Forecast fold (door, not this page) #book-ledger-fold

Tables themselves have no wrapper ids. Assert on the empty copy, the column info tips (data-tip="Injected Energy", The allocation provenance), and title="Pool · …" / title="Member · …" on the badges.

8.10 What this page is not

9. The Desk — sell the long, buy the short (what if I signed this?)

Open Trader Pools → pool → Commercial. The Delivery month field selects a calendar month and follows you between pool tasks. The visible window explains why its position can differ from Performance’s latest snapshot run. Candidate simulations use this calendar period and remain indicative. The workspace route is /org/trader-pools/pools/:id/commercial?month=YYYY-MM; older simulation routes still work. View pool contracts carries the pool and month through Deals, contract tabs and the return to Commercial.

Route: /org/trader-pools/:id/strategy/simulations · Tab: Desk (was Simulations; the Nominations and Exposure tabs are now steps and sections of this page — §9.9, §9.10)

This chapter is written for someone who has never run a portfolio what-if before. No jargon assumed. By the end you should know what the book needs (its sell need and its buy need, each priced against doing nothing), who to sell to and buy from, how to try one contract in the deal panel beside the candidate list or several at once in the basket, what the Strategy board shows about the co-ordination between buy legs and sell legs, and how to commit — proposals and nominations — without touching live contracts, forecasts or nominations until you say so.

The Desk is the trader’s twin of the IPP Sales Desk (§14) and the off-taker Procurement Desk (§13), two-sided: a trader both sells and buys, and the two needs are read together.

Data. full_demo · seed 42 · stage S09 (settlement matrix) · last re-derived 2026-07-18 against the full_demo manifest.

Not this screen. The Scenario Lab / market-month harness (§16, §17) scripts the whole market. This Desk tab answers only: "what if this book signed this one contract?"


In plain English — why simulations exist

Imagine your energy book is a wardrobe that already has clothes in it. A salesperson offers a new jacket at a great price. The price tag cannot tell you whether the jacket fits with the trousers and shirts you already own. A bargain solar PPA can raise margin while worsening spill (you generate more than anyone can take at midday). An evening buyer can be worth more than a cheaper daytime buyer if your surplus sits after sunset.

A simulation is a safe fitting room for a contract.

You keep the wardrobe as it is (baseline). Then you pretend the new jacket is already hanging there (variant) and ask the same measuring tools you already trust — margin, spill, shortfall, coverage — whether the outfit got better or worse. Nothing leaves the fitting room until you deliberately Build Proposal.

Everyday idea On this screen
Wardrobe today Your trader book / pools as they stand
Trying on a jacket Injecting one hypothetical buy or sell member
Measuring tape Engine KPIs (margin, spill, shortfall, coverage)
"Looks better" Green deltas that all tell one story
Leaving with the jacket Build Proposal → normal negotiation
Leaving empty-handed Leave status COMPLETE / later DISCARDED — book unchanged

Why you run simulations (desired outcomes)

  1. See portfolio fit before negotiation — cheap is not the same as useful.
  2. Compare like-for-like — baseline and variant use the same SIMULATION scenario and period, so deltas are apples-to-apples.
  3. Defend a commercial decision — fit score + KPI deltas travel into the proposal message so the story is evidence, not memory.
  4. Fail safely — bad ideas stay in the Past simulations log; membership, forecasts and nominations never move.

What never happens during a simulation

The Desk — five steps from the book’s position to a committed strategy
1Positionsell need · buy need · Option 0
→
2Candidateswho to sell to · who to buy from
→
3Basketterms per candidate · simulate
→
4Strategy boardbuy legs → pools → sell legs · compare
→
5Commitproposals · nominations · Bid Desk

How the screen is laid out

The page is one flow, top to bottom, and a step rail (#desk-rail) at the top lights the step you are on. Everything else is either always visible or slides in from an edge so you never lose the position strip.

Region What it shows Ids to look for
Step rail Position → Candidates → Basket → Strategy board → Commit; the lit step follows what you have done (a selected candidate lights Candidates, a leg in the basket lights Basket, a simulated basket lights Strategy board) #desk-rail
Headline One sentence from the numbers: how long the book is, how short, what spill earns today and on SAWEM, and which side the desk says to work first #desk-headline
Position strip The Book net position chart (surplus above zero, gap below) with a Sell need card and a Buy need card either side. Each card names its kWh, its share, its heaviest window, and its Option 0 — what happens if you sign nothing. A dashed The desk says box gives the verdict #workbench-book-position, #desk-sell-need, #desk-buy-need
Candidates The Sell / Buy tabs you know, each card now carrying a signal row: how much of the need the candidate would absorb (sell) or cover (buy), the routes open to it (physical PPA, Eskom VPPA, via trader, municipal wheeling), badges such as evening load or already a member, and a + Basket button #sell-candidates-panel, #buy-candidates-panel, [data-role="candidate-signal"]
Deal panel (right of the list) Click a candidate and the deal form opens beside the list — the same layout as IPP Sales and OffTaker Procurement, not a side drawer. Add to basket parks the leg so you can keep browsing. Clear Deal returns the dashed placeholder #desk-deal-panel, #selected-generation-deal-card / #selected-offtake-deal-card, #simulation-form, #simulate-btn, #deal-basket-toggle
Basket tray (bottom) Every leg you have added, with its terms; Simulate basket runs all of them as one book #desk-basket, #basket-simulate, #basket-clear
Strategy board For a simulated basket: buy legs → pools → sell legs, the residual to SAWEM and the grid, KPIs before and after, and exposure per counterparty #desk-strategy-board
Compare Option 0 in row 0, then every strategy and every single simulated leg on one valuation basis, ranked by the mode you pick #desk-compare, #desk-rank-mode
Counterparty exposure The per-counterparty table from the latest risk snapshot against the limits in force — the old Exposure tab #exposure-page, #exposure-table
Commit Build a proposal per leg, open the Bid Desk for the SAWEM residual, and the nominated members’ plans with a link to the nominations workbench — the old Nominations tab #desk-commit, #desk-open-nominations
Past simulations The decision log, unchanged #past-simulations

Follow along. Seat: trader_1@webill.net (password supersecret). Path: Trader Pools → T1 Renewables Pool → Strategy → Commercial. In full_demo September the headline reads the book is long 39.0 GWh and short nothing; the Sell need card values Option 0 at SAWEM P50 ≈ 85 c after the imbalance haircut — above the ~78 c the energy cost — and the Buy need card says do not buy for the book as it stands.

9.1 Start with the portfolio problem — the two needs and Option 0

The Desk starts where the IPP and off-taker desks start: with the need, priced against doing nothing.

Everything below the strip is ranked against these two cards.

Choose the missing shape before you choose the counterparty. The chart at the top and the candidate list underneath are two views of the same question.

Book net position — one chart for both sides

The fold always shows Book net position (24h) from a single FORECAST allocate:

Side of the zero line Colour Meaning Which tab cares
Above Rose — Surplus (unsold) Generation still without a buyer (spill) Sell
Below Sky — Gap (shortfall) Demand still unmet Buy
Dashed Slate — Contracted Total allocated volume (context only) Both

Sell emphasises the surplus lobe; Buy emphasises the gap lobe. You never lose sight of the other side — that is the point of a combined book view.

Read it: tall pink at midday → look for daytime buyers. Tall blue only in the evening → a pure solar purchase will not finish the job. Empty dashed placeholder means no book position yet — run a forecast in Performance first.

Sell tab — "Who can buy my surplus?"

When Sell is active:

Buy tab — "Who can fill my gap?"

When Buy is active:

Fit score — what the number means

The fit score (0–100) is computed from the latest book shape for the current month. The engine builds a 24-hour gap vector (shortfall) and a surplus vector (spill), then compares the candidate's daily profile with cosine similarity. Higher = the candidate's shape lines up better with the problem you are trying to solve. The list is ordered best first: a practical shortlist, not a guarantee of commercial value.

Fit colour (on the card) Rough meaning
Green (≥ 75) Strong shape match — start here
Amber (50–74) Partial match — check hours carefully
Rose (< 50) Weak match — price alone will not save it
Sell example (full_demo feel)

Your solar book spills hard from 10:00–15:00. A retail load that peaks 09:00–17:00 may score about 85. A flat 24/7 factory might score about 55 because it absorbs only part of the midday bump — nights still leave surplus stranded.

Buy example

Evenings show a thick grid band. A wind / evening-heavy IPP may score high; pure midday solar may score lower even if its tariff looks cheap — because it does not hit the hours you still buy from the grid.

Tip. Identify the problem from Overview (spill / shortfall / next-best-actions) before clicking the first card. The chart fold is there so you never forget which gap you are shopping for.


9.2 Enter terms you can defend — beside the candidate list

Clicking a candidate card fills the deal panel to the right of the list (#desk-deal-panel) — the same two-column layout as the IPP Sales Desk and the off-taker Procurement Desk. The candidate list stays on the left (#desk-candidates, lg:col-span-4); the selected deal sits beside it (lg:col-span-8). There is no side drawer: the form does not overlay the page.

The panel holds the same deal form as before, so the field-by-field guide below still applies. Two extra strips sit with the form: the header repeats the candidate’s signal row (absorbs/covers, routes, badges), and Add to basket (#deal-basket-toggle) parks the candidate with default terms — or with the terms of its latest complete simulation — so you can keep browsing and try several together (§9.8). Simulating in the panel still runs one leg against the baseline; adding to the basket does not run anything until you press Simulate basket. Clear Deal (#clear-deal-btn) returns the dashed No Candidate Selected placeholder.

Click a candidate. The right side leaves the dashed No Candidate Selected placeholder and opens the deal form that matches the tab — the same commercial forms used on the Procurement and Sales workbenches.

Tab Form title Mirrors Primary button
Buy Selected Off-take Deal (#selected-offtake-deal-card) Procurement Simulate Purchase
Sell Selected Generation Deal (#selected-generation-deal-card) Sales Simulate Sale

Both forms show the candidate name, a Fit Score chip, Clear Deal, and (for trader-to-trader candidates) an amber refusal banner — VWA registration for traders is not modelled yet (decisions V2); runs stay indicative (NERSA Phase-1/2), not authority to execute.

Buy — Selected Off-take Deal fields

Field What you are pretending Why it changes the result
Target Pool Supply Structure Which supply pool receives the pretend purchase Routing and pool rules (e.g. Flexible vs Wind)
Capacity (MW) Contracted nameplate (default 5) Caps energy the pretend member can deliver each hour
Tariff Price (c/kWh) Energy off-take rate (default 95) Buy cost / landed cost with DLF
Wheeling Cost (c/kWh) Network / admin add-on (book default often 15) Added on top of price ÷ DLF
Contract Term (Years) Commercial horizon (default 10) Stored on the simulation and any later proposal

Hover the ⓘ next to the form title for the same field explanations in-app.

Sell — Selected Generation Deal fields

Field What you are pretending Why it changes the result
Target Pool Demand Structure Which demand pool receives the pretend sale Where the buyer sits in the book
Capacity (MW) How much you pretend to sell (default 5) Caps how much the pretend buyer can take each hour
Energy Price (c/kWh) Sale tariff (defaults from book LCOE / base price) Revenue side of the variant
Contract Term (Years) Commercial horizon (default 10) Stored on the simulation / proposal

Sell has no wheeling field on this form — that matches SalesLive. Defaults are starting points for exploration; replace them with the conversation you actually expect to have.

After you press Simulate…

The engine builds two isolated cases under the SIMULATION scenario:

  1. Baseline — the book as it stands (no new member).
  2. Variant — the same book with the hypothetical candidate and your typed terms injected only for this calculation.

The candidate is never persisted as a real pool member. When the run finishes, the Result — baseline vs simulated panel appears under the form (next section). Use Simulate again / Simulate Purchase / Simulate Sale to change terms and re-run; Clear Deal drops selection and result.


9.3 Compare baseline and variant

The deal panel’s baseline vs simulated result is one leg against the book as it stands. The Compare table lower on the page (#desk-compare) is where legs meet each other: Option 0 in row 0, every strategy you have simulated this session, and every single complete simulation, each with margin, spill, shortfall, the largest counterparty’s share of revenue and margin-at-risk. One valuation basis: every row’s residual spill is valued at SAWEM (P50 × 0.95) rather than at the book’s spill value, so a strategy that sells 3 % of the surplus is not flattered against the market alternative. Pick Balanced · Margin · Spill · Security · Low risk (#desk-rank-mode) to re-rank; Balanced penalises any counterparty above half of revenue.

The result panel is the heart of the workbench. It shows four deltas (variant minus baseline) with trend icons. Colour is directional: green always means better for the book, even when the number itself falls.

Result Plain meaning Better direction
Δ Margin Extra (or lost) Rand margin Higher
Δ Spill Change in unsold supply (percentage points) Lower
Δ Shortfall Change in unmet demand (percentage points) Lower
Δ Coverage Change in delivered / demand (percentage points) Higher
A coherent "yes"

+R 43,700 margin, −2.1 pp shortfall, +2.1 pp coverage — same story three ways: the candidate earns money and closes the gap.

A coherent "careful"

+R 43,700 margin with +4.0 pp spill — cheap energy with nowhere useful to go. Do not promote on margin alone.

How to read arrows

Green arrow next to −2.1 pp spill is good. The sign is the arithmetic; the colour is the judgement.

Read all four results together. Then either Build Proposal (see §9.6) or clear / pick another candidate.


9.4 Worked variant — test daytime offtake

Follow along. Seat: trader_1@webill.net (password supersecret). Path: Trader Pools → T1 Renewables Pool → Strategy → Simulations. You should see: Sell tab selected by default, Book net position chart (surplus emphasised), Sell Candidates, and Past simulations at the bottom.

Suppose Overview reports midday solar spill on T1 Renewables Pool. You want to know whether a daytime buyer earns its place before you phone anyone.

Starting facts (illustrative full_demo shape)

Input Baseline Variant
Pool / book T1 Renewables Pool Same
Chart Net position surplus tall 10:00–15:00 Same chart (book unchanged)
Candidate None Daytime off-taker, Fit ≈ 85
Capacity Existing members only +5 MW pretend sale
Energy price Existing contracts e.g. book LCOE / typed sale tariff
Scenario SIMULATION SIMULATION

Visual story — three outcomes for the same surplus

Same midday surplus — three commercial stories (illustrative bars, SAST midday hour)
Useful / contracted Unsold / spill Still on grid / shortfall side

1 · Baseline (no new buyer)

Baseline midday hour Contracted band with a large unsold spill band on top. Contracted Unsold Surplus with no home

Read it: generation is fine; the pink band is the sales problem. Fit scores rank buyers against this shape.

2 · Weak fit (flat 24/7 load)

Weak-fit daytime hour Slightly smaller spill band; much of the midday bump remains. More sold Still spill Fit ~55 · partial help

Read it: nights soak some energy, midday still spills. Margin may rise a little; Δ Spill barely moves — do not promote on price alone.

3 · Strong fit (daytime offtake)

Strong-fit daytime hour Mostly useful energy with a thin residual spill band. Mostly sold Fit ~85 · coherent deltas

Read it: the variant should show lower spill, higher coverage, and margin that moves the same way — one story, four numbers.

Step-by-step on the data (what you type and what you look for)

  1. Stay on Sell. Confirm the net-position surplus lobe is tall at midday (if empty, run Forecast in Performance).
  2. Open the highest-fit Off-taker card (daytime shape). Note Fit ≈ 80–90.
  3. On Selected Generation Deal, set target demand pool, capacity (e.g. 5 MW), energy price you would actually quote, term (e.g. 10 years).
  4. Click Simulate Sale. Wait for Result — baseline vs simulated.
  5. Check the four deltas as one story:
KPI Example "good sell" reading Why
Δ Margin +R … (green up) Extra revenue from absorbing surplus
Δ Spill − … pp (green) Midday unsold shrinks
Δ Shortfall ~0 or slightly better You were selling surplus, not covering demand
Δ Coverage + … pp (green) More of generation found a buyer
  1. If the four numbers disagree (margin up, spill up), try another candidate or terms — do not promote.
  2. If they agree, proceed to §9.6. Otherwise leave the row in Past simulations as evidence you tested the idea.

Buy-side twin (same method): switch to Buy (gap lobe emphasised), pick a high-fit IPP, fill Selected Off-take Deal (include wheeling), Simulate Purchase, require margin↑ / shortfall↓ / coverage↑ without a spill blow-out.


9.5 Finding the price where the deal stops working

A single Simulate answers "is this price helpful today?" The next question is harder: at what price does the deal stop helping? The system answers by re-running the same what-if at several energy prices and reading off where your saving (buyer bill improvement vs grid) or margin (seller) crosses zero — the break-even price. Nothing is written to the book; the sweep is analysis only.

Sellers use the same engine on the Sales workbench — see V4 §5.6.1 rather than re-learning it here.

Data. full_demo · seed 42 · stage S09 · numbers below are the engine's August 2026 offtaker what-if shape (0.5 MW AS_GENERATED against Megaflex), rounded for reading.

Starting facts

Actor / input Value
Buyer site OffTaker C Midrand DC (demo offtaker book)
Seller plant daytime solar candidate, 0.5 MW contracted
Energy price tried 40 / 70 / 160 c/kWh (plus 15 c/kWh wheeling)
Period Aug 2026 (one allocator month)
Metric watched Δ saving (R) — buyer's bill improvement vs grid

The arithmetic, stepped

  1. At 40 c/kWh the variant saves about R17,670 for the month (cheap green displaces Megaflex).

  2. At 70 c/kWh the same shape costs about R17,490 (all-in with wheeling now sits above avoided retail in too many hours).

  3. Saving falls roughly linearly with price × deal volume. Zero lies between the two brackets:

    break-even ≈ 40 + 30 × 17,670 / (17,670 + 17,490) ≈ 55 c/kWh

  4. Closed-form cross-check (same month):
    70 + (−17,490) / allocated_MWh / 10 ≈ 55 c/kWh ✓
    (The / 10 converts R/MWh into c/kWh — a factor-of-ten slip here would miss by hundreds of cents.)

What you should take away

Swept price Δ saving (illustrative) Reading
40 c/kWh +R17,670 Comfortably worth doing
≈55 c/kWh ≈ R0 Break-even — above this, walk away
70 c/kWh −R17,490 Paying to take the energy
160 c/kWh deeply negative Far past the useful range

On your own book the absolute Rands differ; the pattern does not: three prices, one zero-crossing, a break-even you can defend on a call. Capacity has a twin question — how much MW before more stops helping? — answered by the same engine's capacity knee (over-contract exposure starts biting past the knee). Advisors and proposal studios surface both; this chapter is the plain-language home for the price side.


9.6 Build a proposal from a simulation

Build Proposal turns an accepted what-if into a private draft — it does not send anything to the counterparty. The simulation's fit score and KPI deltas stay on the proposal message as evidence; advisor suggestions land in your private negotiating brief. Price and capacity sweeps run in the background while the draft builds, so advice is waiting when you reach the pricing stage.

The draft's instrument follows the simulation's target pool: a virtual pool (VIRTUAL / VIRTUAL_BUYERS) produces a virtual proposal; a contracted / buyers pool produces a physical one. Promotion is refused — not silently converted — when that instrument is not available for the pair (for example a virtual promote against an incomplete VWA). The Grid backstop pool still cannot be promoted.

The plain-language home for what the button does on each seat:

You are doing Counterparty Proposal type Where you land
Buying Generator site (IPP) TRADER_IPP Trader Buy studio (…/simulations/proposals/:id/buy) — V7 §3.4e
Selling Off-taker site OFFTAKER_TRADER Trader Sell studio (…/simulations/proposals/:id/sell) — V7 §3.4f
Either Another trader TRADER_TRADER Refused on the workbench — VWA registration for traders is not modelled yet (decisions V2)

After Build Proposal on a supported physical sell path you land in the Trader Sell Proposal Studio — net-position evidence, price card, trader seller terms, and readiness-gated Send to buyer (V7 §3.4f). On a supported physical buy path you land in the Trader Buy Proposal Studio — evidence, contract type, trader buyer terms, and readiness-gated Send to seller (V7 §3.4e). A private negotiating brief and suggestions are already attached. Nothing reaches the counterparty until you send.

Selecting another trader shows an amber banner: Trader-to-trader physical/virtual is not confirmable until VWA registration is modelled — see decisions V2. Simulations stay indicative (NERSA Phase-1/2). Build Proposal repeats that copy in the flash and never invents a draft — you stay on Simulations.


9.7 Use the decision log — and walk the whole screen

Past simulations table

The bottom table (#past-simulations) is your decision log. It does not pretend a discarded idea was a live book position; it answers "why did we not sign?" months later.

Column What you see Why
Direction Badge: Buy (badge-info + shopping-cart) or Sell (badge-success + banknotes) Instantly see which side of the book you tested
Status Status badge: DRAFT / RUNNING (spins) / COMPLETE / PROMOTED / DISCARDED / FAILED Lifecycle of that what-if
Δ Margin Signed Rand delta Quick commercial headline; still re-open the full four-KPI story when deciding

Element-by-element field guide (what to click, what it means)

Work top → bottom, left → right:

  1. Page chrome — Strategy shell, subtitle "Search counterparties, simulate a contract, compare KPIs, build a proposal." Confirms you are on the what-if workbench for this trader pool.
  2. Chart fold header — Book net position. Open / Close collapses the chart when you want more room for candidates.
  3. Net position chart — 24 SAST hours. Rose surplus above zero, sky gap below, dashed contracted reference. Active tab emphasises its side; footnote restates how to read it.
  4. Sell / Buy tab bar (#candidates-tab-bar) — banknotes = Sell, shopping-cart = Buy. Switching clears selection so forms cannot cross-wire.
  5. Candidate groups — Off-takers + Traders (Sell) or Generators + Traders (Buy). Empty group = no eligible counterparties for that kind.
  6. Candidate card — click to select (sky ring), or Tab to the counterparty’s name (a real button, #…-candidate-{id}-select) and press Enter or Space. Fit score is the shape shortlist; details (technology, topology, monthly kWh with comma thousands, etc.) are context for the commercial call.
  7. No Candidate Selected placeholder — dashed card until you pick someone; copy changes with the active tab.
  8. Deal form — Off-take (Buy) or Generation (Sell); ⓘ explains each term; V2-open refusal banner on trader-to-trader.
  9. Simulate Purchase / Simulate Sale — starts the baseline/variant pair; button shows Simulating… while the engine runs.
  10. Result panel — four deltas + Build Proposal; SIMULATION scenario badge reminds you this never supersedes live forecasts.
  11. Past simulations — badges for direction and status; Δ Margin for the archive.
  1. Open Overview; note whether the pain is spill (sell) or grid / shortfall (buy).
  2. Open Simulations; confirm net position and which lobe the active tab emphasises.
  3. Pick the highest-fit candidate on that tab; set terms you can defend on a call.
  4. Run the simulation; require the four deltas to tell one story.
  5. Build Proposal only for that story — or leave COMPLETE / discard later and try the next card.
  6. After a real contract lands, assign it on Pools and re-forecast; do not expect the pretend member to appear by magic.

Follow along. Seat: trader_1@webill.net · Path: T1 Renewables Pool → Strategy → Simulations. You should see Sell selected, Book net position (surplus emphasised), ranked Sell Candidates, deal form after click, result deltas after Simulate, and a Past simulations row with Direction and Status badges.

Start from the portfolio problem, not from the first candidate. Run detail (§8) is where you audit an engine result line-by-line; the proposal workflow lives in the Deals volume. The next chapter covers nominations — a different monthly commitment, not a contract what-if.

9.8 The basket and the Strategy board — several legs as one book

A single what-if answers “this one contract?”. A trader’s real question is “these two sales and that one purchase, together?” — because a purchase only pays when a sale needs its shape, and two sales compete for the same surplus.

  1. Fill the basket. From a candidate card’s + Basket or the deal panel’s Add to basket. Each leg lands in the tray at the bottom (#desk-basket) with its side, terms and whether it has been simulated. Default terms are 5 MW at the book’s base price (sell) or 95 c plus the book’s wheeling rate (buy); a candidate with a complete simulation brings that simulation’s terms.
  2. Simulate basket (#basket-simulate). Every leg without a simulation gets one created; the engine then allocates the whole book with all legs injected at once, no run persisted. The result is named Strategy A, B, … and stays for the session.
  3. Read the board (#desk-strategy-board). Left: buy legs (new and existing) feeding the supply pools. Middle: the pools. Right: sell legs (new and existing) taking energy, each with the kWh it takes and its share of revenue. Between them the co-ordination lines: which purchase feeds which sale. Beneath: the residuals — what still spills to SAWEM and what is still topped up from the grid, in kWh and Rand. Then KPIs before → after (margin, spill, shortfall, coverage, contracted ratio, margin-at-risk) and exposure per counterparty with the concentration verdict. Several strategies sit as buttons above the board.
  4. Compare (§9.3) ranks the strategies against Option 0 and the single legs.

Data. full_demo · seed 42 · T1 Renewables, September. Add OffTaker C Midrand DC (absorbs 3 %) and Simulate basket: the board shows one sell leg taking 1.2 GWh, 91.7 % of supply still spilling to SAWEM, and Compare ranks the strategy just under Option 0 — the desk’s point exactly: sell more, or sell at a better price than the market nets.

9.9 Commit — proposals, the Bid Desk and nominations

The last step (#desk-commit) turns a chosen strategy into work:

9.10 Counterparty exposure in Commercial

The per-counterparty table (#exposure-page, #exposure-table) sits between Compare and Commit: every counterparty on the latest risk snapshot with side, position MW, exposure in Rand, the limit in force and an ok · warn · breach status. It is the page that used to be the Exposure tab; …/strategy/exposure forwards here and carries a ?date= if you had one. The strategy board’s own exposure panel is the forward-looking twin — what the strategy would make each counterparty’s share — so the two read together: today’s book on the snapshot, tomorrow’s book on the board. The risk method behind the snapshot is V3 §22.5.

10. Nominations — the workbench (how much should I commit?)

The trader’s problem. Flexible supply is bought by declaration. Before each delivery month you must tell the system — hour by hour — how much a flexible member will deliver. Guess too low and the shortfall is topped up from the grid. Guess too high and you still pay the physical PPA for energy nobody took. Those two mistakes do not cost the same. This page replaces an eyeball guess with a priced nomination plan you can explain, override, approve, and only then submit.

Open Trader Pools → pool name → Operations → Nominations. Route: /org/trader-pools/pools/:id/operations?panel=nominations&month=YYYY-MM. Legacy nomination links still work. The month selector chooses the delivery month; it does not change a plan’s generation date.

This chapter is written for someone who has never nominated flexible energy before. No jargon assumed. By the end you should know what a nomination is, why the market forces you to make one, how Webill turns that guess into a priced decision, and what to click on the live workbench — every card, tip, empty state and gate that is built now.

Follow along. Seat: trader_1@webill.net (password supersecret). Path: Trader Pools → T1 Renewables Pool → Operations → Nominations. You should see plans for the delivery month and the selected member’s templates.

Data. full_demo · seed 42 · T1 Renewables Pool · last read 2026-09-19 from strategy_nomination_plans on book 01a0ab57-ea8b-76a0-8871-1aa65bef7922. Numbers below are that book’s live rows, not a hand-drawn example.


In plain English — the bakery problem

Imagine you run a bakery that must order flour the day before. Tomorrow’s customers are uncertain:

Those two mistakes do not cost the same. Emergency flour is usually far more expensive than the scrap value of leftovers. So the smart order is not “the average of what I usually sell” — it is a bit higher than average, because running short hurts more than running long.

A nomination is that flour order, for electricity.

Flexible (as-generated / trader-fill) supply is bought by declaration: before each delivery month you must tell the system — hour by hour — how much your flexible member will deliver. Settlement then holds you to that declaration. Guess wrong and you pay, asymmetrically:

Mistake Everyday meaning Money consequence
Nominate too little You promised less than demand needed The shortfall is topped up from the grid at the Eskom top-up rate — usually your most expensive energy, and for firm sales often a locked-in loss.
Nominate too much You promised more than anyone took You still pay the PPA buy price for energy that spills — recovered only at (at best) spill value.

Today many traders still “eyeball” this number. The Nominations workbench replaces the eyeball with a priced, explainable plan: an optimiser proposes the MWh, shows you exactly why, lets you override any hour, and — only after you approve — submits the plan into settlement. Nothing reaches settlement without your explicit sign-off.

Three ways to nominate one evening hour — same uncertain demand, very different bills
Energy that cleared usefully Wasted / spill cost Expensive grid top-up

Too little (shy)

Nominate too little Short bar of nominated useful energy plus a large top-up band for unmet demand. Nominated Grid top-up Cheap promise · expensive fill

Read it: you under-promised. Demand still arrived; the tall amber band is emergency energy at top-up rates.

Too much (bold)

Nominate too much Useful nominated band plus a large spill band of unused energy. Used Spill Paid for · not taken

Read it: you over-promised. The pink band is energy you paid for that nobody needed — recovered only at spill value.

Sweet spot (workbench)

Optimised nomination Mostly useful energy with thin top-up and spill bands — deliberately a little above average. Mostly useful Slightly above average

Read it: because top-up hurts more than spill, the workbench aims a little above the average residual — not at the cap, not at the mean.

What a nomination is used for

  1. Market / SO declaration — the formal “this is how much I will deliver” commitment for the month.
  2. Settlement input — after you Submit, the plan expands into 20-minute nomination rows that settlement (and every NOMINATED run — §6.1) reads.
  3. Book planning — even before submit, the PROPOSED plan is a priced forecast of mismatch cost, so you can see whether a contract’s tolerance band or your top-up rates are about to hurt you.

How you benefit

How to get the best out of nominations

Do this Why it matters
Enrol the right members (§10.1) No tick = no plan. No demand in the book = a correct zero nomination.
Keep pools and PPAs current before the 20th The worker proposes from the book as it stands; stale memberships → stale plans.
Read the rationale on peak hours (especially evenings) That is where asymmetry is largest and money is made or lost.
Override only when you know something the model doesn’t Outages, one-off plant maintenance, known plant trips — not “round numbers”.
Watch the ⚠ tolerance chip A high breach probability means renegotiate the band or accept the penalty before you lock the month.
Approve early, submit before the deadline Two-step sign-off is deliberate; leaving it to the last hour invites mistakes.
After submit, run a Nominated scenario (§6.1) See the declared position in the same charts you already trust.

10.1 Prerequisites — enrolling a member

The workbench operates on nominated members: supply-pool memberships with the Nominated box ticked (§5.3). Two things matter:

  1. The member should carry a physical PPA — the buy price comes from the contract, and submission writes settlement rows against that PPA. A prospect member (site with no contract) can be optimised for planning, but cannot be submitted.
  2. Your book needs demand for the optimiser to measure — the residual it nominates against is your demand minus your non-nominated supply. An empty demand side means a zero residual and a zero nomination (correctly: there is nothing to serve).

If no member is enrolled, #nominations-empty says so: No nominated members. Mark a Flexible-pool membership nominated on the Pools screen, then re-optimise here.

Before the workbench can help — four enrolment stops
1PoolsFlexible member exists
→
2Tick Nominatedenrol on this tab
→
3Demand in bookresidual measurable
→
4Re-optimisefirst PROPOSED plan

10.2 How the optimiser thinks — the newsvendor rule, step by step

The method is the classic newsvendor problem: a newspaper seller must decide this morning how many papers to buy before knowing how many customers will show up. Too few → missed sales; too many → worthless unsold stock. Demand is uncertain and each mistake costs differently — newsvendor is the mathematics of the best quantity under exactly that shape of uncertainty. Here, the “papers” are kWh and the “customers” are your residual demand.

For each nominated member and each hour template (weekday / Saturday / Sunday × hour 0–23) the optimiser walks five steps:

Step 1 — measures the residual demand. It runs your book for the month without its nominated members. Whatever demand goes unserved in that run is, by definition, the energy the flexible member exists to supply — the residual R, per template hour.

Step 2 — admits it doesn’t know the exact number. The residual is a forecast, so the optimiser turns it into a small scenario set: five values around the expected residual, with probabilities. (Until settled-actuals history exists to derive your book’s real forecast-error distribution, default error ratios are used, and the plan records scenario_source: default_quantiles — honest provenance, visible as the Default quantiles badge.)

Step 3 — asks: how much does each mistake hurt?

You can be wrong in two opposite ways. They almost never cost the same:

Mistake Everyday picture What you pay extra
Too little (short) You under-promised; demand still arrived You buy the missing energy from the grid at the expensive top-up rate — instead of from your cheaper PPA.
Too much (long) You over-promised; nobody needed it You still paid the PPA price for energy that spilled — and you only get back the cheap spill credit.

So Step 3 just puts a Rand-per-kWh price on each kind of pain:

Step 3 — what does “wrong” cost?

Short pain (Cu) — each kWh you under-nominated costs you the gap between grid top-up and your PPA buy price.

Long pain (Co) — each kWh you over-nominated costs you the gap between your PPA buy price and what spill recovers.

Short pain Cu  =  grid top-up  −  PPA buy price
Long pain  Co  =  PPA buy price  −  spill recovery

Where the numbers come from: top-up from the firm demand you would otherwise leave short; buy price from that member’s PPA for that hour; spill recovery from the membership’s spill value. You do not type these by hand — the workbench reads them from the book.

Worked feel: if grid top-up is 210c and your PPA is 95c, each short kWh hurts 115c. If spill only recovers 40c, each long kWh hurts 55c. Short hurts about twice as much as long — that fact drives Step 4.

Step 4 — aims a little toward the more expensive mistake.

If both mistakes cost the same, you would nominate the middle of the scenarios (the average). They do not cost the same. When short hurts more, you deliberately nominate a bit high — you accept a little more spill risk to avoid expensive grid top-up. When long hurts more, you would aim a bit low. That “tilt” is all Step 4 does.

Step 4 — how far to tilt?

Think of a scale from 0% to 100% of the residual scenarios (Step 2’s five bars). Step 4 picks a target coverage on that scale:

Aim point  =  short pain  ÷  (short pain + long pain)

Example with the numbers above: 115 ÷ (115 + 55) = 0.676 → aim to cover about 68% of the residual outcomes, not 50%. Then pick the smallest scenario bar that already reaches that 68% — that MWh is the nomination (capped by the member’s MW limit).

If… Aim point What you nominate
Short hurts more (Cu > Co) Above 50% Above the average residual
Both hurt equally 50% Near the average
Long hurts more (Co > Cu) Below 50% Below the average residual

In the screen this aim point is labelled q* (“critical quantile”). You do not need the name — only the idea: tilt toward the mistake that hurts more.

Step 5 — checks the bill before you commit.

Steps 1–4 suggested a nomination. Step 5 answers the only question that matters to a trader: “If I lock that number in, what do I expect to pay for being wrong — and is it better than the obvious alternatives?”

You still do not know which residual will actually happen. So the workbench does not pretend to. Instead it asks, for each possible residual from Step 2:

  1. If I nominated N MWh and reality was R MWh, was I short or long?
  2. Multiply the shortfall (or the spill) by the short pain or long pain from Step 3 — that is the mismatch cost for that one outcome.
  3. Weight that cost by how likely the outcome is (the % under each bar).
  4. Add those weighted costs up — that single Rand figure is the expected mismatch cost for nomination N: the bill you should plan for, on average, if this hour template repeats many times.

It then runs that check for three strategies side by side:

Strategy What you nominate Everyday meaning
Aim for the average The middle / expected residual The “sensible guess” most people make by eye.
Workbench pick (Step 4) The tilted number Deliberately a bit high (or low) because mistakes are unequal.
Nominate the cap The member’s full MW limit “Just max it out so we never go short.”

If the workbench pick is doing its job, its expected mismatch cost is the lowest of the three. That is the proof: not “trust the formula”, but “here is the cheaper bill versus two common guesses.”

Step 5 — what you are looking at

Mismatch cost — the extra Rand you pay when nomination and reality disagree (grid top-up when short, unpaid spill when long).

Expected — not a crystal ball. It means: average the mismatch cost across the five possible residuals, giving more weight to the more likely ones.

Why three strategies? So you can see the workbench beat both “guess the average” and “nominate everything” in Rand, not in jargon.

On the screen this lives in the rationale panel when you click an hour: scenarios, short/long pain, aim point, nomination, and the expected-cost comparison. Months later you can still open that panel and see why that hour said 6.19 MWh.

The five steps as a picture — residual → scenarios → pain prices → tilt → prove the bill
Nomination optimiser pipeline Five boxes left to right: residual, scenarios, short and long pain, aim tilt, prove the bill. 1 · Residual Unserved demand 2 · Scenarios 5 possible R 3 · Pain prices Short vs long 4 · Tilt Aim point 5 · Prove Compare bills

Worked feel — a clean evening hour. A flexible member buys at 95 c/kWh (cap 10 MW); the demand it serves tops up at 210 c/kWh; spilled energy recovers 40 c/kWh. Short pain is 115c, long pain is 55c, aim point is 68%. That picture is how the maths tilts. The T1 demo does not use those prices — its live weekday 19:00 is in §10.10.

The intuition to keep: because being short costs more, nominate above the average — but nowhere near the cap.

The tolerance guard. If the PPA carries an imbalance tolerance band (e.g. ±10%), the plan also reports the probability that the realised residual lands outside the band around the nomination — computed straight off the scenario set. That is the ⚠ tol figure. High % = warning: renegotiate the band or accept the penalty before you sign the month.

10.3 The plans roster

The nominated PPA identity lives in the page heading (#org-page-heading) and the compact line #nominations-ppa-identity under the crumb — member · MW, not a top card. The workbench itself opens with a Plans table (#nomination-plans / #nomination-plans-table): a header strip, then one selectable row per nominated member.

Roster header

Left to right:

Each plan row

Each row is #nomination-plan-row-{membership_id} with data-role=nomination-plan-row. The selected row washes brand green (data-selected=true, aria-pressed=true). Click a row to load that member’s workbench below.

The Member column is the membership’s own label when it has one. On T1 that is Nominated PPPA-202609-867473777 — the same words as #org-page-heading and #nominations-ppa-identity. If the membership has no label, the row falls back to PPA {agreement_ref}, then the generator site name, then Nominated member. The identity line also shows the MW cap when the membership has one.

A plan that exists shows:

Column Meaning
Status PROPOSED (info / light-bulb), APPROVED (warning / check), SUBMITTED (success / paper-airplane). SUPERSEDED plans are filtered out, so you never pick a dead version.
Nominated Month total — T1 312.4 MWh.
E[cost] Month expected mismatch cost — T1 R 61,250.
⚠ tol Tolerance breach probability when a band applies. Amber under 25%, rose at 25% and above. — when there is no band. T1 September is ⚠ 22%; October is ⚠ 65%; August is ⚠ 35%.

vs P50 is not on the table. That saving lives on the KPI strip (§10.4) once you open the plan.

A member with no plan for the selected month shows status — no plan — and — in the numeric columns. The workbench below then shows #nomination-no-plan: No plan yet for {label} — press Re-optimise all to build one for {Month YYYY}.

Which month? The selector defaults to the current calendar month. The monthly worker (§10.7) proposes next month on the 20th — step the chevron forward to see that review. Desk Commit rows also deep-link with ?month=YYYY-MM&from=desk.

10.4 The plan detail — header, KPIs, hour grid and rationale

Once a plan is selected, #nomination-plan-detail (data-status=PROPOSED|APPROVED|SUBMITTED) fills the rest of the page. There are no day-type tabs. Read it top to bottom: header, KPI strip, hour grid, rationale.

Header — same words as the page heading

The workbench heading is the same member label as #org-page-heading — on T1, Nominated PPPA-202609-867473777. Beside it: the status badge, then a scenario source badge (title Scenario uncertainty provenance):

Badge Meaning
Default quantiles Built-in error bands around the residual forecast (used until your book has enough settled history).
Measured Drawn from real forecast-error history (n= sample size when shown). T1 September and August show this.
Override Someone forced custom scenario inputs for this template.
· vN (optional) Version of the forecast-error profile — so two plans can be compared if the profile was updated.

#nomination-plan-meta is the three-part provenance line:

Stepper and the three buttons

The lifecycle rail on the right is #nomination-plan-steps (aria-label="Plan lifecycle"). Three pills only: Proposed → Approved → Submitted. The current step is the solid green pill; earlier steps are done (check); later steps are grey. DRAFT does not appear on this stepper — the optimiser proposes in the same call, so a plan that reaches this page is already PROPOSED or later. SUPERSEDED plans are filtered from the roster.

Three actions sit under the stepper:

Button Id When you see it What it does
Costs (cog) #nomination-open-costs Hidden once SUBMITTED Opens the branded cost modal (§10.4 costs). Re-optimise from that modal only succeeds while the plan is still PROPOSED.
Approve plan #nomination-approve Only on PROPOSED Flash Plan approved. Status → APPROVED; the grid and override form lock.
Submit nominations #nomination-submit Always, but disabled until APPROVED Hover title while PROPOSED: Approve the plan first. While APPROVED: Expand the plan into 20-minute nomination rows for settlement. After submit: Already submitted. Flash: Submitted N 20-minute nomination rows.

That two-step gate is the whole point of the page. Re-optimise cannot sneak past a plan you have already signed.

The KPI strip

#nomination-kpis is five tiles. Every label is an info header whose tip opens above the tile (placement={:top}, tooltip-top).

Tile id Label Tip (exact) T1 September
#nomination-kpi-nominated Nominated Plan’s total for the month. 312.4 MWh · note month total across 72 hour templates
#nomination-kpi-cost E[cost] Month’s expected mismatch cost at the optimiser’s numbers. R 61,250 · expected mismatch cost for the month
#nomination-kpi-saving vs P50 Saving against naively nominating the expected value. R 21,050 saved (green) · 26% below nominating the average (P50)
#nomination-kpi-tol ⚠ tol Tolerance-breach probability. 22% (amber) · chance an hour lands outside the imbalance band. No band → — and no imbalance band on the contract
#nomination-kpi-overrides Overrides Hour templates where you replaced the optimiser’s N by hand. 0 / 72 · no hand overrides — pure optimiser plan. A count turns the tile amber. T1 October is 1 / 72 (weekday 12:00).

This is where vs P50 lives — not on the plans table.

The hour grid

#nomination-hour-grid is one table: a sticky header of hours 00–23, then three rows at once — Weekday, Saturday, Sunday. There is no tab to switch day type.

The title Nominated MWh by hour carries an info tip that opens below the words (placement={:bottom}, class tooltip-bottom). That placement is deliberate — a top tip would cover the bars. The tip says: Optimiser’s nomination per hour (N) for each day type. Bar height = MWh vs this plan’s peak hour. Click a cell to read its rationale below.

#nomination-heat-legend on the right of that title:

Each day-type row (tr[data-day=weekday|saturday|sunday]) shows the day name, then {N} days · {MWh} MWh/day — the calendar count for this delivery month times that row’s hourly sum. Each cell is #nomination-cell-{day}-{hour} (for example #nomination-cell-weekday-19). The number is the effective MWh (your override if you typed one, otherwise the optimiser’s N). The bar grows from the bottom of a 30 px track. A hand override also draws a tick at the optimiser’s N and the green dot in the corner. Hover title on a plain cell: N {MWh} MWh · E[cost] R …/h. On an override: Override {MWh} MWh · optimiser N {MWh} MWh.

Click a cell to select it (aria-pressed=true, brand ring). The rationale panel below updates. The page always keeps a cell selected: on first load it picks the weekday peak hour (or the overall peak if weekday is empty), so the rationale is never a blank hole.

Rationale panel — field by field

#nomination-rationale-panel (data-day, data-hour) is the optimiser showing its homework for one hour template. Title: Rationale · Saturday 19:00 plus why the optimiser nominates what it does for this hour. The scenario-source badge can differ per template (n= when measured).

If that hour has no line, the panel says No optimiser line for {day} {hour} — nothing to explain.

Otherwise three columns:

Residual scenarios — lowest to highest (#nomination-scenario-chart). Five bars, shortest residual on the left. The figure under each bar is the cumulative probability. Filled (darker) bars are outcomes the nomination already covers; the horizontal line is N; a second brand line appears when you have an override (ovr). The chosen bar — the one that first reaches q* — is marked q*. Hover a bar (tooltip-top): X.XX MWh · p=0.yy · cumulative 0.zz. These are five possible residuals, not five nominations.

Decision. #nomination-decision-mwh is the effective MWh for this hour, then MWh this hour. If you overrode, a brand line says Your override — the optimiser proposed {N} MWh. #nomination-decision-reading is a plain-English sentence built from Cu, Co and q* — it will say the optimiser leans high (or low), which scenario it picked, whether a MW cap trimmed it, and how many Rand per hour the tilt saves against P50.

While the plan is PROPOSED, #nomination-override-form sits under that reading. The Override ⓘ opens above (tooltip-top): Replaces the optimiser’s N for this hour when the plan is submitted — only for PROPOSED plans. Clear it to return to N. Type MWh in #nomination-override-input (placeholder is the optimiser’s N), press Save override (#nomination-save-override) → flash Override saved. The KPI override count ticks up and the cell gets data-overridden=true. Clear (#nomination-clear-override, danger style) appears only after a save → Override cleared.

On APPROVED or SUBMITTED the form is gone. The note reads Overrides are only possible while a plan is PROPOSED — this plan is approved and waiting to be submitted. (or this plan has been submitted.)

Numbers (#nomination-rationale-numbers). Every label except Saving is an info tip that opens above:

Label Tip (exact) T1 weekday 19:00
Cu Short pain: extra c/kWh when you under-nominate (grid top-up − PPA). 125 c/kWh
Co Long pain: extra c/kWh when you over-nominate (PPA − spill recovery). 45 c/kWh
q* Aim point: share of residual outcomes to cover — Cu ÷ (Cu + Co). 0.68
nominate Chosen MWh for this hour — smallest scenario that already reaches q*, then capped. 6.19 MWh
E[cost] Expected mismatch cost per hour at this nomination. Lower is better. R 1,013.00/h
P50-nom Same expected cost if you had nominated the average (P50) residual instead. R 1,332.00/h
Saving (no tip) R 319.00/h (green when the tilt is cheaper)
⚠ tol Plan-level probability that an hour lands outside the imbalance tolerance band. 22% on the September plan, plus ⚠ 22% probability outside the imbalance tolerance band

The five residual bars behind that 19:00 cell, lowest to highest: 4.46 · 5.45 · 6.19 · 7.06 · 8.11 MWh at probabilities 10% / 20% / 30% / 25% / 15%.

How to read one panel in ten seconds
  1. Bars — what residual might be.
  2. Cu vs Co — which mistake hurts more.
  3. q* — how far to tilt.
  4. nominate — the number.
  5. E[cost] vs P50-nom — is the tilt worth it in Rand?
  6. ⚠ line (if any) — tolerance trouble ahead?

This panel is the governance heart of the workbench: any nominated number, months later, can be decomposed back into the exact scenario set and costs that produced it.

Costs — changing the optimiser’s assumptions

Costs (#nomination-open-costs) opens #nomination-cost-modal. The title Cost parameters sits in the branded green .wg-modal-header. X (#nomination-cost-close, aria-label="Close cost parameters") and Escape (phx-window-keydown) and the backdrop all close it.

The lead copy: Values below are this plan’s current Top-up and Imbalance tolerance. Edit either field, then Re-optimise to rebuild the PROPOSED plan. Clear a field to fall back to the book / contract default.

When you can use it

What Re-optimise does

The footer note is on the form: Re-optimise supersedes this PROPOSED plan and builds a new one with your overrides stored on the new plan’s params. APPROVED and SUBMITTED plans stay locked. Cancel closes with no change. Success flash: Re-optimised with new cost parameters.

Two fields, each with a “Current plan:” line (#cost-topup-current, #cost-tolerance-current) that names the source — your override, member rate, book default, fallback default, contract, or no band on contract.

Top-up (c/kWh)

What it is. The grid replacement price you pay when you under-nominate — the expensive energy that covers residual demand the flexible member did not cover. In c/kWh. Placeholder Book default.

How it changes the maths. Short pain is Cu = top-up − PPA buy price. Raise top-up → Cu rises → the workbench nominates more (still capped). Lower top-up → less upward tilt. Co does not move.

Why you would change it. A tariff hike the book has not priced yet; a book top-up that looks too high for this member; a what-if before you renegotiate the PPA. After Re-optimise, open a peak hour: Cu, q*, nominate, and E[cost] vs P50-nom should move together.

Imbalance tolerance (%)

What it is. The ±% band around the nomination inside which the PPA treats mismatch as acceptable. Placeholder Contract default. Current plan prints e.g. ±10% · contract or none · no band on contract.

How it changes the maths. Tolerance does not change Cu, Co, q*, or nominated MWh. It only recomputes ⚠ tol. The helper under the field says so: Does not change nominated MWh — only the ⚠ tol breach probability on the plan and rationale panel.

Why you would change it. Stress a tighter or looser band before renegotiation; surface a commercial band the contract row does not yet carry. After Re-optimise, nominate and E[cost] should stay put; only ⚠ tol moves. Change one field at a time when you are diagnosing.

Costs — decide in thirty seconds
  1. Still PROPOSED? If already APPROVED/SUBMITTED, costs will not rebuild the plan.
  2. Changing Top-up? You are changing short pain → expect nominate and E[cost] to move.
  3. Changing tolerance? You are only changing the ⚠ risk flag → nominate should stay put.
  4. Blank = keep the book default; filled = your assumption, stored on the new plan’s params.
  5. Re-optimise → re-open a peak hour rationale and confirm Cu / q* / ⚠ match the story you intended.
  6. Happy? Approve. Unhappy? Adjust again before sign-off — not after Submit.

10.5 Approve and submit — the sign-off gate

The on-screen stepper is the lifecycle you can act on:

Plan status on the workbench — Proposed, then you Approve, then you Submit
PROPOSED
→Approve plan
APPROVED
→Submit nominations
SUBMITTED
From PROPOSED only: RE-OPTIMISE → SUPERSEDED

The monthly worker may create PROPOSED plans; it never Approves or Submits. APPROVED and SUBMITTED plans stay locked. DRAFT never appears on this stepper.

Status path — who moves the plan
  1. Optimise → PROPOSED (the first status you see here).
  2. PROPOSED — you override / approve → APPROVED (optimiser cannot touch it after that).
  3. APPROVED — you submit → SUBMITTED (read-only; Costs disappears).
  4. From PROPOSED only: re-optimise is allowed; the old plan becomes SUPERSEDED and drops off the roster.

What submit actually does. Each hour template expands into real settlement rows: for every matching calendar day of the delivery month, each nominated hour becomes three 20-minute rows of one third of the hour’s energy each — the grain settlement works at. The rows carry the PPA, the SAST-correct interval timestamps, TOU/season/day-type tags, and the plan’s identity as their provenance (submitted_by: strategy_nomination_plan:<id>). The confirmation tells you the scale: Submitted 1,584 20-minute nomination rows. From that moment the rows are visible to settlement and consumed by every NOMINATED run (§6.1).

Example count. A plan nominating 8 evening hours on weekdays only, in a month with 22 weekdays: 22 days × 8 hours × 3 slots = 528 rows, each carrying kWh ÷ 3.

Re-submitting. If you re-optimise and submit again for the same month (before the deadline, or as a post-deadline revision), the previous month’s rows are replaced wholesale — not patched — and the new rows are marked revised instead of firm. Wholesale replacement matters: a revised plan may nominate a different set of hours, and patching would leave stale rows behind. The submitted plan shows its timestamp on #nomination-plan-meta: Submitted 16 Sep 2026 17:51 UTC — read-only.

10.6 A complete worked session — click by click

Walk T1 once from Overview. September on the demo is already APPROVED, so you are looking at a locked grid; step to October to practise override → approve → submit on a PROPOSED plan.

Six steps from Overview to submitted settlement rows

1 · Arrive

From Overview press Open Nominations workbench (#overview-open-nominations). URL keeps ?from=overview. Overview stays lit. Crumb reads Overview · Nominations.

2 · Read the header and the table

The heading names Nominated PPPA-202609-867473777. The Plans table has one row: 312.4 MWh, R 61,250, ⚠ 22% in September. Press the row if it is not already selected.

3 · Inspect 19:00

On the hour grid click #nomination-cell-weekday-19. Rationale should show Cu 125 c/kWh, Co 45 c/kWh, q* 0.68, nominate 6.19 MWh, E[cost] R 1,013.00/h vs P50-nom R 1,332.00/h.

4 · Override (October)

Step to Oct 2026 (PROPOSED). Click weekday 19:00. In #nomination-override-form type a value, Save override → Override saved. Totals recompute; the rationale still records the optimiser’s N. T1 already has one seeded override at weekday 12:00 (6.25 vs 5.65).

5 · Approve

Press Approve plan. Status → APPROVED, the form disappears, Submit nominations enables. Re-optimise all will leave this plan locked.

6 · Submit

Press Submit nominations → confirmation with the 20-minute row count. Status → SUBMITTED, Costs disappears. Launch a Nominated run (§6.1) to see the declared position.

Checklist after submit

  1. Plan badge reads SUBMITTED and the grid is read-only.
  2. Confirmation flash named a non-zero row count (or you know why it was zero — usually no PPA on the member).
  3. A Nominated run for that month shows coverage shaped by your declarations, not a raw forecast shape.
  4. If you must revise before the deadline: re-optimise is blocked on APPROVED/SUBMITTED — create a deliberate new propose path only when your process allows wholesale replacement (§10.5).

10.7 The monthly rhythm — the worker proposes, you dispose

On the 20th of each month at 05:00 (configurable per deployment), a scheduled worker builds a PROPOSED plan for next month for every active nominated member — so when you arrive, the review is waiting rather than the modelling. The worker observes the same lock you do: a plan you have already approved or submitted for that month is skipped, never replaced.

Your only recurring job is the review loop:

Your monthly review loop
  1. 20th — worker proposes next month.
  2. You inspect peak hours + ⚠ tolerance.
  3. Override where you know better (rationale form, PROPOSED only).
  4. Approve → Submit (before the nomination deadline).
  5. Optional Nominated run to verify the declared book.

Do that comfortably ahead of the deadline and nomination stops being a last-minute scramble — it becomes a priced, auditable habit.

10.8 How you get here

Nominations is its own URL. Four doors write ?from= so ‹ Back (#nominations-back) returns to the door you used. A missing or unknown from behaves as desk.

Door Control URL Nav that stays lit Back label
Overview footer #overview-open-nominations · Open Nominations workbench …/nominations?from=overview Overview ‹ Back to Overview → /strategy
Overview ranked leak Re-optimise → Nominations when take-or-pay is under-used or tolerance is breached (§4.5) …/nominations?from=overview Overview same
Desk · Commit row #commit-plan-{id} …/nominations?month=YYYY-MM&from=desk Desk ‹ Back to the Desk → /strategy/simulations
Desk · Commit footer #desk-open-nominations · Open the nominations workbench › …/nominations?from=desk Desk same
Dashboard a Dashboard link that passes from=dashboard …/nominations?from=dashboard Dashboard ‹ Back to Dashboard
Book a Book link that passes from=book …/nominations?from=book Book ‹ Back to Book

Where the doors are taught. Overview actions: §4.5. Desk Commit: §9.9. Getting in: §3.

10.9 Page chrome

While plans load, Shell.page_loading shows Loading nominations…. Then:

  1. #strategy-nav — Overview / Book / Desk / Dashboard. The tab that matches from= is active. There is still no Nominations tab.
  2. Page heading — Desk — Commit · Nominations — {member label} (#org-page-heading) once a nominated member is selected. The compact line #nominations-ppa-identity under the crumb repeats member · MW. There is no Nominated PPA card.
  3. #nominations-desk-crumb — {door} · Nominations. From Overview that is Overview · Nominations. From the Desk, Desk · Commit · Nominations. From Dashboard / Book, those names. The back link sits on the same line.
  4. #nominations-workbench — empty state, or plans table + detail + optional cost modal.

10.10 T1 on the demo

One nominated member, label Nominated PPPA-202609-867473777, PPA PPPA-202609-867473777, membership 01a0ab57-f6dd-70c0-bca0-8db95f74d53b.

Month (selector) Status you will see MWh E[cost] vs P50 (KPI) ⚠ tol Overrides Scenario badge
August 2026 SUBMITTED (Costs hidden; meta shows Submitted … — read-only) 312.4 R 61,250 R 21,050 saved 35% 0 / 72 Measured
September 2026 (default) APPROVED (Submit enabled; override form gone) 312.4 R 61,250 R 21,050 saved 22% 0 / 72 Measured
October 2026 PROPOSED (Approve + override form live) 312.4 R 61,250 R 21,050 saved 65% 1 / 72 (weekday 12:00, 6.25 vs 5.65) see badge on the header
July 2026 SUPERSEDED is filtered — the table row reads — no plan — — — — — — —
November 2026 A seeded DRAFT can appear if you step this far; the live optimiser never leaves DRAFT on this page (it proposes in the same call). — — — — — —

Weekday 19:00 on the August / September / October plans is the same line: 6.19 MWh, Cu 125 c/kWh, Co 45 c/kWh, q* 0.68, E[cost] R 1,013.00/h, P50-nom R 1,332.00/h, residual bars 4.46 / 5.45 / 6.19 / 7.06 / 8.11 MWh.

10.11 Empty states

Id When Copy
#nominations-empty No active nominated memberships in this book No nominated members. Mark a Flexible-pool membership nominated on the Pools screen, then re-optimise here.
#nomination-no-plan Members exist, but the selected row has no live plan for this month No plan yet for {label} — press Re-optimise all to build one for {Month YYYY}.
Hour cell — That day-type / hour has no optimiser line Title No optimiser line; rationale No optimiser line for {day} {hour} — nothing to explain.
KPI — vs P50 or ⚠ tol has nothing to show Saving tile —; ⚠ tol — with no imbalance band on the contract.
Load failure The async page load exits Flash Could not load nominations.

A plan with a PPA-less member can still be proposed and approved; submit writes 0 settlement rows (the flash still reports the count).

10.12 Screen ids

What Id or selector
Strategy tab bar #strategy-nav
Overview / Desk (lit from from=) #strategy-tab-overview · #strategy-tab-desk
Crumb + back #nominations-desk-crumb · #nominations-back
PPA identity #org-page-heading · #nominations-ppa-identity
Page body #nominations-workbench
Empty / no plan #nominations-empty · #nomination-no-plan
Plans table #nomination-plans · #nomination-month-nav · #nomination-roster-summary · #nomination-reoptimise-all · #nomination-plans-table · #nomination-plan-row-{membership_id}
Detail #nomination-plan-detail · #nomination-plan-meta · #nomination-plan-month · #nomination-plan-generated · #nomination-plan-steps
Actions #nomination-open-costs · #nomination-approve · #nomination-submit
KPIs #nomination-kpis · #nomination-kpi-nominated · #nomination-kpi-cost · #nomination-kpi-saving · #nomination-kpi-tol · #nomination-kpi-overrides
Hour grid #nomination-hour-grid · #nomination-heat-legend · #nomination-cell-{day}-{hour}
Rationale #nomination-rationale-panel · #nomination-scenario-chart · #nomination-decision-mwh · #nomination-decision-reading · #nomination-override-form · #nomination-override-input · #nomination-save-override · #nomination-clear-override · #nomination-rationale-numbers
Cost modal #nomination-cost-modal · .wg-modal-header · #nomination-cost-form · #nomination-cost-close · #cost-topup-ckwh · #cost-tolerance-pct · #cost-topup-current · #cost-tolerance-current
Overview door #overview-open-nominations
Desk doors #commit-plan-{id} · #desk-open-nominations

10.13 What this page is not


10.10 Reconcile before sign-off

The Nominated tile is the calendar-weighted total of the effective hourly quantities, including manual overrides. Multiply each day type’s daily total by the number of matching days in the delivery month, then add them. Submission expands those same templates into three 20-minute rows per hour in South African Standard Time (SAST).

If the saved summary differs by more than 0.001 MWh, the roster says needing reconciliation, uncertain cost and tolerance summaries show dashes, and a warning shows both quantities and the calendar counts. Approve plan and Submit nominations are disabled; the server also refuses either action, so the status and settlement rows remain unchanged. Re-optimise a proposed plan. An already approved inconsistent record needs a corrected replacement; the page does not silently rewrite its approval. New demo plans derive totals and costs from their templates. Older demo records can still show this warning. Manual quantity overrides refresh a proposed plan’s quantity summary; cost figures remain the optimiser’s baseline.

11. BESS — dispatch the battery

Open Trader Pools → pool → Operations → Battery dispatch at /org/trader-pools/pools/:id/operations?panel=battery. Legacy /strategy/bess links enter this panel. The five workspace tabs remain visible.

The Forecast fold (#book-battery) is a five-tile summary of that run plus Open full dispatch ›. The destination page is taught in §11.11. Books without an active battery never see the fold or a populated page.

What it is for. A battery is the one member whose value is time itself: it buys hours and sells them back later. This screen gives it a real, deterministic dispatch: an hour-by-hour charge/discharge schedule computed against your book's actual spill and shortfall, priced with the same conventions as everything else, and — critically — explainable both ways: every hour it moved energy shows its economics, and every profitable-looking pair it declined shows why it held.

The classic pattern it monetises is the one most South African books have: midday solar spill (paid-for energy with no buyer) three hours before an evening peak / firm shortfall (energy bought from the grid at punitive rates). A dispatched battery converts the one into the other.

Classic SA day — midday spill becomes evening firm cover (illustrative)
Solar supply Spill / charge BESS discharge Demand line

Without a battery

Same day without battery — midday spill and evening shortfall Solar supply exceeds demand at noon, leaving a spill cap. At 19:00 demand clears a thin firm stack, leaving a shortfall gap. 12:00 spill 19:00 shortfall 08h12h19h21h

Read it: paid-for solar sits unused at noon; the evening demand line clears the stack — expensive grid top-up.

With dispatch

Same day with battery — charge at noon, discharge at 19:00 A dashed gold charge wedge absorbs midday spill. A purple battery band covers the evening firm shortfall. A fine gold SoC line rises then holds. 12:00 charge 19:00 discharge 08h12h19h21h

Read it: the dashed gold wedge soaks spill into the battery; the purple band returns it against the evening firm gap. Fine gold line = SoC.

11.1 The battery's physics, in five parameters

The asset-config modal (⚙, §11.4) captures the battery as the dispatcher sees it. The defaults are sensible for a grid-scale lithium unit:

Parameter Default What it means
Usable capacity (MWh) — The energy window between the SoC bounds — how much the battery can hold.
Max charge / discharge (MW) — Power limits: how fast energy can go in or come out (per hour).
Round-trip efficiency η_rt (%) 88 Of every kWh cycled through, only 88% comes back. Losses are split evenly: one-way efficiency = √0.88 ≈ 0.938, so charging 5 000 kWh stores ≈ 4 690, and delivering 5 000 draws ≈ 5 330 from storage.
Min / max SoC (%) 10 / 100 The operating window — the dispatcher never drains below the floor or fills past the cap.
Initial SoC (%) 10 Where each planning period starts; within a run, each day starts where the previous day ended.
Max cycles/day 1.5 The warranty limit, in equivalent full cycles (energy discharged ÷ usable capacity). The dispatcher will not exceed it, however profitable the day looks.
Degradation cost (c/kWh) 15 Warranty amortisation per discharged kWh — cycling is never free, and this keeps the dispatcher honest about it.
Min spread (c/kWh) 20 The profitability threshold (§11.2). Below it, the battery holds rather than grinding out thin cycles.
Grid charging allowed off Whether the battery may charge from the grid. ⚠ Enabling it adds wheeling cost and dilutes the battery's green (REC) attributes — the modal warns you.

11.2 How the dispatcher decides — the spread rule

This section is for someone who has never dispatched a battery. No trading jargon assumed. By the end you should know what the engine looks at, what "spread" means in Rand, why some hours charge and others discharge, what gets held back, and what to look at on the screen.

In plain English — the warehouse problem

Imagine you run a warehouse that can store goods overnight.

The smart move is obvious: park the leftovers in the warehouse in the morning, sell them in the evening. That is what a battery does with electricity.

Two catches make it non-obvious:

  1. Storage is lossy. Put 100 units in; only about 88 come back out (round-trip efficiency from §11.1).
  2. Cycling wears the asset. Every discharge costs a little warranty money (degradation).

So the engine does not move energy just because "evening is expensive". It asks, for each possible morning→evening pair: after losses and wear, is the profit large enough? That profit gap is the spread. Below your min spread threshold, the battery holds — it stays idle on purpose.

Step 1 — what the engine already knows

Before the battery moves anything, an allocation run has already priced the book without it (Pass A — §7.3). For every hour of the day the engine therefore already knows:

Input Plain meaning Why the battery cares
Spill Paid-for energy with no buyer Cheap (often free) charge fuel
Firm shortfall A firm promise the book cannot cover Highest-value place to discharge — avoids expensive grid top-up
Unmet sales Demand that could still take energy Next best discharge outlet (peak, then standard)
Prices Contract buy, sell, wheeling, top-up Turn every hour into cents per kWh

Those four facts become two numbers per hour: a charge cost ("how expensive is energy going in?") and a discharge value ("how valuable is energy coming out?").

One day's decision path — from the book's facts to a charge/discharge schedule
1Book factsspill, shortfall, prices
→
2Price each hourcharge cost · discharge value
→
3Spread ruleprofit after losses & wear
→
4Schedulecharge · hold · discharge

Step 2 — charge cost (what it costs to fill the battery)

The engine always charges from the cheapest available source first. Think of a shopping list sorted by price:

Charge cost ladder — cheapest first
  1. Spill — energy the book already paid for but nobody took. If spill is zero-rated, charge cost is 0 c/kWh (free fuel).
  2. Surplus PPA energy — leftover contracted supply. Cost = the contract buy price (e.g. 65 c/kWh).
  3. Grid off-peak — buying from the grid to charge. Only available if you ticked Grid charging allowed in §11.1. Usually the most expensive option, and it dilutes green attributes.

Step 3 — discharge value (what the energy is worth coming out)

Discharge goes to the highest-value outlet first — the place where each kWh saves or earns the most:

Discharge value ladder — highest outlet first
  1. Firm shortfall — cover a firm promise the book cannot meet. Value = the avoided Eskom top-up (e.g. 210 c/kWh). This is usually the best use of a kWh.
  2. Peak sale — sell into peak demand. Value = sell price − wheeling (e.g. 150 − 15 = 135 c/kWh).
  3. Standard sale — same idea in standard hours (e.g. 120 − 15 = 105 c/kWh).

Step 4 — what "spread" means in cents

Pick one charge hour and one later discharge hour. The spread is the profit per kWh delivered, after two taxes:

The spread rule — in four lines
  1. Spread = discharge value − (charge cost ÷ η_rt) − degradation.
  2. Dispatch only when spread ≥ min spread (default 20 c/kWh).
  3. Rank clearing pairs highest-spread first (best profit first).
  4. Everything else is held — and listed so you can see why (§11.4).

Plain-language unpacking of the two taxes:

One charge→discharge pair — money in, money out, profit left (illustrative cents per kWh)

Good pair — dispatch

Spill at noon to firm shortfall at 19:00 clears the min spread A tall green value bar at 210, zero charge cost, small degradation bite, large remaining spread well above the 20c line. Value 210 Cost 0 Spread 195 min 20 10h spill → 19h firm · clears ✓

Read it: free midday spill into a 210c firm gap. After the 15c wear tax, 195 c/kWh remains — well above the 20c floor.

Thin pair — held

Paid solar into a standard sale falls below min spread Value bar at 105, charge cost bar after efficiency, degradation, remaining spread 16.1 sitting under the min-20 dashed line. Value 105 Cost 74 16.1 min 20 13h @65 → 21h @105 · held ✗

Read it: paid charge into a weaker sale. Spread is positive (16.1) but below 20 — the engine refuses the cycle and lists it as held.

Step 5 — how charge vs discharge is chosen for the day

For each day the dispatcher roughly does this:

  1. Build candidate pairs — every sensible charge hour × later discharge hour, using the ladders above.
  2. Score each pair with the spread formula.
  3. Drop pairs below min spread (they become the rejected-pairs strip on screen).
  4. Take the best remaining pairs first, subject to physics: usable capacity, max MW in/out, SoC floor/cap, and max cycles/day (§11.1).
  5. Write the schedule — each hour is charge, discharge, or idle; SoC walks from morning start to evening end.

The classic South African shape from the chapter opener — midday spill in, evening firm gap out — is simply the highest-spread pairs winning that race.

Step 6 — what you should look at on the screen

When a day has been dispatched, read it in this order (§11.4 has the full map):

Trader checklist — one dispatched day
  1. KPI strip — day margin (Rand earned), cycles/day (warranty budget), spill absorbed, firm backing, end SoC.
  2. Dispatch chart — bars down = charge; bars up = discharge; SoC and price lines. Full reading guide: §11.4 · How to read the dispatch chart.
  3. Schedule table — hour-by-hour action, kWh, source, cost, value, spread, SoC after, and a plain-English rationale.
  4. Rejected-pairs strip — every pair the engine declined, with the arithmetic ("13h → 21h · spread 16.1 < min · held"). This is how you audit a "no" as easily as a "yes".

If charge energy is free spill, the rejected strip is often empty — free fuel clears almost any threshold. It fills up when charging starts costing real money.

Worked example — one August weekday. Battery: 5 MW / 20 MWh usable, η_rt 88%, SoC 10–100%, degradation 15 c/kWh, min spread 20 c/kWh, start SoC 2.0 MWh. Book that day: zero-rated solar spill of 6.7 MWh/h from 10:00–13:00; peak sales at 17:00–18:00 worth 135 c/kWh net; a firm shortfall at 19:00 whose avoided top-up is worth 210 c/kWh.

Four candidate pairs scored:

Pair value cost ÷ η_rt degr. spread ≥ 20?
spill 10h → firm-short 19h 210 0 15 195.0 ✓ best
spill 11h → peak 18h 135 0 15 120.0 ✓
spill 12h → peak 17h 135 0 15 120.0 ✓
solar @65 13h → standard 21h @105 105 73.9 15 16.1 ✗ held

The last row is the discipline the spread rule buys: 16.1 c/kWh is positive but below the 20c threshold — the battery holds instead of wearing its warranty for thin margin. That is the pair you find in the rejected-pairs strip.

The SoC walk (schedule table):

Hour Action MWh SoC after
10:00 charge from spill 5.0 in 2.0 + 5.0 × 0.938 = 6.69
11:00 charge from spill 5.0 in 11.38
12:00 charge from spill 5.0 in 16.07
13:00 charge from spill 4.19 in (clipped) 20.00 — the cap
14–16 idle — 20.00
17:00 discharge to peak 5.0 out 20.00 − 5.0 ÷ 0.938 = 14.67
18:00 discharge to peak 5.0 out 9.34
19:00 discharge to firm 5.0 out 4.01 (20%) ✓ above the floor

The battery charges 19.19 MWh to deliver 15 — the 13:00 top-up to the cap is free spill banked so SoC survives three full-power discharge hours. Cycles: 15 ÷ 20 = 0.75 of the 1.5/day cap ✓. Book spill that day drops from 26.8 to ~7.6 MWh.

The economics: peak sales 2 × 5 000 kWh × 1.20 = R 12 000; firm backing 5 000 × (2.10 − 0.15 − 0.15) = R 9 000 → ≈ R 21 000 for the day, against R 0 for the same battery sitting idle — and midday take-or-pay spill is partly recovered as the charge source.

11.3 Setting a battery up

  1. The site must be a battery. Only generator sites with technology BESS or HYBRID can carry dispatch parameters — the form rejects anything else.
  2. Configure the dispatch parameters. If your book has no configured battery, the BESS screen's empty state lists your organisation's eligible BESS/HYBRID sites, each with a [Configure dispatch] button → the asset-config modal (§11.1). One battery configuration per site.
  3. Make it a pool member. The dispatcher only sees batteries that are active members of an active supply pool — conventionally your 🔒 Firm pool (a battery is the classic firm-backing asset). Add the site as a member on the Pools screen (§5.3).
  4. [Re-run dispatch] — runs the current month; the two-pass (§7.3) engages and the day view populates.

To stop dispatching without losing the configuration, edit the asset and untick active — the member reverts to a plain flat firm block.

11.4 Reading the screen

The chart-reading guide lives here. The full /strategy/bess walk — every control, id, empty state, and the T1 demo — is §11.11.

The page is one day inside the battery’s month, under the Book. It opens with the Book’s thread strip (#book-thread, Forecast stage lit), a breadcrumb Book · Forecast · Battery dispatch (#bess-crumb) naming the run this dispatch belongs to, and ‹ Back to the forecast (#bess-back-to-book). Then a headline written from the selected day, the five facts, the dispatch chart, the day as moves, the reserve verdict when one exists, and the hourly schedule folded beneath. The right rail holds the month heat-calendar, the asset card, and what the battery feeds in the Book.

The identical day view appears as the BESS tab inside any run detail that dispatched a battery (§8.4) — there it shows that run’s frozen schedule; /strategy/bess shows the latest Forecast that already has intervals.

How to read the dispatch chart

This is the picture of one selected day: what went into the battery, what came out, how full it was hour by hour, and what each active hour cost or earned. You do not need trading jargon — only the words below.

Terms used on this chart

Term Plain meaning
Charge Energy going into the battery this hour (filling it).
Discharge Energy coming out of the battery this hour (emptying it into a use).
SoC (state of charge) How much usable energy is stored at the end of the hour, in MWh.
Price (on the chart) The cents-per-kWh figure for that hour's action: charge cost on charge hours, discharge value on discharge hours. Idle hours sit at zero.
SAST South African Standard Time — every hour label on the chart is a SAST clock hour.
Axes and units

The chart has three scales working together:

What each axis shows
  1. Bottom (X) — hours of the selected day, labelled 0h … 23h in SAST. Each bar is one settlement hour.
  2. Left (Y), unit MWh — energy. Charge and discharge bars are megawatt-hours moved in that hour. Because the interval is one hour, bar height in MWh also equals average power in MW for that hour — but the axis title on screen is MWh, not MW. The SoC line uses this same left axis (stored energy).
  3. Right (Y), unit c/kWh — money intensity. The dashed Price line (and, when present, the P25–P75 forecast ribbon) plot here. Split gridlines are hidden on the right axis so the energy picture stays primary.

Zero on the left axis is the mirror line: charge bars grow downward (negative), discharge bars grow upward (positive). That is deliberate — energy in and energy out are opposite directions on the same scale.

Legend — each series on the live chart

The legend under the plot lists these names exactly as the UI draws them. Series that have no data that day simply stay flat at zero (or hide their band).

Contract charge

Bars below zero in emerald (#059669). Energy charged from non-market sources — typically spill (paid-for energy with no buyer) or leftover contract supply. On T1 this is the overnight fill, not a midday solar wedge.

Market charge

Bars below zero in a separate amber tone. Energy bought from the market / grid to charge the battery. Only appears when Grid charging allowed is on (§11.1). Treat it as a warning colour in the story: real money went in, and green attributes may dilute.

Contract / firm Discharge

Bars above zero in amber (#f59e0b). Energy discharged into the book's own outlets — covering a firm shortfall, or selling into contracted / peak demand. This is the "evening cover" stack on a classic day. T1’s October forecast instead sells evenings to market (pink), so this series often stays flat.

Market Discharge

Bars above zero in pink. Energy discharged into the market rather than the book's firm or contract outlets. Absent on many books; when present it means the battery earned by selling out rather than by covering your own shortfall.

SoC

A smooth purple line on the left (MWh) axis. End-of-hour stored energy. It should rise through charge windows, hold (flat) through idle hours, and fall through discharge windows. It must stay inside the asset's min/max SoC window (§11.1).

Price

A dashed slate line on the right (c/kWh) axis. On a charge hour it is the charge cost; on a discharge hour it is the discharge value. Hover the chart to read the exact number for that hour. Idle hours sit near zero — there was no priced action.

P25–P75 forecast

A soft purple ribbon on the right (c/kWh) axis. Shown only when the day used a market price forecast. It is the uncertainty band between the 25th and 75th percentile forecasts — the lane the dispatcher considered for market-aware hours. If you see no ribbon, that day had no forecast cells attached.

Reserve floor

A teal dashed band / floor on the left (MWh) axis. Shown only when the run held a reserve (see the Reserve band KPI and the Reserve availability card under the chart). It marks the raised SoC floor the battery must respect — energy kept back rather than fully discharged for arbitrage. The companion "Reserve base" series is the ordinary min-SoC floor; the legend highlights Reserve floor as the held level.

Note. "Spill absorbed" and "Firm backing" are KPI tiles, not legend series. The chart shows where energy moved; the schedule's Source / Outlet badges and those KPIs tell you why that movement mattered for spill and shortfall.

Annotated dispatch chart — classic midday charge → evening discharge (illustrative; matches live legend roles)
Contract charge (↓) Contract / firm Discharge (↑) SoC line Price (dashed)

One day on the dispatch chart

Mirrored charge and discharge bars with SoC and price lines X axis hours 8 to 21 SAST. Left axis MWh with charge bars below a centre zero line at midday and discharge bars above at evening. Purple SoC line climbs then falls. Dashed slate price line sits low at noon and high at 19h. MWh c/kWh 0 charge ↓ discharge ↑ SoC → 08h12h19h21h

Read it: left axis = MWh (bars + SoC); right axis = c/kWh (dashed Price). Midday bars below zero fill the battery; evening bars above empty it; SoC climbs then falls; Price is cheap at charge and valuable at discharge.

Step-by-step — reading one day

Use this order every time. It turns a busy plot into a five-minute audit.

Six steps — how to read the dispatch chart
  1. Orient on the day and the hours. Confirm the day picker selection and the amber selected-day badge on the chart header. Scan 0h → 23h (SAST). Mentally mark midday (roughly 10h–14h) and evening peak (roughly 17h–20h) — that is where classic SA books move energy.
  2. Find the charge windows. Look below the zero line for emerald Contract charge (and any amber Market charge) bars. Note which hours are tallest — those are the main fill hours. Idle hours have no bar.
  3. Find the discharge windows. Look above the zero line for amber Contract / firm Discharge (and any pink Market Discharge) bars. Check that discharge sits later than the charge you just found — time-shifting is the whole point.
  4. Trace the SoC trajectory. Follow the purple SoC line left → right. It should rise while charging, stay flat while idle, and fall while discharging. Ask: does it hit the cap too early (clipped charge)? Does it scrape the floor (or a teal Reserve floor) before evening is done? End-of-day SoC should match the End SoC KPI — that is tomorrow's start.
  5. Look for rejected opportunities and gaps. Hours with no bars between a charge block and a discharge block are idle by design, not missing data. Then drop to the rejected-pairs strip: every held pair ("13h → 21h · spread 16.1 < min") is a profitable-looking move the engine refused. Tall midday spill with an empty evening and a busy rejected strip often means the spread rule (or cycles/SoC limits) blocked cover — not that the chart failed to draw.
  6. Compare to the demand / spill story. Pair the picture with the KPI strip and the Hourly schedule:
    • Midday Contract charge + schedule Source = Spill → this is spill absorbed into storage (the Spill absorbed KPI).
    • Evening Contract / firm Discharge + schedule Outlet = firm → this is shortfall covered / firm backing (the Firm backing KPI).
    • Read the dashed Price line (or hover tooltips): charge hours should be cheap (often 0 c/kWh on zero-rated spill); discharge hours should be valuable (firm avoided top-up is often the tallest). If Price is high on a charge bar, you are looking at paid or market charge — check whether that still cleared min spread in the schedule's Spread column.

Tip. Hover any hour on the live chart for the axis tooltip (all series at that hour). Then open the matching row in Hourly schedule for Source, Outlet, Spread, and the plain-English Rationale — chart for shape, table for proof.

[⚙ Asset config] on the right-rail asset card re-opens the parameters modal (§11.1); saving prompts "Battery saved. Re-run dispatch to apply." — configuration changes never silently alter an existing run (immutability, §1.3); they take effect on the next run, whose inputs hash will show the change. The full modal walk is §11.11.

11.5 What it feeds

The dispatch flows into everything downstream automatically: the run's BESS_CHARGE / BESS_DISCHARGE lines (§8.5) roll into the run KPIs, the nightly snapshot picks up four battery metrics (arbitrage margin, cycles/day, spill absorbed, firm backing — §12.7), the dashboard's ⑥ BESS panel displays them, a cycles/day risk limit (§12.6) turns warranty discipline into an alert, and the Overview's next-best-actions (§4.5) prompt you when the battery runs near its cap with profitable pairs still on the table — the data-driven case for a bigger battery, which the Simulation workbench (§9) can then price.

11.6 In the wholesale market, degradation cost travels as a price

Worth knowing before your battery enters SAWEM, because it changes where one of these parameters lives.

The market registry asks a storage unit four things (§7.4): its charging rating, its minimum stable charging point, its energy levels, and its cycle efficiency. It asks nothing about degradation. There is no field for cost per discharged kilowatt-hour, no field for maximum cycles per day, and no field for minimum spread — the Market Operator has never heard of them and could not act on them if it had.

So those three stay here, doing exactly what they do now: driving dispatch, gating pairs on the spread rule (§11.2), and feeding the cycles/day risk limit. They are not sent to the registry, and the registration payload is tested to exclude them.

The cost still reaches the market — as a price. A battery’s offer is a ladder of cost increments, and the deeper rungs, the ones only reached on a hard discharge, carry more degradation than the shallow ones. A shallow cycle offers cheaper than a deep one, which is what the physics says and what a market can actually act on.

Two things follow for how you read a market offer built from this book:

How much of a cycle counts as “shallow”, and whether the ladder reflects marginal or average life cost, are open commercial decisions rather than calculations. Building the offer is V9 §5’s territory; what a storage unit registers is V9 §3.7.

11.7 The market offer still carries a flat addend

§10.6 above described where degradation cost would travel. It now travels. When the desk builds a submission curve for a storage unit, the degradation cost is added to every discharge block’s cost increment before the curve goes to the market. It is no longer a parameter that stops at the book boundary.

Two things about that are worth stating plainly, because the second one is a limitation and not a feature.

The decision. Degradation reaching the market through the offer price is a decision, not something derived from the Market Code. The Code gives a storage unit no field for it, and it was never going to grow one — degradation is a commercial parameter and the registry holds physical ones. Pricing it into the offer is the only route left, and it is recorded as such rather than presented as the obvious reading.

The market-offer addend is a single constant. In the market curve, a shallow cycle and a deep one price identically. The same rand-per-megawatt-hour is added to the first discharge block and the last, which is precisely what §10.6 said should not happen. It is a placeholder that works and is honest about being one: the code asserts that market-curve limitation by name in a test. The book’s dispatcher now uses the owner’s depth curve when one is recorded; this does not change the wholesale offer builder.

Depth would need the increments to differ by block — the third block carrying more life cost per megawatt-hour than the first. Deciding by how much is a question for a battery engineer with your warranty curve, not for a reading of the Market Code, which is why it is still open.

What this means for you in the meantime: your battery’s offers into SAWEM are cost-covering on average across a cycle and wrong at both ends of one. If your commercial case turns on deep-cycle discipline, keep the min_spread rule doing that work here in the book, where it is depth-aware, rather than expecting the market offer to carry it.

11.8 Depth: the same kilowatt-hour costs more at the bottom of the battery

The owner can record a warranty cycle-life curve on Battery contract. Load LFP default fills the editor with the illustrative LFP default v1 table; it does not save or apply it. The owner must also record the cycling-attributed pack replacement cost and provenance, including residual-value treatment. A battery without a table keeps its configured flat wear cost, normally 15 c/kWh. The trader sees the resulting Depth (%) and Wear (c/kWh) on each dispatch interval.

The dispatcher divides effective capacity into ten equal terminal-energy slices. Each slice costs the extra fraction of a pack consumed at that depth, divided by the slice’s kWh. It only discharges a slice when the outlet price less charging cost, efficiency losses and that slice’s wear clears the minimum spread. A depth wear hold means the next slice failed that test.

Depth band LFP default wear (c/kWh), 20 MWh and R25.2m pack
0–10% 5.65
10–20% 11.49
20–30% 15.67
30–40% 19.04
40–50% 22.27
50–60% 25.09
60–70% 28.06
70–80% 30.23
80–90% 33.41
90–100% 34.09

On a shallow day delivering 8,000 kWh, the table charges R1,037.04 of wear, compared with R1,200 at flat 15 c. At an outlet worth 62 c with charging at 10 c and 88% round-trip efficiency, the eighth slice still clears a 20 c minimum spread; the ninth does not. The depth model stops at 16,000 kWh and books R3,150 of wear. A single fill of this battery, with its 10% storage floor, can physically deliver at most 16,885.50 kWh; an 18,000 kWh flat comparison would need another charging opportunity during the day. Wear is based on cumulative terminal discharge, not the instantaneous percentage of stored energy.

11.9 State of health

The owner records a dated capacity test rather than overwriting history. A 94% test makes a 20 MWh asset dispatch as 18.8 MWh from that date: its 10% floor becomes 1.88 MWh and its 1.5-cycle budget becomes 28.2 MWh. Power ratings stay unchanged. Before any test, dispatch uses nameplate capacity. Existing runs retain their applied health percentage in their daily audit.

Smaller slices also increase wear per kWh if the pack replacement cost is unchanged. At 94% health the ladder is divided by 0.94; on the 62 c example above the eighth slice now fails and the depth model stops at 70%, or 13,160 kWh. Health and pack cost are visible only to the owner. The trader’s two contract chips show cycles against the owner’s cap and measured round-trip efficiency, with No settled month yet before ACTUAL battery evidence exists.

11.10 The two plans of one day

Open Plans to compare the day-ahead and latest intraday schedules. The hand-over hour marks where the replacement schedule starts. Earlier hours are copied from the preceding plan; their energy and ending state of charge do not change. Without a replan, the screen says No re-plan today. The reserve-floor band marks the storage that a contracted upward service needs.

A weather refresh rebuilds the remaining plan before the IDM decision reads the position. A completed 2 MW, one-hour upward activation draws 2,000 terminal kWh and reduces stored energy by 2,132.007 kWh at 88% round-trip efficiency. The daily audit records that correction and its instruction reference. Replaying the same inputs creates no extra plan. Later replans carry the executed part of the earlier intraday plan and apply each activation once. A measured state of charge can replace the assumed hand-over value when telemetry is available.

For the noon example, 10,000 kWh charged before noon leaves 11,380.832 kWh in storage. If only 1,200 more kWh can charge, evening delivery falls from 13,000 to 9,856 kWh: a 3,144 kWh change. The state of charge immediately before noon is conserved; the ending value of the changed noon interval is expected to differ. The IDM decision uses the revised suffix while the DAM record and the day-ahead forecast remain available.

11.11 The /strategy/bess page

The problem. The Forecast fold tells you whether this run used the battery. It does not show the day. You still need to see the tank fill and empty: which hours charged, which hours discharged, why a pair was held, and which settings the dispatcher obeyed.

Think of the battery as a water tank. Cheap leftover energy is water you pour in. Expensive evening hours are taps you open later. This page is the tank’s diary for one day — and a calendar of the other days in the same run.

Data. full_demo · seed 42 · T1 Renewables Pool (01a0ab54-e46b-7dde-b45f-73d119213c75) · Rosslyn BESS (5 MW / 20 MWh) · last read 2026-09-19 from the seeded book.

Follow along. Seat: trader_1@webill.net (password supersecret). Path: T1 Renewables Pool → Book → Forecast → #book-battery → Open full dispatch ›, or open /org/trader-pools/01a0ab54-e46b-7dde-b45f-73d119213c75/strategy/bess directly. You should see Book lit on #strategy-nav, Forecast lit on #book-thread, and a headline for Sunday 13 September.

How you get there

There is no BESS door on #strategy-nav. The four tabs stay Operations · Performance · Allocation · Commercial · Dashboard. While you are on this page, Allocation (#strategy-tab-book) is the lit tab.

Ways in:

Door What it does
Forecast fold Open full dispatch › From #book-battery on Book · Forecast (§6.17). The href is /strategy/bess with no ?run= — the page picks its own run (below).
Direct URL /org/trader-pools/:id/strategy/bess
Overview next-best action Battery at {n} cycles/day — near the warranty cap → Open BESS /bess (§4.5)
Run detail BESS tab The same day view (BessView) frozen to that run (§8.4). Use this when you need a month that is not the latest Forecast.
Old BESS tab /bess still opens this page under Book (§3.4)

The Forecast fold stays the summary. Do not expect the hour table there.

Which run it opens

The page heading is Dispatch — {power} MW / {energy} MWh (T1: Dispatch — 5 MW / 20 MWh). The subtitle: The battery’s part of the forecast run: one dispatched day at a time, inside its month, under the Book.

On connect it shows Loading BESS dispatch…, then binds one run:

  1. Take the book’s latest complete, non-superseded Forecast run (§6) (latest_allocation_run sorted by creation, not by calendar month).
  2. If that Forecast already stored dispatch intervals, use it.
  3. If it stored none, walk other complete non-superseded runs and take the first that has intervals (older demos sometimes left battery evidence only on a Simulation).

T1’s latest Forecast with intervals is the September 2026 P50 (01a0b951-b50d-76c2-bfd8-840b7ecc12cd). The crumb chip reads FORECAST P50 · 01 Sep 2026 → 01 Oct 2026 · complete. The run KPIs are all zero: arbitrage R 0, cycles 0.00 / day, spill absorbed 0 %, firm backing 0 %. That matches the Forecast fold’s tiles (§6.17).

The page does not read ?run= or ?month= from the Forecast URL. If you had a different run selected on Forecast, Open full dispatch › can still land on this latest Forecast. To inspect another run’s battery, open that run’s ledger and use the BESS tab.

T1 also has an October 2026 P50 Forecast (01a0ab61-a371-729c-b79c-c36c7881b70f) that did dispatch — about R 569,889 arbitrage over the run, 0.836 cycles a day, 1.3 % of spill absorbed, still 0 % firm backing. It is older by creation, so /strategy/bess does not open it. The worked days below use September for what this page shows, and 29 October for a day that actually moved energy.

Top of the page

Read downward.

#book-header / #book-thread. The same three-stage strip as every Book view: Rules → Forecast → Outcomes. Forecast is lit (#book-stage-forecast). The Forecast pill is the book’s spill or coverage word — not a battery pill. Click Forecast to leave this page and return to the fold.

#bess-crumb. Book · Forecast · Battery dispatch — 5 MW / 20 MWh, then the run chip (data-role="bess-run-chip") and the words the battery’s part of this run.

#bess-back-to-book. ‹ Back to the forecast returns to /strategy/book?mode=forecast&run={id}&month={YYYY-MM} when a run is bound, or to Forecast without a run if none is.

#bess-contract-chips. Two owner-facing numbers the trader may see:

Chip Id What it says
Cycles to date #bess-cycles-chip Trailing-year cycles against the owner’s BESS_CYCLES_PER_YEAR cap, or No settled month yet · owner’s cap {n / not recorded}
Measured RTE #bess-rte-chip Measured round-trip efficiency after an Actual month, or No settled month yet

T1 shows No settled month yet on both until Actual battery evidence exists. Health and pack cost stay on the owner’s Battery contract (V4 §20).

#bess-flat-model. A one-line note Wear: flat {n}c/kWh (no cycle-life table). Hidden on T1 — Rosslyn carries a cycle-life table, so wear varies with depth (§11.8).

#bess-plans. A closed <details>: Plans · day-ahead and intraday. With no intraday replan for the selected day, #bess-no-replan reads No re-plan today. When an Intraday run exists for that date, #bess-plan-comparison shows the hand-over hour (#bess-hand-over) and a 24-row table of day-ahead vs intraday discharge (#bess-plan-hour-0 … #bess-plan-hour-23). How the two plans relate is §11.10. On T1, 13 September has no replan; 19 September can.

A simulated ribbon appears only when a Simulation owns the bound run. T1’s September Forecast does not show one.

The headline and the facts

#bess-headline is one sentence written from the selected day’s moves and the run’s battery KPIs.

T1 on Sunday 13 September charges 2.3 MWh from spill and discharges nothing, so the sentence reports earned R 0 and the run’s zeros. Later September days (14–19) take the did nothing wording.

Under the headline: One day of the battery’s month. The facts, the chart, the moves and the hours are one object; the day strip on the right is how you change it…

The facts (data-role="bess-facts") sit above the chart. Each tile (data-role="bess-fact") has a label, a short hint, the day number, a run · line for the whole Forecast, and a pointer to the chart or table that proves it.

Label Hint Day number Run line Pointer
Day margin Realised discharge margin for selected day Rand for this day run · {R} · arbitrage over the run → the moves below
Cycles/day Discharged energy ÷ usable capacity ÷ days (vs warranty max cycles/day) This day’s equivalent full cycles run · {n} · a day over the run · cap {max} → energy moved
Spill absorbed Spill converted to stored energy The run’s % (not re-cut per day) of the book’s spill, over the run → the teal charge bars
Firm backing Output serving firm shortfall The run’s % When zero: discharges into the market, not Firm Pool shortfall → the outlet column
End SoC Energy carried into next day Last interval’s SoC, MWh min {floor} · max {cap} MWh → the SoC line’s last point

Three extra tiles appear only when the run stored them:

Label When What it is
Market arbitrage bess_market_arbitrage_r present Day-ahead spread against the P25–P75 forecast
Reserve band bess_reserve_mwh present MWh held back for the reserve offer
Forecast slippage bess_forecast_slippage_r present Realised against the price forecast

T1 September shows the five standing tiles at R 0 / 0 / 0 % / 0 % / 4.0 MWh on the 13th (End SoC is the tank after the 2.3 MWh charge). Market arbitrage, reserve band and slippage stay hidden — the KPI map has no keys for them. Firm backing’s run line is the amber warning: this battery sold (or sat) rather than covering Firm Pool shortfall.

The dispatch chart on this page

The chart lives in a white card titled Dispatch chart. Subtitle: Charge bars below zero, discharge above — with SoC (MWh) and price (c/kWh) over the day. The moves under the chart are the same hours, grouped. The amber selected-day badge is #bess-chart-selected-badge. The plot itself is #bess-dispatch (the shared .StrategyChart hook).

How to read the axes, colours and legend is §11.4. Do not re-learn it here.

On T1 13 September you will see a small emerald Contract charge bar at 0h and a flat night. No discharge bars. The purple SoC line steps from the morning start up to 4.0 MWh and holds. That is an honest empty-ish day, not a broken chart.

The day as moves

#bess-moves groups consecutive hours that did the same thing. One row (data-role="bess-move", data-kind, data-hours) per block.

Kind Left border Title pattern Money
Charge Teal Charge {MWh} MWh from {spill / the market / the grid / contract supply} −R {charge cost} · bought · charge
Discharge Sky Discharge {MWh} MWh to {market / firm shortfall / contract demand} +R {margin} (rose if negative) · margin · discharge
Held Dashed grey Held plus the rejected pair that starts in the block R 0 · declined
Idle Dashed grey Idle or Held · full R 0 · waiting

A lone idle hour is dropped (the table still has it). Two or more idle hours become a row.

Under the rows: Rejected pairs — why the battery held. Empty copy: None — every profitable charge→discharge pair was dispatched. When pairs exist, each line is {charge}h → {discharge}h · spread {c} · below minimum · held (or held by marginal depth wear). Market-sourced holds show the P25 − P75/η − degradation arithmetic.

T1 13 September: one charge move (Charge 2.3 MWh from spill at 40 c), then a held/idle evening whose schedule rationale is contracted reserve held. Day margin stays R 0 because nothing came back out.

If the selected day has no intervals, the section says No dispatch on this day.

When the run held a priced reserve, #bess-reserve-verdict appears under the moves: Reserve availability (MWh at the schedule boundary, market alternative vs reserve offer, and why the floor was held or released) plus the reserve card. T1 September does not render it — bess_reserve_mwh is absent — even though some hour rationales still say the reserve was held.

Hourly schedule

#bess-hourly-schedule is a dashed <details>, closed until you open it. Summary: Hourly schedule — Charge and discharge actions for the selected day, hour by hour — the 24 rows behind the moves. Badge: #bess-schedule-selected-badge.

The table is #bess-hourly-schedule-table. Above it, the sun/moon legend: Sun hours 06–17 / Dark hours 00–05 and 18–23. Each hour cell carries a sun or moon.

Column Tip on the header What you read
Hour (no tip) SAST hour with sun/moon
Depth (%) Depth of discharge, percent End-of-hour depth, or Not recorded
Wear (c/kWh) Wear cost, cents per kilowatt hour Slice wear, or Flat model
Action charge when energy enters; discharge when it leaves Emerald charge or orange discharge badge
kWh Energy moved this hour Charge-in or discharge-out, rounded
Source Spill, Contract, or Market — blank on discharge Amber Spill, cyan Contract, rose Market
Outlet contract, firm, or market — blank on charge Teal contract, violet firm, rose market
Forecast Short price-forecast id and confidence lane {first 8 of id} · {lane}, or —
Cost Charge cost in c/kWh The stored cost; — when idle
Value Discharge value in c/kWh Blank on charge rows
Spread Value minus cost against the min-spread rule Often blank on a pure charge
SoC State of charge after the hour, MWh End-of-hour usable energy
Rationale Human-readable reason e.g. charge 2.27 MWh from spill @ 40.0c

Empty body: No dispatch this day. (13 columns.)

These rows are the persisted dispatch intervals — the audit trail behind BESS_CHARGE / BESS_DISCHARGE lines (§8.5).

The right rail

On a wide screen the rail is the right three columns. On a narrow screen it stacks under the day view.

#bess-day-picker. Card labelled Dispatch period, with the run’s first–last interval dates (T1: 13 Sep 2026 – 19 Sep 2026 — only days that stored intervals, not the whole September month). Selected-day badge: #bess-day-selected-badge. Month label with ‹ › (shift_calendar, disabled at the edges of the interval set). Weekday chips Mon–Sun. Each date is #bess-day-{YYYY-MM-DD} (data-role="bess-day-tile"). Days without intervals are greyed and disabled. A teal bar (data-role="bess-day-bar") is that day’s margin, scaled to the month’s tallest day. Footer: Each tile’s bar is that day’s margin; the month reads before you click. Click a live tile to rebuild the headline, facts, chart, moves and table for that date.

#bess-asset-card. The asset — The numbers the dispatcher obeys. Each row is data-role="bess-param":

Label Note T1 Rosslyn
Power max charge / discharge 5 / 5 MW
Energy usable · SoC 10–100 % 20 MWh
Round trip efficiency η 88 %
Cycles warranty cap a day 1.5
Degradation priced into every spread 15 c/kWh
Min spread below this the engine holds 20 c/kWh
Grid charging market as a source allowed

⚙ Asset config opens the branded Edit battery modal (green #wg-modal-header, close #bess-config-close, Escape or Cancel). Fields match §11.1, each with an info tip. Allow grid charging warns that grid charge adds wheeling and dilutes green (REC) attributes. Submit is Save & re-run. Success flash: Battery saved. Re-run dispatch to apply. Failure: Could not save the battery configuration.

Re-run dispatch runs the engine for the current calendar month (not the bound Forecast’s month) and flashes Dispatch re-run. Then the page reloads. Re-run never silently edits the old run (§1.3). The note under the buttons: Re-run recomputes this run’s battery pass; the Book’s Forecast stage re-reads.

From the empty-battery state the same modal is titled Configure battery and is reached from Configure dispatch on an eligible site.

#bess-feeds-card. What it feeds in the Book.

Row T1 September
Firm Pool shortfall · member of the Firm pool Amber pill 0% backed
Book spill · charged at the spill value Teal pill 0% absorbed
Market arbitrage · day-ahead spread Hidden unless the KPI exists

Links: Rules · Firm Pool card › → /strategy/pools, and Forecast · battery fold › → the same Forecast URL as ‹ Back to the forecast.

Empty states

What you see When What to do
No battery configured. Dispatch modelling needs a BESS or HYBRID generator site with dispatch parameters. plus a list of eligible sites and Configure dispatch The book has no active BessAsset member Configure, then add the site to a supply pool (§11.3)
No eligible BESS/HYBRID sites in this organisation yet. Empty list inside that dashed box Register a BESS or hybrid site first (V2)
No dispatched run yet — press Re-run dispatch. A battery is seated but no complete run stored intervals Press the button in the box
Loading BESS dispatch… First paint / after save or re-run Wait; a load failure flashes Could not load BESS dispatch.
No dispatch on this day. / No dispatch this day. Selected date has no intervals, or only idle hours that the moves list dropped Pick another day, or believe the hold
Headline the battery did nothing Intervals exist but no charge or discharge cleared the spread rule Read rejected pairs and the reserve rationale
Forecast fold present, this page all zeros T1 September — the battery is seated and the run stored intervals, but it did not sell the stored kWh Honest. The 2.3 MWh charge and the reserve hold are the whole story

Books without battery KPIs never render #book-battery. You can still type /strategy/bess; you will land on the configure-empty state if no asset is seated.

T1 on the demo

Two days, two truths.

What /strategy/bess opens (13 September 2026, latest Forecast). Rosslyn is a 5 MW / 20 MWh tank, 88 % round-trip, 10–100 % SoC, 1.5 cycles/day, 15 c/kWh wear, 20 c/kWh min spread, grid charging allowed, cycle-life table on. At 00:00 it charged 2,272.727 kWh from spill at 40.0 c/kWh. SoC ended the hour at 4.012 MWh and stayed there. Hours 17–20 are stored as idle with rationale contracted reserve held — the evening tap stayed closed so a contracted reserve could keep the floor. Day margin R 0. Cycles 0. The Forecast fold’s Battery R 0 tile is the same story in five numbers.

A day that did dispatch (29 October 2026, October P50 Forecast — open that run’s BESS tab). Overnight it poured 18.0 MWh of spill into the tank at 40 c (00h–03h, last hour clipped at the 18.8 MWh health-adjusted cap). Evening it sold 15.9 MWh to the market at 186 c (17h–20h). SoC walked 6.57 → 18.8 → 1.88 MWh. Wear rose with depth (11.0 → 35.4 c/kWh). Day margin about R 23,174. The October run totals about R 569,889 arbitrage, 0.836 cycles a day, 1.3 % of a huge spill book absorbed, 0 % firm hours backed — it sold evenings rather than covering Firm Pool shortfall.

Looks good: a charge block, a later discharge block, SoC that climbs then falls, day margin above zero, rejected pairs you can recite. Looks bad: a named BESS, a 96 % spill tile on Forecast, and this page’s facts still at R 0 — T1 September.

What to do next on T1 September

  1. Believe the page: the tank took 2.3 MWh and held it for reserve. It did not earn.
  2. Open the October run’s BESS tab if you need to see a charge→discharge day on this book.
  3. Do not raise min spread or re-run hoping September will suddenly absorb the 57 GWh spill — the battery is 20 MWh.
  4. When you want a buyer for the leftover solar, leave through Forecast · battery fold › and use Find offtake → Desk (§6.19).

Data. full_demo · seed 42 · stage S09 (settlement matrix) · last re-derived 2026-09-19 against the seeded T1 book (September P50 01a0b951-…; October P50 01a0ab61-… for a dispatching day).

Follow along. Seat: trader_1@webill.net (password supersecret). Path: T1 Renewables Pool → Book → Forecast → Open full dispatch ›. You should see Book lit, Forecast lit on the thread strip, and Sunday 13 September with a 2.3 MWh spill charge and R 0 day margin.

12. Dashboard — the story of the pool

Route: …/strategy/dashboard · Tab: Dashboard

What it is for. Overview (§4) is today. The Book (§5, §6) is how the pool is wired and what this month did. The Desk (§9) is where you act. The Dashboard is the long view and the coach: how the pool has performed since it began, where the money leaked, who it traded with, how healthy it has been month by month, what the next twelve months look like, and the moves that would change them most. It is the trader’s twin of the off-taker (V5 §7) and IPP dashboards — six chapters, each a verdict sentence, one visual and a So what.

Of the ten numbered panels this page used to be, two survive as folds — forecast quality by member under Chapter 4 and the sampled distribution under Chapter 5. The rest were removed in 3.9.1 because the chapters, the Book or the Bid Desk already tell what they told; their sections below are kept as stubs so older links still land.

The six chapters

The verdict and the dial. The header writes one sentence from the numbers (“The book made R 1.3 m over 6 months but kept only 57 % of what it could have; R 1.0 m leaked, most of it grid top-up above sale price”) and shows the pool’s single score: kept of what the book could have made. Achievable is realised margin plus the avoidable losses in Chapter 2; the dial is realised ÷ achievable. Chips grade the months — settled (every leg FINAL), preliminary (a draft or preliminary leg), engine (an ACTUAL run, no settlement), forecast (the current month) — and a flagged month (a ledger or seed artefact, such as sales many times larger than purchases) is dimmed and excluded from every total. Read an earlier snapshot keeps the old Period card for audit; Edit limits opens the limits editor (§12.6).

Chapter The question The visual Folded underneath
1 · Performance Did the book make what the plan said, and what it could have? Margin by month: settled bar, plan outline (that month’s FORECAST), achievable tick; the current month as a forecast band; one diary line per month —
2 · Where it leaked Every Rand the book could have kept and did not, with an owner The loss ledger: unsold energy below cost · market alternative not taken (the avoidable part, counted by the dial) · grid top-up above sale price · imbalance charges · nomination misses · take-or-pay not used · network carried (a cost, not a loss) · paired items that cancel (excluded). Rows stay visible at zero; each names its owner and links to the screen that fixes it —
3 · Who we traded with Which counterparties actually moved energy, and which are only wired The trading web: sources left, buyers right, the pool in the middle; solid lines are settled kWh, wide by volume; dashed lines are members that never settled a leg. Spill / SAWEM and the grid are counterparties too; a trader-to-trader leg is violet. A ranked table with cheapest, most reliable, ≥ 50 % of revenue, trader, modelled badges —
4 · Health over time Was each vital inside its limit, month by month, and what changed when a colour did The health strip: eight vitals (coverage, spill, shortfall, margin at risk, concentration, counterparty exposure, imbalance, nomination accuracy) × every month, coloured by the limit in force that month — your limit where one exists, a default threshold where none does — with an events row read from contract dates, limit effective dates, the snapshot’s structure digest changing and plan status forecast quality by member (the ⑧ league)
5 · Outlook Where is the book heading Twelve months at P50 with the P90 band, the first move dotted in; facts: margin at risk, VaR 95 / 99 at one day and one month, the position next month with its Option 0 the sampled distribution — margin quantiles p05–p95 with its absent / stale notice (§22)
6 · Next moves What would change the next twelve months most Up to three moves ranked by Rand a month — sell the unsold block, nominate (or drop) the trader-to-trader sale, add an evening shape, buy the short hours, tighten tolerance, run the back-cast — each opening the Desk, Nominations, the Book or the Bid Desk. Run the back-cast scores the last settled month in one click and lights the nomination rows —

Follow along. Seat: trader_1@webill.net (password supersecret). Path: Trader Pools → T1 Renewables Pool → Strategy → Dashboard. In full_demo the story runs February to September 2026: four engine months, two settled months (June, July: purchases from Sandton Solar and Midrand Hybrid, no sale settled), August flagged, September the forecast. The dial reads about 57 %; the web shows one supplier and no settled sale; the outlook says the year loses money at P50 because 95 % of supply has no buyer; move 1 is to sell the unsold block.

Data. The story reads settled legs with REVERSED re-runs dropped (the same rule as the Book’s check), the ACTUAL and FORECAST runs, the month-end snapshots, the hourly imbalance positions, the BRP panel, nomination plans, limits and memberships. When a month is back-cast, its nomination and forecast-quality scores now also land on that month’s ACTUAL snapshot, so the health strip can show them as a series.


The folded panels

Two folds remain — open one by clicking its dashed Folded · bar under the chapter. Forecast quality by member (Chapter 4) is the MAPE / bias league per member on the selected snapshot, worst contributor first. The sampled distribution (Chapter 5) is the margin fan — quantiles p05 to p95 from the stochastic sampler — with a stated absence when no distribution exists for the snapshot and a stale notice when it is from another date; the method is §22. The sections that follow describe the panels that were removed.

12.1 Top bar

Retired panel (3.9.1). This panel was removed from the Dashboard when the page became the story of the pool; what it showed now lives in the header — Read an earlier snapshot and Edit limits — see the six chapters. The heading and anchor are kept so older links still land here.

12.2 ① Portfolio Margin

Retired panel (3.9.1). This panel was removed from the Dashboard when the page became the story of the pool; what it showed now lives in Chapter 1 · Performance — see the six chapters. The heading and anchor are kept so older links still land here.

12.3 ② Risk

Retired panel (3.9.1). This panel was removed from the Dashboard when the page became the story of the pool; what it showed now lives in Chapter 5 · Outlook and Chapter 4 · Health over time — see the six chapters. The heading and anchor are kept so older links still land here.

12.4 ③ Coverage

Retired panel (3.9.1). This panel was removed from the Dashboard when the page became the story of the pool; what it showed now lives in Chapter 4 · Health over time (the coverage row) — see the six chapters. The heading and anchor are kept so older links still land here.

12.5 ④ Price

Retired panel (3.9.1). This panel was removed from the Dashboard when the page became the story of the pool; what it showed now lives in Chapter 1 · Performance (the landed and sale c/kWh on each month) — see the six chapters. The heading and anchor are kept so older links still land here.

12.6 ⑤ Operational Alerts + Edit limits

Retired panel (3.9.1). This panel was removed from the Dashboard when the page became the story of the pool; what it showed now lives in Chapter 4 · Health over time and the header’s Edit limits — see the six chapters. The heading and anchor are kept so older links still land here.

12.7 ⑥ BESS

Battery contract limits now include BESS_CYCLES_PER_YEAR (above), BESS_RTE_MEASURED_PCT (below) and BESS_AVAILABILITY_PCT (below). They are data-driven warn/breach limits evaluated after ACTUAL battery evidence arrives. The trader’s BESS page shows cycles against the owner’s cap and RTE; the owner sees all three on Battery contract. See V4 §20 for the window and evidence basis.

Where this is taught. The trader /strategy/bess page — contract chips, day view, calendar — is §11.11.

Retired panel (3.9.1). This panel was removed from the Dashboard when the page became the story of the pool; what it showed now lives in the chapters above — see the six chapters. The heading and anchor are kept so older links still land here.

12.8 ⑦ Nomination Performance

Retired panel (3.9.1). This panel was removed from the Dashboard when the page became the story of the pool; what it showed now lives in the chapters above — see the six chapters. The heading and anchor are kept so older links still land here.

12.9 ⑧ Forecast Quality

Route cue: Dashboard → panel ⑧ Forecast Quality.

This panel answers one question: "After the month settled, how wrong was the forecast — as a portfolio error rate, as a signed over-/under-estimate, and which members dragged the book?" Panel ⑦ scores nominations you submitted (§12.8). Panel ⑧ scores the engine's forecast energy shapes against the same meters. Same Actual gate; different question.

Everything here comes from the selected risk snapshot — and only when that snapshot's metrics already carry a non-empty FORECAST_ACCURACY_BY_MEMBER map (merged in by backcast after an Actual run). On Forecast — or before any member can be scored — the panel shows the awaiting-actuals copy.


In plain English — every concept on this panel

Read this once; the rest of the section assumes these words.

Word on / about the panel Plain meaning
Forecast (energy) What the engine expected each non-proxied member to generate or consume that hour, from the month's FORECAST run inputs
Actual (energy) What meters observed for that member that hour — the settled truth the backcast uses
Backcast Re-running allocate on settled volumes for the same delivery month (§6.2). Seals the Actual snapshot and merges forecast-quality metrics into it
MAPE Mean Absolute Percentage Error — average hour-by-hour |forecast − actual| ÷ actual, as a percent. "How far off, ignoring whether high or low"
Bias Signed error: (Σ forecast − Σ actual) ÷ Σ actual × 100. Positive = forecast was too high (over-estimated settled energy). Negative = forecast was too low
Portfolio MAPE / Bias Book-wide scores: MAPE is volume-weighted across eligible members; bias uses the summed forecast and actual totals
Member row One scored site / membership: its own MAPE, bias, and settled kWh
Settled kWh Sum of that member's observed meter energy over hours used in the score
Proxied member A membership whose energy is inferred, not metered — excluded from this scorecard (same provenance rule as nomination scoring)
Zero-actual hour An hour where the meter read 0. Dropped from MAPE (dividing by zero is meaningless); still counted in bias totals when present
Awaiting settled actuals Empty state when FORECAST_ACCURACY_BY_MEMBER is empty — usually Forecast period, or Actual backcast has not yet scored a matching FORECAST run

When this panel lights up — the Actual gate

Panel ⑧ is gated on settled reality plus a scored forecast. It does not invent quality on a forward plan.

On a Forecast period (or unscored Actual)

What you see. Grey note: "Awaiting settled actuals — member forecast quality appears after an ACTUAL backcast."

Why. There is no member breakdown yet. The Forecast run is live for panels ①–⑥; comparing it to meters waits for backcast to pair that month's COMPLETE FORECAST run with ACTUAL inputs and write FORECAST_MAPE_PCT / FORECAST_BIAS_PCT / FORECAST_ACCURACY_BY_MEMBER.

What to do. Keep using Forecast for morning triage. Flip Period to an existing … · Actual month (§12.1), or run backcast after meters land (§6.2).

On an Actual period (after backcast scored the forecast)

What you see. Two tiles — Portfolio MAPE, Bias — plus a member table sorted by impact (MAPE × settled kWh, worst first).

How they get there. Backcast finds the matching COMPLETE FORECAST run for the same delivery window, builds forecast vs actual hourly energy per non-proxied member, scores MAPE/bias, and merges the results into the Actual risk snapshot.

Neighbours. ⑦ Nomination Performance shares this Actual unlock. ⑨ Market does not — market figures can already be live on Forecast when BRP registration is ACTIVE (§12.10).

You want to… Period select Why
See whether June's forecast was noisy Jun 2026 · Actual MAPE / bias need settled hours vs the June Forecast run
Plan July before meters Jul 2026 · Forecast Panel ⑧ correctly says awaiting — use run detail / Simulations instead
Check "did backcast even score quality?" Actual month still awaiting No matching FORECAST run, no eligible members, or metrics not merged yet

Careful. Panel ⑧ is not nomination accuracy. A perfect nomination scorecard with an ugly MAPE means declarations were good but the engine's prior shape was wrong — different fix (error profiles / membership / forecast inputs), not only re-optimise nominations.


Anatomy — every visual element on panel ⑧

Piece on screen What you see What it means
Panel title ⑧ Forecast Quality Report card for forecast energy vs settled meters
Tile grid Two stat cards Live when the member map is non-empty
Portfolio MAPE Percentage, e.g. 9.3% Volume-weighted average member MAPE for the book
Bias Signed percentage, e.g. +4.1% or −12.5% Portfolio over-/under-estimate; leading + when ≥ 0
Member table Columns: Member · MAPE · Bias · Settled kWh League table of who contributed error
Footer note "Positive bias means the forecast over-estimated settled energy." Reminder of the sign convention
Empty state "Awaiting settled actuals …" No members in FORECAST_ACCURACY_BY_MEMBER on the selected snapshot

Sort order. Rows are ordered by MAPE × settled kWh descending — not alphabetically. A medium MAPE on a huge plant ranks above a terrible MAPE on a tiny site, because that is where the book's error mass lives.


The two portfolio tiles — what each shows and why it matters

Portfolio MAPE · FORECAST_MAPE_PCT

What it is. For each eligible member, hour MAPE is the mean of |F − A| ÷ A over hours with actual > 0. Portfolio MAPE is the settled-volume-weighted mean of those member MAPEs:

member MAPE %  =  mean over hours ( |F − A| ÷ A ) × 100   (skip A = 0)
portfolio MAPE %  =  Σ (member MAPE × member settled kWh)  ÷  Σ settled kWh

Rounded to one decimal on the tile.

Why it is here. One noise number for the book. High MAPE means the shapes you planned on were unreliable — nomination residual scenarios, MaR stories, and DAM positions all inherit that uncertainty (§10.2).

How to read it.

Reading Meaning Typical next look
Low single digits Forecast tracked meters well Still check bias sign and the member league
~10–20% Material noise Which members own the impact column; run Δ (§8.2)
≫ 20% Systematic shape failure Membership / resource assumptions; refresh forecast-error profiles after enough Actuals
Low MAPE, ugly ⑦ Forecast OK, nominations not Nominations workbench — not a modelling fire drill
Bias · FORECAST_BIAS_PCT

What it is. Signed portfolio error:

bias %  =  (Σ forecast − Σ actual)  ÷  Σ actual  × 100

Taken over the same members/hours used in the scorecard (forecast summed only on hours that have an actual observation). Displayed with an explicit + when non-negative.

Why it is here. MAPE is unsigned — 10% high and 10% low look the same. Bias tells you the direction: persistently positive means you planned as if more energy existed than meters delivered (optimistic supply / underestimated demand, depending on side); negative means the opposite.

How to read it (UI footer agrees).

Reading Meaning Typical next look
Near 0% with moderate MAPE Noisy but centred Hour-shape noise; member table for outliers
Sustained + (over-estimate) Forecast too high vs meters Spill / shortfall story on Actual run; do not grow sales on that optimism
Sustained − (under-estimate) Forecast too low vs meters Missed cover or under-declared resource; check whether MaR used a timid P50
Big |bias| with small MAPE Almost impossible long-run — usually one-sided hours dominate Member rows; which hours actually settled

The member table — every column

Column Field What it shows How to use it
Member label Display name of the scored membership (site / PPA label) Identify who — open that member on Pools / run detail
MAPE mape_pct That member's own mean absolute % error Noise for this site alone
Bias bias_pct That member's signed (F − A) ÷ A × 100 Direction for this site; same + / − convention
Settled kWh actual_kwh Sum of observed meter kWh in the score Weight — large settled kWh × MAPE = why this row sorted high

Who appears. Non-proxied members that have at least one eligible actual hour (actual > 0 for MAPE). Members with no meter overlap against the forecast are omitted — they do not pad the table with zeros.

Worked sort. MAPE 10% on 500 kWh (impact 5 000) ranks above MAPE 12% on 100 kWh (impact 1 200). The UI test fixture uses exactly that pattern: Tshwane Solar before Small Wind.


How forecast vs actual relate (schematic)

Think of one member-hour as two bars: what the forecast claimed vs what the meter showed. Absolute gap feeds MAPE; the sign of the gap feeds bias.

One forecast hour — over-estimate vs under-estimate vs near hit
IllustrativeActual = 100 · forecast miss
Over-estimate (+ bias)F 120 · A 100 · |err| 20%
Actual 100 +20 forecast air
Under-estimate (− bias)F 80 · A 100 · |err| 20%
Forecast 80 +20 missed
Near hitF 102 · A 100 · small MAPE crumb
Within noise · barely moves portfolio
Settled actual Forecast too high (+ bias) Forecast too low (− bias) Near hit

Notice. The same 20% absolute miss can be +bias or −bias. Portfolio MAPE treats them alike; the Bias tile and the Bias column do not.


Worked example — three solar hours, then a two-member book

Same arithmetic the engine uses (WB.Strategy.Accuracy). Numbers match the unit tests so you can re-check by hand.

One member — three hours (seeded solar check)
Hour Forecast (F) Actual (A) |F−A|÷A
h11 16.40 14.76 11.1%
h12 16.71 16.71 0.0%
h13 15.20 12.16 25.0%

MAPE = mean(11.1%, 0%, 25%) = 12.0%.

Bias = (16.40+16.71+15.20 − 14.76−16.71−12.16) ÷ (14.76+16.71+12.16) × 100 ≈ +10.7% (forecast over-estimated).

Two members — portfolio weights
Member Settled kWh Member MAPE Contribution
Small solar 100 10% 1 000
Large wind 300 20% 6 000

Portfolio MAPE = (1 000 + 6 000) ÷ 400 = 17.5%.

If Small forecast 110 vs 100 and Large forecast 240 vs 300: portfolio bias = (110+240 − 100−300) ÷ 400 × 100 = −12.5% (book under-estimated overall because the large wind miss dominates).

Same ideas — MAPE crumbs vs signed bias stack
Matched / small error Over-estimate (+) Under-estimate (−)

1 · Hour MAPE crumbs → 12%

Three absolute percentage errors averaged Bars for 11 percent, zero, and 25 percent absolute errors averaging to 12 percent MAPE. h11 11% h12 0% h13 25%

Look for: tall absolute misses, not the sign. Learn: mean of the three crumbs is 12%. Act: if live months stay here, open the member league before blaming nominations.

2 · Bias stack → +10.7%

Forecast total above actual total Two stacks showing forecast total taller than actual total for a positive bias. Σ F Σ A over-estimate · +10.7%

Look for: whether Σ F sits above or below Σ A. Learn: positive bias means the forecast over-stated settled energy. Act: do not add sales that need that "air" energy.

3 · League sort by impact

Large site ranks above small noisier site Two impact bars showing large wind ahead of small solar despite lower MAPE. Large · 10% × 500 Small · 12% × 100

Look for: top row = biggest MAPE × kWh product. Learn: fix the heavy plant first. Act: open that member's Actual vs Forecast Δ on run detail.

Zero-actual hours (edge case)

Hour with A = 0 is skipped for MAPE (no division by zero) but still participates in bias when you sum forecast and actual totals. A forecast of 100 against a true zero meter hour does not inflate MAPE; it does push bias positive if that hour is in the actual map as an explicit zero.


How to read Forecast Quality — a deliberate order

  1. Confirm the Period card shows … · Actual for the month you care about (§12.1). Awaiting on Forecast is expected.
  2. If awaiting on Actual, confirm a COMPLETE FORECAST run exists for that same delivery window and that backcast has run (§6.2).
  3. Read Portfolio MAPE — noise size for the book.
  4. Read Bias — direction. Remember: positive = over-estimated.
  5. Walk the member table top-down — first row is usually where to spend investigation time.
  6. Pair with ⑦ Nomination Performance — same meters, different decision (submitted nominations vs engine shapes).
  7. Pair with run-detail Δ (§8.2) when you need hour evidence, not only the league.
  8. Act forward — refresh error profiles / membership / next Forecast; you cannot rewrite last month's sealed snapshot by staring at the tiles.

What you can learn — and how to act

What the panel shows What it usually means What to do next
Awaiting on Forecast Gate working as designed Flip to Actual, or wait for backcast
Awaiting on Actual No scored members / no paired FORECAST run Run backcast; confirm Forecast COMPLETE for that month
Low MAPE, bias ≈ 0 Shapes held Protect the process; watch ⑦ separately
Low MAPE, bias persistently + Quietly optimistic Do not grow offtake on that optimism; check spill on Actual
Low MAPE, bias persistently − Quietly pessimistic Coverage / shortfall may have been worse in plan than in meters
High MAPE, one member on top Local resource / meter / seating fault Fix that membership first
High MAPE, many members Systemic forecast process Error profiles, weather/resource inputs, proxy exclusions
Ugly ⑧, quiet ⑦ Forecast wrong, nominations still hit Modelling fix; nominations may be compensating by luck
Quiet ⑧, ugly ⑦ Shapes OK, declarations not Nominations re-optimise / submit discipline (§12.8)
Rising MAPE month over month Residuals drifting Overview next-best-actions; stop treating P50 as certain

Why this panel exists (desired outcomes)

  1. Score the forecast itself, not only the nominations layered on top of it.
  2. Separate noise (MAPE) from direction (bias) so "wrong" has a verb.
  3. Name the members so triage starts at the top of the impact league, not in a spreadsheet hunt.
  4. Stay honest about the Actual gate — quality appears only after meters and backcast, like settlement.
  5. Feed the next loop — high MAPE refreshes residual / error-profile thinking for nominations and MaR; it does not rewrite history.

Follow along. Seat: trader_1@webill.net (password supersecret). Path: Trader Pools → T1 Renewables Pool → Strategy → Dashboard. Pick an … · Actual month. Panel ⑧ Forecast Quality should leave awaiting and show Portfolio MAPE, Bias, and the member table (worst impact first). Flip to Forecast and confirm the awaiting copy returns. Compare with ⑦ on the same Actual — they unlock together but answer different questions.

Capacity-normalised skill and diversification

Forecast Quality shows capacity-normalised MAE alongside the existing MAPE and bias. It reads weekly issued-forecast skill evidence; no scorecard means the necessary observations have not landed. The diversification tile compares the book’s generation error standard deviation with the capacity-weighted sum of its members’ standard deviations over their common observed hours.

For capacities 10,000 and 6,000 kW, member deviations 6% and 8% give a weighted 6.75%. A measured book deviation of 4.2% gives a factor 0.622. Perfectly correlated errors give 1.0. No observations or zero denominator are unavailable. The versioned six-month book profile supplies the sampler’s thin-cell fallback; its version and the fallback hours travel with the sampled path set. These metrics do not introduce a new bid gate.

12.10 ⑨ Market (BRP)

Retired panel (3.9.1). This panel was removed from the Dashboard when the page became the story of the pool; what it showed now lives in the chapters above — see the six chapters. The heading and anchor are kept so older links still land here.

Capture and the plan-to-actual bridge

The Market panel distinguishes acceptance from DAM capture. Cannibalisation measures how far generation hours fall below the average price; the limit warns above the configured threshold. Capture is a historical benchmark with source and date, rather than a forecast.

The Performance bridge follows seven steps: volume, average market price, generation shape, imbalance, contract terms, leaked energy, and unexplained items. A positive step helped the month; a negative step hurt it. The residual stays visible at zero.

The plan of record is the latest completed monthly forecast in force at SAST month start. A subsequently superseded run can still be that plan. If none existed, a later monthly forecast is labelled plan chosen after the month began · low confidence. Missing plan prices or settled delivery refuse a bridge. Where a bridge exists, the Performance plan bar uses the same plan cents.