Tier 3 · Internal Strategy

Industry Intelligence Analytics Suite

M-210 · lifecycle: monitoring · RAT-210-v1.0.0

Intended Use

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.


Components

Inputs, processing, outputs

data sources
DS-008 · DS-021
assumptions
A-100, A-101
engines
insmodel.L3.peer_ranking
insmodel.L3.archetype_stress
insmodel.L3.industry_extrapolator
insmodel.L3.pe_fee_analyzer
goldcopy.L7.comparative_analytics
contracts
intelligence_results_v1
dimensions
D9 · D10

Methodology & Mechanics

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:

  1. PeerRankingEngine (insmodel.L3.peer_ranking, firmmodel/engines/peer_ranking_engine.py) — the capstone. Given a stress scenario (one of seven prescribed scenarios plus a composite 2008_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, a capital_impact_pct, the primary and secondary channels, and a full channel breakdown. Rank 1 is the least resilient (most negative impact).

  2. 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 of economic_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.

  3. 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.

  4. 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 by 1 + asset_return_pct/100). It supplies PeerRankingEngine's fee channel.

  5. ComparativeAnalytics (goldcopy.L7.comparative_analytics, validation/comparative_analytics.py in the gold_copy repo) — 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 a firm_results_dict and, with filing_tolerances, produces a comparative_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() sums disclosed_figures.total_assets_B across 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

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

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

Limitations and Known Gaps

  1. Live firm-data path is divergent (BV-032). The PeerRankingEngine and the default IndustryExtrapolator/PEFeeAnalyzer read the in-repo FIRM_PROFILES and 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.

  2. Extrapolation is a flat coverage divide. industry = sample / coverage assumes 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.

  3. 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.

  4. Segment coverage needs the real segment map. compute_coverage_by_segment and confidence_intervals depend on SEGMENT_PEERS from company_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.

  5. 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.

  6. 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.

  7. 2008_replay reuses archetype internals. The composite 2008 scenario calls ArchetypeStressComparison._compute_economic_impact directly 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 Evidence

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

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.pyPRESCRIBED_SCENARIOS (the seven prescribed scenarios). - ecosystem/InsModel/Models/firmmodel/config/firm_calibration_profiles.pyFIRM_PROFILES (calibrated sample, disclosed figures). - ecosystem/InsModel/Models/firmmodel/config/company_configs.pyCOMPANY_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

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_copy validation/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 in legacy_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.

2L Inventory Review

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.

HIGH INV-029 · P5 · validation-gap

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.


Ratification

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.