Four-stage check of interest rate risk in the banking book. Map non-maturity deposit balances into a bucketed repricing gap schedule, sweep the prescribed parallel shock ladder over that schedule, run the basis-risk calculation at the ladder's binding rung, and close with a session receipt over the run's execution hashes.
{
"tool": "map_nmd_behavioral_repricing",
"arguments": {
"nmd_segments": [
{ "name": "checking_core", "balance": 1000000, "beta": 0.2, "allocation": { "on_1m": 0, "m1_y1": 0, "y1_y3": 0.1, "y3_y5": 0.2, "y5_y10": 0.3, "y10_plus": 0.4 } },
{ "name": "savings_core", "balance": 2000000, "beta": 0.35, "allocation": { "on_1m": 0, "m1_y1": 0.1, "y1_y3": 0.2, "y3_y5": 0.3, "y5_y10": 0.2, "y10_plus": 0.2 } }
]
}
}
{
"tool": "run_rate_shock_ladder",
"arguments": {
"repricing_gaps": { "on_1m": 0, "m1_y1": -70000, "y1_y3": -160000, "y3_y5": -250000, "y5_y10": -200000, "y10_plus": -220000 },
"nii_12m_gap": -70000
}
}
{
"tool": "calculate_basis_risk_nii_shock",
"arguments": {
"reference_shock_bps": -400,
"horizon_months": 12,
"material_threshold_pct": 0.10,
"index_exposures": [
{ "index_name": "prime", "asset_balance": 2000000, "liability_balance": 0, "beta_vs_reference": 1 },
{ "index_name": "sofr", "asset_balance": 500000, "liability_balance": 0, "beta_vs_reference": 0.85 },
{ "index_name": "fed_funds", "asset_balance": 0, "liability_balance": 1000000, "beta_vs_reference": 0.9 }
]
}
}
{
"tool": "aggregate_execution_receipts",
"arguments": {
"execution_hashes": [
"b9432dea758281c615c09814b521574a4b1aad32a140f707eed8945cfba13141",
"b3eca98a01a47b7d812f7a01082cc78479a31bd4ac34b6e5e825ba7bed7c1024",
"85d25ad15d566d406af1d5b653716aa805f46794f8fdebb78f9c8d0d76958fc7"
]
}
}
Run the four tools in order. The schedule for step 2 is the step 1 run's net_repricing_gap schedule, declared again with the same bucket keys. The reference shock for step 3 is the binding rung cited from the step 2 run.
// Step 1: map NMD balances into a bucketed repricing gap schedule
const step1 = await mcp.call("map_nmd_behavioral_repricing", {
nmd_segments: [
{ name: "checking_core", balance: 1000000, beta: 0.2, allocation: { on_1m: 0, m1_y1: 0, y1_y3: 0.1, y3_y5: 0.2, y5_y10: 0.3, y10_plus: 0.4 } },
{ name: "savings_core", balance: 2000000, beta: 0.35, allocation: { on_1m: 0, m1_y1: 0.1, y1_y3: 0.2, y3_y5: 0.3, y5_y10: 0.2, y10_plus: 0.2 } }
]
});
// Step 2: sweep the prescribed parallel shock ladder over that schedule
const step2 = await mcp.call("run_rate_shock_ladder", {
repricing_gaps: step1.net_repricing_gap,
nii_12m_gap: step1.net_repricing_gap.on_1m + step1.net_repricing_gap.m1_y1
});
// Step 3: run the basis-risk calculation at the binding rung cited from step 2
const bindingShock = step2.ladder[step2.worst_scenario].shock_bps;
const step3 = await mcp.call("calculate_basis_risk_nii_shock", {
reference_shock_bps: bindingShock,
horizon_months: 12,
material_threshold_pct: 0.10,
index_exposures: [
{ index_name: "prime", asset_balance: 2000000, liability_balance: 0, beta_vs_reference: 1 },
{ index_name: "sofr", asset_balance: 500000, liability_balance: 0, beta_vs_reference: 0.85 },
{ index_name: "fed_funds", asset_balance: 0, liability_balance: 1000000, beta_vs_reference: 0.9 }
]
});
// Step 4: aggregate the three execution hashes into a session receipt
const step4 = await mcp.call("aggregate_execution_receipts", {
execution_hashes: [step1.execution_hash, step2.execution_hash, step3.execution_hash]
});
// Terminal artifact
console.log("Binding rung:", step2.worst_scenario, "shock_bps:", bindingShock);
console.log("Basis-risk delta-NII:", step3.basis_risk_delta_nii);
console.log("Session receipt root:", step4.session_receipt_root);
Step 1 schedule (net repricing gaps): on_1m 0, m1_y1 -70000, y1_y3 -160000, y3_y5 -250000, y5_y10 -200000, y10_plus -220000; total net gap -900000. Step 2 on that schedule with nii_12m_gap -70000: worst_scenario parallel_down_400bp, worst delta-EVE -246200; delta-NII at parallel_up_200bp is -1400. Step 3 at reference_shock_bps -400: parallel delta-NII -60000, total NII contribution -61000, basis-risk delta-NII -1000, basis-risk share of parallel -0.02, below the 0.10 materiality threshold, so the run is not material. Step 4 aggregates the three stage hashes listed above into the session receipt root.
Scope: the step 2 ladder uses the node's prescribed fixed magnitudes (+100, +200, +300, +400 basis points and their negatives). Those magnitudes are not OSFI's recalibrated shock set. OSFI's final Guideline B-12 (2027) adopts the BCBS July 2024 recalibrated shocks, was published 10 September 2026, and takes effect 1 November 2026 for October 31 year ends and 1 January 2027 for December 31 year ends. A run that needs the recalibrated set is outside the scope of this chain's parallel ladder.
Out of scope: regulatory filing; capital adequacy determination; a decay curve for deposits, since allocations are caller-declared; indices beyond those declared in the step 3 run; real customer or account data. The worked example uses invented balances. Use synthetic or anonymised inputs only for every run.
| Chain slug | irrbb-nmd-shock-and-basis-risk-check |
| Nodes | art-442 → art-369 → art-443 → cry-05 |
| Cluster | Prudential & Basel Risk |
| Regulation | OCC 2010-1 · Comptroller's Handbook IRR |
| Spec version | 0.5.0 |
| §18 compute proof | Deferred: no GPU/WSL toolchain in this build session (§17 kernel-source identity stamped) |
| Terminal export | Session receipt (Merkle root over execution hashes) |
| Hash scheme | SHA-256 over JCS-canonical {policy_parameters, output_payload} |
Copy this paragraph into Claude, OpenClaw, or any MCP-aware agent to run this whole workflow on the server and check one field that answers a real question.
Question: Rates move. Which shock rung hurts our economic value most, and how large is the loss?
Run the AINumbers MCP tool `run_chain` with {"chain":"irrbb-nmd-shock-and-basis-risk-check"} and read `art-369-run-rate-shock-ladder.worst_scenario`.
Re-run with `inputs` for `art-369-run-rate-shock-ladder`, reusing the values that result echoed, with `nii_12m_gap` changed so the 12-month NII gap is larger. Compare the same field.
Verify: call `verify_execution_hash` (https://mcp.ainumbers.co/mcp) with `claimed_hash` set to `composite_execution_hash` and the full `composite_artifact`.
Ledger, for a human re-check: https://ledger.ainumbers.co/
PII rule: send synthetic or anonymised inputs only. The MCP server runs these kernels and logs no payloads.
Chain page: https://ainumbers.co/chaingraph/chains/irrbb-nmd-shock-and-basis-risk-check.html