# Scenario YAML Reference This document summarises the structure expected by the simulator when loading scenario configuration files. The authoritative machine-readable specification lives alongside the loader in [`simulator/io/scenario_schema.json`](../simulator/io/scenario_schema.json); editors and validation tooling can use that JSON Schema to lint scenario files before they reach the loader. For single-deal deterministic runs, see [`Deterministic Deal YAML`](./deterministic_deal_yaml.md). ## Top-Level Structure | Key | Type | Notes | | --- | --- | --- | | `version` | string/number (optional) | Free-form schema or configuration revision identifier. | | `metadata` | object (optional) | Carried through untouched; useful for provenance (owner, timestamps, etc.). | | `deals` | array (required) | At least one deal definition. Each entry must satisfy the **Deal Definition** section below. | | `simulation` | object (required) | Global simulation controls (scenario count, discounting, etc.). | ## Deal Definition Every deal entry captures static attributes, stochastic parameter specifications, and optional collateral/insurance/residual configuration. ### Required keys - `id`: unique string identifier. - `start_date`: ISO date (`YYYY-MM-DD`). - `parameters`: object describing stochastic inputs (principal, rate, term, etc.). ### Optional keys - `asset_type`: free-form descriptor (e.g. `gpu_compute_cluster`). - `currency`: ISO currency code. - `frequency`: payment interval (`M`, `Q`, or `A`). Defaults to monthly. - `collateral`: cash collateral configuration (upfront ratio, contribution rules, yield spec). - `insurance_policy`: insured value curve and premium assumptions. - `liquidation`: recovery schedule to overlay when defaults occur. - `revenue_offsets`: fee and rental models contributing to exposure reduction. - `operating_income`: operating cash-flow generator; supports `constant`, `probabilistic`, or `driver` modes. - `residual_model`: depreciation curve, multipliers, and optional obsolescence shocks. - `downpayment_percent`: deterministic borrower equity share (1 - initial LTV). Within `revenue_offsets`, supply continuous fee parameters via: - `origination_fee_pct`: upfront fee expressed as a fraction of principal (e.g. 0.02 for 2%). - `servicing_fee_pct`: annual servicing fee applied to the outstanding balance (decimal form). - `aum_fee_pct`: annual fee applied to collateral balances (decimal form). - Legacy keys (`*_percent`/`*_apr`) remain accepted but are deprecated. ### Parameters block Each parameter entry combines a distribution specification with optional truncation and quantisation directives. Distributions are described via `spec`, whose `mode` is one of: - `params`: direct call-through to SciPy (e.g. `{family: "lognorm", params: {...}}`). - `quantiles_fit`: recover distribution parameters from a list of quantile anchors. - `histogram`: discrete histogram defined by `bins` + `counts`. - `from_values`: empirical samples. When using `quantiles_fit`, provide a `quantiles` array under the spec: ```yaml rate: spec: mode: quantiles_fit family: beta params: lo: 0.02 hi: 0.25 quantiles: - { q: 0.1, x: 0.035 } - { q: 0.5, x: 0.085 } - { q: 0.9, x: 0.17 } truncation: lo: 0.025 hi: 0.22 rounding_step: 0.0005 ``` ### Collateral and insurance - `collateral.contribution` supports combinations of fixed amounts, payment percentages, age curves, and ratio-based schedules (mirrors `simulator.engine.collateral`). - `collateral.yield` accepts either a fixed rate (`{mode: fixed, rate: 0.02}`) or a distribution spec (`{mode: distribution, spec: {...}}`). - `insurance_policy.insured_value_curve` maps month → insured percentage. ### Residual model Define the baseline depreciation curve (`straight_line` today), optional macro/idiosyncratic multipliers, and a list of `obsolescence_shocks`. Each shock can carry probabilistic triggers, relative timing, and drop magnitudes/fractions. ## Simulation Settings | Key | Type | Notes | | --- | --- | --- | | `n_scenarios` | integer (required) | Number of Monte Carlo draws. | | `discount_rate` | number | Portfolio-wide base discount rate. | | `rng_seed` | integer/null | Seed for reproducible draws; omit for stochastic runs. | | `scenario_discount_rule` | object (optional) | Currently supports `type: piecewise_rate` with an ordered `rules` array. | | `deterministic_baseline` | object (optional) | Enables deterministic draw (`enabled: true`) with optional per-field overrides. | | `output_controls` | object (optional) | Path and inclusion toggles for persisted artefacts. | Example discount rule: ```yaml scenario_discount_rule: type: piecewise_rate rules: - max_rate: 0.08 discount_rate: 0.05 - max_rate: 0.12 discount_rate: 0.0575 - discount_rate: 0.065 `hazard_curve.extend_with_last` is an optional boolean that mirrors the loader's default of extending the final supplied monthly hazard rate across the remaining term when the input curve is shorter than the simulated horizon. ``` ## Validating Scenarios Run a JSON Schema validator (e.g. `jsonschema`, `ajv`, or your IDE integration) against `simulator/io/scenario_schema.json` before committing new scenarios. Example using `jsonschema`: ```bash jsonschema -i examples/server_finance_scenario.yaml simulator/io/scenario_schema.json ``` The loader raises descriptive errors for common issues (missing quantile lists, unknown truncation modes, etc.), but schema validation catches most structural mistakes earlier in the workflow.