Industry Intelligence Analytics Suite Cross-firm peer ranking, archetype-based stress testing, industry-level extrapolation, and PE-affiliation fee analysis.
Collapse of four insmodel.L3 engines per Q-06 reasoning (shared intended-use family: cross-firm analytics over FinView data). Outputs are internal-strategy-grade; not regulator-facing.
Inputs, processing, outputs
Methodology
M-210, the Industry Intelligence Analytics Suite, is a Tier-3 composite model. It does not compute a single number; it composes four lower-tier (L3) cross-firm intelligence engines into one analytics surface that answers "how does this firm sit relative to its peers, and what does the calibrated sample imply for the whole industry?" The four sub-engines and what each computes:
-
PeerRankingEngine (
insmodel.L3.peer_ranking,firmmodel/engines/peer_ranking_engine.py) — the capstone. Given a stress scenario (one of seven prescribed scenarios plus a composite2008_replay), it ranks the calibrated firm sample from most to least resilient by decomposing each firm's capital impact through four channels: product (weighted archetype stress over the firm's enabled product lines), counterparty (reinsurance-recoverable haircuts under rating downgrades), derivative (hedge P&L under rate/equity/credit shocks), and fee (asset- management fee revenue change under the scenario's implied asset return). It returns, per firm, acapital_impact_pct, the primary and secondary channels, and a full channel breakdown. Rank 1 is the least resilient (most negative impact). -
ArchetypeStressComparison (
insmodel.L3.archetype_stress,firmmodel/engines/archetype_stress.py) — runs six product archetypes (SpreadLiability, RILA, IndexedAnnuity, VAGuarantee, PRT, TraditionalLife) through seven prescribed scenarios, producing a 6×7 = 42-cell vulnerability heat map ofeconomic_value_change_pct. Each cell is a closed-form analytical sensitivity (duration × rate shock on bond holdings, buffer/cap logic for indexed products, guarantee-cost delta for VA, mortality/lapse/ expense/volatility overlays) rather than a full product-model run. It also ranks archetypes by average absolute change and emits heat-map-ready data. This is the engine that supplies PeerRankingEngine's product channel. -
IndustryExtrapolator (
insmodel.L3.industry_extrapolator,firmmodel/engines/industry_extrapolator.py) — bridges the calibrated ~15-firm sample to the full ~$9.3T US Life & Annuity industry. It computes asset-weighted coverage overall and per segment, extrapolates any sample aggregate to an industry estimate (industry_estimate = sample_value / coverage_pct), attaches confidence-interval half-widths that tighten with coverage (CI_width = base_width / sqrt(coverage)), and produces a coverage waterfall ordering firms by size with cumulative coverage. -
PEFeeAnalyzer (
insmodel.L3.pe_fee_analyzer,firmmodel/engines/pe_fee_analyzer.py) — maps the PE/AM management-fee economy across the sample: external managers (Apollo, Blackstone, KKR, BlackRock), internal AM subsidiaries (PGIM, AB, MIM, PGI, NYL Investors, etc.), and parent relationships. It computes total fee economy, blended/ external/internal fee rates in bps, fee-to-AUM ratios, and a linear fee stress under an asset-return scenario (AUM and fees scale by1 + asset_return_pct/100). It supplies PeerRankingEngine's fee channel. -
ComparativeAnalytics (
goldcopy.L7.comparative_analytics,validation/comparative_analytics.pyin thegold_copyrepo) — the asset-side cross-firm analytics surface, back-populated into M-210 on 2026-05-02 (Bucket C). Unlike the four InsModel L3 engines above, this one lives in Gold Copy and works off pre-computed independent pricing results. It is constructed from afirm_results_dictand, withfiling_tolerances, produces acomparative_report: per-firm product mix (classifying each firm's product models into spread / equity_linked / longevity / protection buckets), derivative intensity (derivatives notional / total assets), NII yield spreads between firms, a cross-firm summary that places these metrics side by side, and anomaly detection via product-mix divergence across firms against configured tolerance bands. It is the comparative surface built from Gold Copy's independent pricing rather than from the InsModel firm-calibration path.
Representative engine in detail: IndustryExtrapolator
The cleanest deterministic surface — and the one snapshotted below — is the
IndustryExtrapolator, because it is dependency-injectable with a synthetic
firm sample and its arithmetic is fully self-contained. Its construction
accepts a firm_profiles dict (defaulting to the repo's calibrated
FIRM_PROFILES) and an optional industry_store; when a store is present it
reads life_insurer_total_assets (FRED, reported in millions, converted to
billions) to override the $9,300B industry constant. The core operations:
_sample_total_assets()sumsdisclosed_figures.total_assets_Bacross the sample._overall_coverage_pct()= sample assets / industry assets.extrapolate_to_industry(metric, value)divides a sample aggregate by coverage to gross it up to the industry, returning the coverage used and the estimate.confidence_intervals(base_width=0.10)widens the interval as coverage falls — a 100%-coverage sample would carry the base half-width; a low- coverage segment carries a proportionally wider band.coverage_waterfall()orders firms descending by assets and accumulates coverage, showing how few large firms drive most of the captured industry.
Key Assumptions and Their Justification
| ID | Assumption | Value / form | Justification |
|---|---|---|---|
| A-210a | Industry total assets (US L&A) | $9,300B constant (FRED-overridable) | Sized to the disclosed US Life & Annuity general-account universe; injectable from a FRED life_insurer_total_assets series so the denominator can track the published aggregate. |
| A-210b | Extrapolation is linear in coverage | industry = sample / coverage |
Treats the calibrated sample as asset-representative of the industry; the simplest defensible gross-up when no segment-mix weighting is supplied. |
| A-210c | CI half-width scales as 1/sqrt(coverage) |
base_width=0.10 at full coverage |
Sample-size intuition: precision improves with the square root of captured exposure. The base width is a documented input, not estimated from data. |
| A-210d | Archetype stress is closed-form, not model-driven | analytical sensitivities | Duration/buffer/cap/delta approximations let the 42-cell grid run instantly and deterministically; acceptable for a comparative heat map, not for a reserve number. |
| A-210e | Counterparty haircut ≈ 1 notch per 100bps spread | DOWNGRADE_HAIRCUTS table |
When a scenario lacks an explicit downgrade, credit-spread widening is mapped to notches (clamped 1–6); collateralised exposures take half the haircut. |
| A-210f | Fees scale linearly with AUM | fee × (1 + asset_return/100) |
First-order pass-through of asset returns to ad-valorem fees; ignores fee floors, performance fees, and re-pricing lags (see Limitations). |
| A-210g | Derivative book is net hedging | rate-receiver / equity-put proxies, capped ±5% of assets | Most insurance derivative notional hedges rate and equity tail risk; the cap prevents the hedge channel from dominating an otherwise loss-making scenario. |
Prose. The load-bearing assumption is A-210b — that the calibrated sample is asset-representative of the industry, so a simple coverage divide grosses sample aggregates up correctly. This holds best for metrics that themselves scale with assets (reserves, AUM) and worst for metrics concentrated in firms the sample under- or over-weights. A-210d is what makes the whole suite fast and reproducible: the archetype grid is analytical, so peer ranking is a weighting exercise over a precomputed grid rather than a fleet of product-model runs — at the cost of approximation error that is fine for ordering firms but not for sizing any one firm's loss.
Output Snapshot
Deterministic run of the representative sub-engine IndustryExtrapolator
(insmodel.L3.industry_extrapolator), dependency-injected with a synthetic
three-firm sample so the output depends on no live firm data (immune to the
BV-032 firm-data divergence), plus a pure-synthetic ArchetypeStressComparison
cross-check. Reproduce with python scripts/model_snapshots.py M-210 in
InsModel; the underlying engines are asserted by
tests/test_industry_extrapolator.py, tests/test_peer_ranking_engine.py,
tests/test_archetype_stress.py, and tests/test_pe_fee_analyzer.py.
Inputs: synthetic sample SYN1 $400B + SYN2 $250B + SYN3 $150B = $800B
against the $9,300B industry constant; sample aggregate metric
(aggregate_reserves_B) = $500B. Archetype cells under the prescribed
equity_crash_40 scenario.
| output | value | meaning |
|---|---|---|
| sample_assets_B | 800.00 | sum of the synthetic sample's disclosed assets |
| industry_assets_B | 9,300.00 | industry denominator (FRED-overridable constant) |
| coverage_pct | 0.0860 | sample / industry — the gross-up divisor |
| sample_metric_B | 500.00 | the synthetic sample aggregate to extrapolate |
| industry_estimate_B | 5,812.50 | 500 / 0.086 — sample grossed up to the industry |
| waterfall_top (SYN1) cum_cov | 0.0430 | largest firm alone covers 4.3% of the industry |
| waterfall_full cum_coverage_pct | 0.0860 | all three synthetic firms reach 8.6% |
| archetype VAGuarantee · equity_crash_40 | -46.55 | VA with guarantees loses ~46.6% of economic value in a 40% equity crash |
| archetype SpreadLiability · equity_crash_40 | 0.00 | a fixed-spread book (no equity allocation) is unaffected by the equity shock |
The two archetype cells show the comparative logic the suite exists to surface:
under a 40% equity crash the VAGuarantee archetype loses ~46.6% of economic
value (separate-account drop plus guarantee-cost delta) while a pure
SpreadLiability book is flat — the equity shock touches no equity allocation.
The extrapolation row shows the coverage mechanic: a low-coverage (8.6%)
synthetic sample grosses a $500B aggregate up to a ~$5.8T industry estimate,
which is exactly why the confidence-interval band widens as coverage falls.
For reference, the engine's default calibrated sample reaches ~52.07%
coverage ($4,842.3B of $9,300B across 15 firms), per
test_overall_coverage_approximately_52_pct.
Captured 2026-06-04 · deterministic, no live data.
Limitations and Known Gaps
-
Live firm-data path is divergent (BV-032). The PeerRankingEngine and the default IndustryExtrapolator/PEFeeAnalyzer read the in-repo
FIRM_PROFILESand hand-curated fee tables, which are disclosed/calibration figures baked into the codebase — not a live, validated firm-data feed. The snapshot above deliberately injects a synthetic sample to stay clear of BV-032; any industry estimate built on the real calibrated sample inherits whatever staleness those disclosed figures carry. -
Extrapolation is a flat coverage divide.
industry = sample / coverageassumes the sample is asset-representative. There is no segment-mix reweighting, no firm-level inclusion-probability model, and no correction for the sample skewing toward large public filers. Industry estimates for metrics that do not scale cleanly with assets (e.g., a niche product line) can be materially biased. -
Confidence intervals are heuristic, not statistical. The
1/sqrt(coverage)half-width is a documented assumption (A-210c), not a sampling distribution. It conveys relative precision across segments but should not be read as a calibrated frequentist or Bayesian interval. -
Segment coverage needs the real segment map.
compute_coverage_by_segmentandconfidence_intervalsdepend onSEGMENT_PEERSfromcompany_configs; when the extrapolator is injected with a synthetic sample and an empty config (as in the snapshot), the per-segment outputs are empty and only the overall/waterfall/extrapolation surfaces are exercised. Segment-level intelligence is therefore only as good as the curated segment membership. -
Archetype stress is analytical, not a product-model run. The 42-cell grid uses closed-form duration/buffer/cap/delta approximations (A-210d). It is built for comparing archetypes and driving the peer-rank product channel — it is not a reserve or capital number and should never be cited as one.
-
Channel models are first-order and partly heuristic. The derivative channel assumes a fixed 60/30/10 rate/equity/credit notional split and caps benefit at ±5% of assets (A-210g); the fee channel assumes pure linear AUM pass-through (A-210f); the counterparty channel infers downgrade notches from credit spread when none is given (A-210e). These are deliberately simple and will mis-state any firm whose actual hedging, fee, or reinsurance structure departs from the proxies.
-
2008_replayreuses archetype internals. The composite 2008 scenario callsArchetypeStressComparison._compute_economic_impactdirectly with a bespoke shock set rather than reading a precomputed grid cell, so its product-channel numbers are produced by a slightly different path than the seven prescribed scenarios — a coupling worth noting for maintenance.
Validation Packet
| Check | Where | What it asserts |
|---|---|---|
| Coverage ≈ 52% on calibrated sample | tests/test_industry_extrapolator.py::test_overall_coverage_approximately_52_pct |
15-firm sample covers 50–54% of the $9.3T industry |
| Sample assets ≈ $4,842.3B | …::test_overall_sample_assets_approximately_4842B |
Sum of disclosed assets matches the documented total |
| Extrapolation identity | …::test_extrapolation_basic_math, …::test_extrapolation_coverage_matches_overall |
industry = sample / coverage; coverage matches overall |
| CI tightens with coverage | …::test_ci_tighter_for_higher_coverage, …::test_ci_formula_correct |
Higher-coverage segments get smaller half-widths; formula exact |
| Waterfall ordering & monotonicity | …::test_waterfall_ordered_by_size_descending, …::test_waterfall_cumulative_is_monotonic |
Firms descend by size; cumulative coverage is non-decreasing |
| Peer ranking structure | tests/test_peer_ranking_engine.py::TestRankingStructure |
15 entries, ranks 1–15, sorted most-negative-first, 4 channels present |
| Channel validity | …::TestChannelIdentification |
Primary/secondary channels valid and distinct |
| 2008 economic intuition | …::Test2008ReplayIntuition |
VA-heavy firms (JXN, BHF) land bottom-5; spread-only firms do not; JXN worse than APO |
| Archetype grid | tests/test_archetype_stress.py |
6×7 grid, vulnerability ranking, heat-map data shape |
| Fee economy | tests/test_pe_fee_analyzer.py |
Fee totals, bps rates, fee-to-AUM ratios, linear stress |
| Governance metadata | each test module's test_model_governance* |
Sub-engine model IDs (M-911/M-912/M-913/M-914), category per engine, ≥3 references |
Governance IDs. The sub-engines carry their own SR-11-7 legacy metadata:
PEFeeAnalyzer = M-911 (category AssetManagement),
ArchetypeStressComparison = M-912, IndustryExtrapolator = M-913,
PeerRankingEngine = M-914 — loaded from
firmmodel/governance/legacy_metadata/<ClassName>.yaml via
load_legacy_metadata. M-210 is the Tier-3 composite card over these.
References
Engine source:
- ecosystem/InsModel/Models/firmmodel/engines/peer_ranking_engine.py — PeerRankingEngine (insmodel.L3.peer_ranking, M-914).
- ecosystem/InsModel/Models/firmmodel/engines/archetype_stress.py — ArchetypeStressComparison (insmodel.L3.archetype_stress, M-912).
- ecosystem/InsModel/Models/firmmodel/engines/industry_extrapolator.py — IndustryExtrapolator (insmodel.L3.industry_extrapolator, M-913).
- ecosystem/InsModel/Models/firmmodel/engines/pe_fee_analyzer.py — PEFeeAnalyzer (insmodel.L3.pe_fee_analyzer, M-911, category AssetManagement).
- ecosystem/gold_copy/validation/comparative_analytics.py — ComparativeAnalytics (goldcopy.L7.comparative_analytics; asset-side cross-firm analytics, back-populated 2026-05-02 Bucket C).
- ecosystem/InsModel/Models/firmmodel/engines/stress_testing_engine.py — PRESCRIBED_SCENARIOS (the seven prescribed scenarios).
- ecosystem/InsModel/Models/firmmodel/config/firm_calibration_profiles.py — FIRM_PROFILES (calibrated sample, disclosed figures).
- ecosystem/InsModel/Models/firmmodel/config/company_configs.py — COMPANY_CONFIGS, SEGMENT_PEERS (segment membership).
Tests:
- ecosystem/InsModel/Models/tests/test_industry_extrapolator.py
- ecosystem/InsModel/Models/tests/test_peer_ranking_engine.py
- ecosystem/InsModel/Models/tests/test_archetype_stress.py
- ecosystem/InsModel/Models/tests/test_pe_fee_analyzer.py
Snapshot:
- ecosystem/InsModel/Models/scripts/model_snapshots.py (snap_M_210 / python scripts/model_snapshots.py M-210).
Change Log
Card change history. Code-side change history lives in git log of the component files.
- 2026-05-08 — stub created from registry data per Decision 023 Phase 5 / B-07.
- 2026-06-06 — code-grounded documentation completeness pass. Added Standards Coverage section (ASOP 56 + internal only; no statutory/GAAP/Solvency II binding — strategy-grade Tier-3 model, grounded in registry
regulatory_frameworks: [asop_56, internal]+ materiality). Added Dependencies section (no upstream models per registry; consumes disclosed FIRM_PROFILES / fee tables / company_configs as data inputs DS-008/DS-021 and an optional FRED industry-assets series). Added the 5th sub-engine ComparativeAnalytics (goldcopy.L7.comparative_analytics, gold_copyvalidation/comparative_analytics.py, M-210 member per engine_registry; asset-side cross-firm analytics back-populated 2026-05-02) to Methodology. Added PEFeeAnalyzer = M-911 (category AssetManagement) to the Governance-IDs roster (now M-911/M-912/M-913/M-914), grounded inlegacy_metadata/PEFeeAnalyzer.yaml; reconciled the Validation-Packet governance-metadata row and References accordingly. No model outputs, validation results, or back-test numbers were fabricated or changed; no output-changing / modeling-code items were applied.
Open findings (1)
Independent 2nd-line review (INV-2026-06) — implemented capability vs registered scope. Each carries a recommended fix and is tracked in insightalm-mrm until closed.
Validation evidence + change logs missing across most of the inventory
Only M-001/M-020/M-050 carried full documentation packs before this pass. Most models record validation_evidence: missing and change_log: missing with peer_review: pending. Gold tests freeze behaviour but many assert only structural invariants (e.g. reserve>0), not correctness against external truth. The flagship T0-vs-10-K match is circular (BV-032).
Recommendation: For each Tier-1 model: produce a validation-evidence pack (back-test vs disclosed results once BV-032 re-calibration lands, sensitivity suite, challenger comparison), a change log, and a 2L ratification. Sequence behind BV-032 (firm-data) for anything needing 10-K reconciliation.
Ratified — RAT-210-v1.0.0
Latest ratification on file: RAT-210-v1.0.0. Authored by 2L (mrm-peer-reviewer) per Decision 028 charter §5 Pattern A.