First-Look Exhibits — Spec & Tracker
The descriptive first pass over the assembled base table: a fixed battery of exhibits, each the
minimal evidence for one clause of the management message — no modelling, only data in hand. Every
exhibit follows the same shape (question · data · chart · grain · caveat · report home), so a built
exhibit slots straight into a named report section rather than becoming orphan EDA. The runnable code
is split into the First-Look Transform (builds the base
table) and the First-Look Script (renders the exhibits).
Concept-only: figures are computed in the corporate environment; this spec carries structure, not
data. The eligible-AUM base, frontier, headroom, and money-weighting definitions live in the
driver-analysis plan (kept internally).
Why "work backwards": a first look without a destination is the open-ended EDA that recurses
until people lose interest. Every exhibit below earns its place against the message; anything that
doesn't map to a clause is cut, not parked.
The destination (what these are evidence toward)
We collect custody fees well below what the book could bear; the shortfall is concentrated, and a
large part of it looks like "never asked" rather than client resistance; here is where it
concentrates; and here is where a collection-growth target sits in pure arithmetic.
Preconditions
The battery runs on the joined analysis base table (the transformation step). The base table is
anchored on the account master (the near-complete account universe), with the charging outcome
left-joined; accounts absent from the charging file are the full-waiver pool (a full custody-fee
waiver), kept and flagged rather than dropped. Before any exhibit is trustworthy: explode the
account→MG mapping · GST-strip · FX-normalise · reconcile MG↔account. The first exhibit (E0)
is the verdict on whether that assembly worked.
Eligible-AUM note: custody_eligible_aum is the authoritative backend eligible base at
account grain (provided by the data team — not re-derived). Sum it up to MG for an MG-grain
eligible AUM. It is the realized-rate denominator throughout, and having it at both grains is what
lets E8 identify the within-MG gap directly and supports the MG-level cuts. Completeness: the
backend figure is populated only for accounts in the charging file (the non-full-waiver set); the
full-waiver pool carries no eligible-AUM value until a data request fills it — so eligible-AUM cuts
describe the charged universe, and the full-waiver gap is countable but not yet sizable in money.
E0 · Coverage & completeness panel (the gate)
| |
|---|
| Question | Can we trust the joins — and how large is the full-waiver gap? The account universe is the account master (near-complete); what share sit in the charging file vs are absent (the full-waiver pool)? Coverage of MG / domicile / management-type? GST & FX resolved? |
| Data | Account-master universe ← charging outcome ← account→MG backfill, post-join (have). |
| Chart | Coverage bars (MG / domicile / mgmt-type / in-charging-file / has-eligible-AUM) + the full-waiver pool count called out. |
| Grain | Both — reported per client and per MG. |
| Caveat | Not a throwaway — the gate. If coverage is poor, every downstream exhibit is degraded and gets labelled as such. Run first. The headline is the full-waiver share — those accounts are visible in the universe but carry no eligible-AUM until a data request fills it. |
| Report home | R7 (data-gap appendix); underwrites all. |
| Status | PENDING |
Headline landscape — R1 / R2
E1 · Realization waterfall
| |
|---|
| Question | Of the theoretical custody charge, how much is waived, how much discounted, how much actually collected? |
| Data | custody_fee_computed (theoretical), custody_fee_charged (actual); waived = computed − charged (have). |
| Chart | Waterfall: theoretical → −waived → −discount → actual. |
| Grain | Book-level (sum); optionally split by site. |
| Caveat | GST-strip first or the bars are inflated unevenly across sites. The full-waiver pool sits outside this waterfall (no theoretical charge recorded for it) until the eligible-AUM data request lands — so the waterfall covers the charged (non-full-waiver) universe only. |
| Report home | R1. |
| Status | PENDING |
E2 · Realized-bps distribution
| |
|---|
| Question | What rate do accounts actually realise? Where is the mass, how big is the zero-fee spike, and what is the empirical practical maximum (vs the mythical 25 bps)? |
| Data | custody_fee_charged ÷ custody_eligible_aum, per account (have — the denominator is the authoritative backend eligible AUM, not derived). |
| Chart | Histogram / ECDF; mark the 25 bps mythical line and the empirical practical max. |
| Grain | Account natively; roll custody_eligible_aum up to MG for an MG-grain variant. |
| Caveat | No base to choose — the denominator is the authoritative custody_eligible_aum. |
| Report home | R1 / R2. |
| Status | PENDING |
E3 · Fee-code → discount ladder
| |
|---|
| Question | What discount level does each custody-fee code actually encode? |
| Data | cdt_code × realized rate (have). |
| Chart | Box/strip of realized bps by code, sorted; the full-waiver code anchors zero. |
| Grain | Account. |
| Caveat | Recovers the level, not the reason (the reason needs the fee-code dictionary). |
| Report home | R2. |
| Status | PENDING |
E4 · Charged-at-all
| |
|---|
| Question | What share is fully-waived vs partial vs charged — by count, and by AUM? The never-asked share. |
| Data | Charged flag, eligible AUM (have). |
| Chart | Two stacked bars — count-weighted and AUM-weighted, side by side. |
| Grain | Account (rolled to book); MG view optional. |
| Caveat | The count view and the money view differ — show both; the message is the money one. Provisional: the biggest fully-waived block — the full-waiver pool — is now in the universe but its eligible-AUM is blank pending a data request, so the AUM-weighted never-asked share is understated until that lands; show the count now and flag the money view as pending. This is the W3–W4 early read / first socializable exhibit. |
| Report home | R1 (descriptive); the headline margin R3 later adjusts. |
| Status | PENDING |
E5 · Frontier curve
| |
|---|
| Question | What do the best-charged comparable relationships actually realise, by size × segment band — the practical ceiling? |
| Data | realized_bps among charged, non-waived; size band; segment (have). |
| Chart | Frontier (e.g. top-quartile realized rate) by size × segment band; expect it to fall with size. |
| Grain | MG (band percentile). |
| Caveat | Descriptive percentile, not a forecast or target; it replaces 25 bps as the benchmark everywhere. The fair rate for a given MG is further conditioned on its total return-on-AUM (see E10) — low-return clients sit at the top of the frontier. |
| Report home | R2. |
| Status | PENDING |
Where variation lives — R3 / R4 (raw, hypothesis-generating)
E7 · Realized-rate & charged-share small-multiples
| |
|---|
| Question | Where does fee realization visually concentrate across the candidate dimensions? |
| Data | Realized rate + charged share by segment · site · management type · domicile (on/offshore) · wallet-share band · AUM-size band (have). |
| Chart | Bar small-multiples or a heatmap, one panel per dimension. |
| Grain | Decide and state per panel — aggregate account charges up to MG, or attribute MG traits down to accounts; be consistent. |
| Caveat | RAW / UNADJUSTED — nominates drivers, does not confirm them. Dimensions are mutually confounded (size ⟂ segment ⟂ offshore). No DIRECT/INDIRECT labels here; that's R3's adjusted job. Treat as a shortlist. The cross-site split is provisional — distorted while full-waiver accounts carry no eligible-AUM; revisit once the data request lands. Tax-haven domiciles (e.g. BVI / Cayman) are not real residence (the ultimate beneficial owner's domicile is not captured) → exclude or separately flag them in the on/offshore panel, don't read them as genuine offshore. |
| Report home | R3 / R4 (as the raw half of the raw-vs-adjusted exhibits). |
| Status | PENDING |
Within-relationship & money concentration — R5 / R6
E8 · Within-MG mixed fee status
| |
|---|
| Question | Of multi-account MGs, how many hold both charged and fully-waived accounts? How much eligible AUM sits in zero-fee accounts? |
| Data | account→MG mapping + per-account custody_eligible_aum + per-account charge (have); per-account category AUM (a remaining data gap). |
| Chart | Distribution of within-MG fee-status mix + a headline gap-$ figure. |
| Grain | MG (over its accounts). |
| Caveat | Mostly unblocked. The headline gap — eligible AUM in zero-fee accounts = Σ custody_eligible_aum where the account is uncharged — is directly computable (account-level eligible AUM + charged flag), resolving the gap-identification confound cleanly. Only the benign-vs-gap split by account purpose still wants per-account category AUM. At MG level the split also has a criterion — total return-on-AUM (E10): a low-custody MG with healthy total return is cross-subsidised (benign), not a gap. |
| Report home | R5 (the gap-AUM quotable). |
| Status | PARTIAL — headline gap-$ computable now; benign/gap-by-purpose split awaits per-account category AUM. |
E9 · Waived-pool Pareto
| |
|---|
| Question | How concentrated is the waived / uncharged pool across MGs? (And collected custody?) |
| Data | Waived + charged $ by MG (have). |
| Chart | Lorenz / Pareto curve. |
| Grain | MG. |
| Caveat | Sets up money-weighting; a concentration read, not a targeting list (boundary: stakeholder owns action). |
| Report home | R6 (money-weighted ranking) / R5. |
| Status | PENDING |
E10 · Return-on-AUM × custody-rate quadrant (the pricing-landscape hook)
| |
|---|
| Question | Where does each relationship sit on total return-on-AUM (revenue ÷ AUM) vs custody realized_bps? Which low-custody MGs are cross-subsidised (high total return → benign) vs underpriced (low total return → the real gap)? |
| Data | return_on_aum = total MG revenue (revenue_2025) ÷ MG AUM (aum_2025) (have) · realized_bps = charged ÷ custody_eligible_aum rolled to MG (have). For the cross-subsidy read, also compute ex-custody revenue ÷ AUM (custody sits inside other fees). |
| Chart | Scatter — return-on-AUM (x) vs custody realized_bps (y), one dot per MG, sized by eligible AUM, quadrant lines at the medians. Bottom-left = low return + low custody = the underpriced pool. |
| Grain | MG. |
| Caveat | Descriptive landscape only — a hook, not an explanation. It locates the underpriced pool using the bank's pricing logic (low return-on-AUM ⇒ no break justified); it does not explain why any given MG deviates — drivers / exceptions are deliberately future-week work. Encodes the benign-vs-gap criterion for E8 (cross-subsidy = benign). |
| Report home | R2 / R6 (the fairness frame; the get-them-interested opener). |
| Status | PENDING |
Discipline rules
- Raw ≠ adjusted. E7 nominates; it never concludes. No evidence labels on raw cuts until R3 adjusts them.
- Money-weight everything. Always show count and AUM/$ views — they tell different stories, and the message is a money story.
- GST-strip + FX-normalise first, or cross-site and any pooled-$ figure is biased before you start.
- Mind the grain (account-grain outcome, MG-grain attributes). State per exhibit whether you aggregate up or attribute down; be consistent.
- Gate on E0. Degraded coverage degrades the exhibit's label — don't socialise an exhibit E0 says you can't trust.
Definition of done (termination)
A fixed ~10-exhibit battery, one pass. Done = each renders, reconciles to E0's coverage, and lands
in its named report section (R-home column). This is not a licence to keep slicing — a new cut
enters only if a battery exhibit raises a specific, message-relevant question worth exactly one more
chart, logged as a decision, not an open thread.
Sequencing & tracker
| Order | Exhibits | Gating |
|---|
| 1 | E0 | base table assembled (explode / GST / FX) |
| 2 | E1 · E2 · E3 · E4 · E5 | charging file + MG attributes (all in hand); E4 (never-asked share) is the W3–W4 read out the door |
| 3 | E7 | joined dimensions (domicile / trust / mgmt-type landed) |
| 4 | E8 · E9 · E10 | account→MG mapping + MG revenue join; E8 headline computable now, by-purpose split awaits per-account category AUM |
Status legend: PENDING · BLOCKED (name the blocker) · BUILT (rendered + reconciled to E0) · SOCIALISED (shown to stakeholder).