Skill: tangweigang-jpg/ifrs9-loss-engine (version 0.3.3)

--- name: ifrs9-loss-engine description: |- 计算IFRS 9预期信用损失（ECL），支持Vasicek单因子前瞻性调整、Kaplan-Meier生存分析计算PD及贷款摊销计划生成，满足Basel III减值合规要求。 license: Proprietary. See LICENSE.txt in project root. compatibility: Designed for Doramagic-host ecosystem (Claude Code / openclaw / Cursor). Requires Python 3.12+ with uv package manager. metadata: version: "v6.1" blueprint_id: "finance-bp-062" compiled_at: "2026-04-22T13:00:19.657886+00:00" capability_markets: "global" capability_activities: "regtech-compliance" sop_version: "crystal-compilation-v6.1" --- # IFRS 9 损失引擎 (ifrs9-loss-engine) > 计算IFRS 9预期信用损失（ECL），支持Vasicek单因子前瞻性调整、Kaplan-Meier生存分析计算PD及贷款摊销计划生成，满足Basel III减值合规要求。 ## Pipeline `data_collection -> data_storage -> factor_computation -> target_selection -> trading_execution -> visualization` ## Top Use Cases (42 total) ### ECL Limit Level Truncation Analysis (`UC-101`) Calculates Expected Credit Loss (ECL) at the limit/tranche level by computing remaining tenor and projecting loan balances with interest, supporting I **Triggers**: ECL, Expected Credit Loss, limit level ### Loan Amortization Schedule Calculator (`UC-102`) Computes loan amortization schedules by iteratively calculating interest amounts and remaining balances after each payment, determining total repaymen **Triggers**: amortization, loan, payment schedule ### Amortization Schedule with NumPy Financial (`UC-103`) Generates amortization schedules using numpy-financial library functions (PMT, PPMT, IPMT) for calculating periodic payments, principal, and interest **Triggers**: amortization, numpy-financial, PMT For all **42** use cases, see [references/USE_CASES.md](references/USE_CASES.md). **Execute trigger**: `When user intent matches intent_router.uc_entries[].positive_terms AND user uses action verb (run/execute/跑/执行/backtest/fetch/collect)` ## What I'll Ask You - Target market: A-share (default), HK, or crypto? (US stocks in ZVT are half-baked — stockus_nasdaq_AAPL exists but coverage is thin) - Data source / provider: eastmoney (free, no account), joinquant (account+paid), baostock (free, good history), akshare, or qmt (broker)? - Strategy type: MACD golden-cross, MA crossover, volume breakout, fundamental screen, or custom factor? - Time range: start_timestamp and end_timestamp for backtest period - Target entity IDs: specific stocks (stock_sh_600000) or index components (SZ1000)? ## Semantic Locks (Fatal) | ID | Rule | On Violation | |---|---|---| | `SL-01` | Execute sell orders before buy orders in every trading cycle | halt | | `SL-02` | Trading signals MUST use next-bar execution (no look-ahead) | halt | | `SL-03` | Entity IDs MUST follow format entity_type_exchange_code | halt | | `SL-04` | DataFrame index MUST be MultiIndex (entity_id, timestamp) | halt | | `SL-05` | TradingSignal MUST have EXACTLY ONE of: position_pct, order_money, order_amount | halt | | `SL-06` | filter_result column semantics: True=BUY, False=SELL, None/NaN=NO ACTION | halt | | `SL-07` | Transformer MUST run BEFORE Accumulator in factor pipeline | halt | | `SL-08` | MACD parameters locked: fast=12, slow=26, signal=9 | halt | Full lock definitions: [references/LOCKS.md](references/LOCKS.md) ## Top Anti-Patterns (15 total) - **`AP-REGTECH-001`**: Missing attribute initialization on data structures - **`AP-REGTECH-002`**: Self-loops in transaction graphs violate domain rules - **`AP-REGTECH-003`**: Unvalidated floating-point inputs cause runtime crashes All 15 anti-patterns: [references/ANTI_PATTERNS.md](references/ANTI_PATTERNS.md) ## Evidence Quality Notice > [QUALITY NOTICE] This crystal was compiled from blueprint finance-bp-062. Evidence verify ratio = 80.0% and audit fail total = 15. Generated results may have uncaptured requirement gaps. Verify critical decisions against source files (LATEST.yaml / LATEST.jsonl). ## Reference Files | File | Contents | When to Load | |---|---|---| | [references/seed.yaml](references/seed.yaml) | V6+ 全量权威 (source-of-truth) | 有行为/决策争议时必读 | | [references/ANTI_PATTERNS.md](references/ANTI_PATTERNS.md) | 15 条跨项目反模式 | 开始实现前 | | [references/WISDOM.md](references/WISDOM.md) | 跨项目精华借鉴 | 架构决策时 | | [references/CONSTRAINTS.md](references/CONSTRAINTS.md) | domain + fatal 约束 | 规则冲突时 | | [references/USE_CASES.md](references/USE_CASES.md) | 全量 KUC-* 业务场景 | 需要完整示例时 | | [references/LOCKS.md](references/LOCKS.md) | SL-* + preconditions + hints | 生成回测/交易代码前 | | [references/COMPONENTS.md](references/COMPONENTS.md) | AST 组件地图（按 module 拆分）| 查 API 时 | --- *Compiled by Doramagic crystal-compilation-v6.1 from `finance-bp-062` blueprint at 2026-04-22T13:00:19.657886+00:00.* *See [human_summary.md](human_summary.md) for non-technical overview.*

path: human_summary.md
content: # Human Summary

> I help you build quant strategies on A-share with ZVT — from data fetch to backtest, one flow. Just tell me what you want; I'll write the code, you don't have to dig docs. (Heads up: ZVT natively supports A-share, HK, and crypto. US stocks — stockus_nasdaq_AAPL — are half-baked; don't bother for serious work.)

## What I Can Do

- **tagline**: I help you build quant strategies on A-share with ZVT — from data fetch to backtest, one flow. Just tell me what you want; I'll write the code, you don't have to dig docs. (Heads up: ZVT natively supports A-share, HK, and crypto. US stocks — stockus_nasdaq_AAPL — are half-baked; don't bother for serious work.)
- **use_cases**: ['Amortization Schedule with NumPy Financial', 'Loan Amortization Schedule Calculator', 'ECL Limit Level Truncation Analysis', 'A-share MACD daily golden-cross backtest with hfq price adjustment from eastmoney', 'End-to-end ZVT pipeline: FinanceRecorder + GoodCompanyFactor + StockTrader', 'Multi-factor strategy with TargetSelector (AND mode) combining MACD + volume breakout', 'Index composition data collection (SZ1000, SZ2000) with EM recorder']

## What I Ask You

- Target market: A-share (default), HK, or crypto? (US stocks in ZVT are half-baked — stockus_nasdaq_AAPL exists but coverage is thin)
- Data source / provider: eastmoney (free, no account), joinquant (account+paid), baostock (free, good history), akshare, or qmt (broker)?
- Strategy type: MACD golden-cross, MA crossover, volume breakout, fundamental screen, or custom factor?
- Time range: start_timestamp and end_timestamp for backtest period
- Target entity IDs: specific stocks (stock_sh_600000) or index components (SZ1000)?


path: references/ANTI_PATTERNS.md
content: # Anti-Patterns (Cross-Project)

Total: **15**

## finance-bp-060--AMLSim (1)

### `AP-REGTECH-011` — Mismatched configuration parameters across coupled components <sub>(medium)</sub>

When TransactionGenerator and Nominator use different degree_threshold values, Nominator identifies hub accounts using different criteria than TransactionGenerator. This causes incorrect fan-in/fan-out candidate selection. Consequence: AML typology patterns placed on wrong accounts, invalidating simulation results.

## finance-bp-060--AMLSim, finance-bp-067--firesale_stresstest (1)

### `AP-REGTECH-002` — Self-loops in transaction graphs violate domain rules <sub>(high)</sub>

When generating directed transaction graphs or AML typologies, allowing source == destination edges creates self-loops. In AML simulation, self-loops represent accounts sending money to themselves, which is not a valid money laundering pattern. In fire-sale models, self-loops cause undefined behavior. Consequence: corrupted graph topology and invalid typology validation.

## finance-bp-060--AMLSim, finance-bp-071--opensanctions (1)

### `AP-REGTECH-001` — Missing attribute initialization on data structures <sub>(high)</sub>

When loading account lists or creating entity dictionaries, failing to initialize required list/dict attributes (e.g., normal_models, statement IDs) causes KeyError or ValueError at runtime. The code path that reads these structures assumes they exist, but the initialization path omits them. Consequence: pipeline crashes or data loss for affected entities.

## finance-bp-062--ifrs9 (3)

### `AP-REGTECH-005` — Incorrect amortization windows violate IFRS 9 compliance <sub>(high)</sub>

Stage 1 ECL requires exactly 12-month amortization (11 zero-indexed iterations) while Stage 2/3 requires full remaining tenor (tenor-1 iterations). Using identical windows for all stages causes ECL over/understatement. Consequence: regulatory non-compliance and materially incorrect loan loss provisions.

### `AP-REGTECH-010` — Incorrect cumulative PD ordering corrupts lifetime ECL term structure <sub>(high)</sub>

Using cumprod(1-conPD) without shift(1) and fillna(1) produces corrupted first-period survival probability. This cascades into all subsequent marginal and cumulative PD calculations, violating IFRS 9 lifetime ECL requirements. Consequence: systematically incorrect provisions across all remaining tenor periods.

### `AP-REGTECH-015` — Missing EAD component in ECL formula produces incomplete provisions <sub>(high)</sub>

IFRS 9 requires ECL = PD x LGD x EAD. When the EAD module is missing or not integrated, the ECL calculation is incomplete and unusable for provisioning. Consequence: regulatory rejection of ECL calculations, blocking of provisioning and reporting processes.

## finance-bp-062--ifrs9, finance-bp-067--firesale_stresstest (2)

### `AP-REGTECH-003` — Unvalidated floating-point inputs cause runtime crashes <sub>(high)</sub>

When parsing CSV files or computing statistical functions on raw data, failing to validate inputs against acceptable ranges (e.g., DDP near 0 or 1 for norm.ppf, unvalidated floats from CSV) causes ValueError or infinite/NaN values. Consequence: entire model crashes before simulation or corrupted downstream calculations.

### `AP-REGTECH-004` — Division by zero in financial calculations produces inf/NaN <sub>(high)</sub>

When calculating ratios like DDP (downgrade observations / total observations) or price impact denominators (total_quantities), zero-denominator cases are not guarded. The resulting inf/NaN propagates through all downstream calculations, corrupting CCI, ECL, or market clearing. Consequence: systematic data corruption across the entire calculation pipeline.

## finance-bp-067--firesale_stresstest (4)

### `AP-REGTECH-006` — Wrong leverage formula in threshold-based decisions <sub>(high)</sub>

Computing leverage as equity-to-liabilities (E/L) instead of equity-to-assets (E/A) produces different values. This causes deleveraging triggers and insolvency detection to fire at wrong thresholds. Consequence: zombie banks continue operating with negative equity, or healthy banks unnecessarily deleverage.

### `AP-REGTECH-007` — Confusing deleveraging buffer threshold with insolvency threshold <sub>(high)</sub>

Banks below 3% leverage are insolvent and must default, but deleveraging should trigger at 4% buffer. Using the same threshold eliminates the buffer zone, causing immediate default with no intermediate corrective action. Consequence: excessive bank failures amplify systemic contagion.

### `AP-REGTECH-013` — Order-dependent execution creates first-mover advantage bias <sub>(medium)</sub>

Without separating step() and act() phases, first-acting banks sell assets before others decide, creating systematic first-mover advantage. This distorts the competitive equilibrium and fire-sale dynamics. Consequence: unreliable systemic risk estimates that understate contagion for late-acting banks.

### `AP-REGTECH-014` — Immediate asset sales cause double-selling and undefined state <sub>(medium)</sub>

Executing asset sales immediately rather than queuing them to a buffer allows multiple banks holding the same asset to sell simultaneously without accounting for concurrent intentions. Consequence: undefined price impact and incorrect cash transfers in market clearing.

## finance-bp-071--opensanctions (3)

### `AP-REGTECH-008` — Cache keys omit request body for state-changing methods <sub>(high)</sub>

Using only URL for cache fingerprints on POST/PATCH requests means different request bodies return identical cached content. This causes stale data, missing entities, and data corruption in compliance screening pipelines. Consequence: sanctions matches missed or false positives from stale entity data.

### `AP-REGTECH-009` — ID collision in entity construction creates false sanctions matches <sub>(high)</sub>

When constructing entity IDs from source identifiers, insufficient identifying attributes cause different real-world entities to receive identical IDs. The database then merges them into one entity. Consequence: a sanctioned entity's ID matches an innocent entity, causing false positive compliance alerts.

### `AP-REGTECH-012` — Reverse property assignment corrupts entity construction <sub>(medium)</sub>

Stub (reverse) properties represent inverse relationships and raise InvalidData when directly assigned. Attempting to add values to stub properties instead of forward properties causes ValueError, aborting entity construction. Consequence: entities lost from output, incomplete compliance datasets.


path: references/COMPONENTS.md
content: # Component Capability Map

**Project**: finance-bp-062--ifrs9
**Scan date**: 2026-04-22
**Stats**: {'total_files': 9, 'total_classes': 32, 'total_functions': 0, 'total_stages': 9}

## Modules (9)

- [transaction_staging](components/transaction_staging.md): 3 classes
- [transition_matrix_estimation](components/transition_matrix_estimation.md): 4 classes
- [survival_analysis_for_pd](components/survival_analysis_for_pd.md): 4 classes
- [forward-looking_pd_adjustment](components/forward-looking_pd_adjustment.md): 5 classes
- [lgd_model_estimation](components/lgd_model_estimation.md): 3 classes
- [exposure_at_default_(ead)_estimation](components/exposure_at_default_-ead-_estimation.md): 3 classes
- [ifrs_9_staging_classification](components/ifrs_9_staging_classification.md): 3 classes
- [amortization_schedule_generation](components/amortization_schedule_generation.md): 4 classes
- [ecl_computation](components/ecl_computation.md): 3 classes


path: references/CONSTRAINTS.md
content: # Constraints

## preservation_manifest

```yaml
required_objects:
  business_decisions_count: 117
  fatal_constraints_count: 54
  non_fatal_constraints_count: 175
  use_cases_count: 42
  semantic_locks_count: 12
  preconditions_count: 4
  evidence_quality_rules_count: 2
  traceback_scenarios_count: 5

```


path: references/LOCKS.md
content: # Semantic Locks + Preconditions

## Semantic Locks (12)

### `SL-01` <sub>(on_violation: fatal)</sub>
Execute sell orders before buy orders in every trading cycle

### `SL-02` <sub>(on_violation: fatal)</sub>
Trading signals MUST use next-bar execution (no look-ahead)

### `SL-03` <sub>(on_violation: fatal)</sub>
Entity IDs MUST follow format entity_type_exchange_code

### `SL-04` <sub>(on_violation: fatal)</sub>
DataFrame index MUST be MultiIndex (entity_id, timestamp)

### `SL-05` <sub>(on_violation: fatal)</sub>
TradingSignal MUST have EXACTLY ONE of: position_pct, order_money, order_amount

### `SL-06` <sub>(on_violation: fatal)</sub>
filter_result column semantics: True=BUY, False=SELL, None/NaN=NO ACTION

### `SL-07` <sub>(on_violation: fatal)</sub>
Transformer MUST run BEFORE Accumulator in factor pipeline

### `SL-08` <sub>(on_violation: fatal)</sub>
MACD parameters locked: fast=12, slow=26, signal=9

### `SL-09` <sub>(on_violation: warning)</sub>
Default transaction costs: buy_cost=0.001, sell_cost=0.001, slippage=0.001

### `SL-10` <sub>(on_violation: fatal)</sub>
A-share equity trading is T+1 (no same-day close of buy positions)

### `SL-11` <sub>(on_violation: fatal)</sub>
Recorder subclass MUST define provider AND data_schema class attributes

### `SL-12` <sub>(on_violation: fatal)</sub>
Factor result_df MUST contain either 'filter_result' OR 'score_result' column

## Preconditions (4)

- **`PC-01`**: `python3 -c 'import zvt; print(zvt.__version__)'` → on_fail: Run: python3 -m pip install zvt then re-run: python3 -m zvt.init_dirs to initialize data directories
- **`PC-02`**: `python3 -c "from zvt.api.kdata import get_kdata; df = get_kdata(entity_ids=['stock_sh_600000'], limit=1); assert df is not None and len(df) > 0, 'No kdata found'"` → on_fail: Run recorder first: python3 -m zvt.recorders.em.em_stock_kdata_recorder --entity_ids stock_sh_600000 (replace with your target entity IDs)
- **`PC-03`**: `python3 -c "import os; from pathlib import Path; zvt_home = Path(os.environ.get('ZVT_HOME', Path.home() / '.zvt')); assert zvt_home.exists(), f'ZVT home not found: {zvt_home}'"` → on_fail: Run: python3 -m zvt.init_dirs
- **`PC-04`**: `python3 -c "import os, tempfile; from pathlib import Path; zvt_home = Path(os.environ.get('ZVT_HOME', Path.home() / '.zvt')); test_f = zvt_home / '.write_test'; test_f.touch(); test_f.unlink()"` → on_fail: Check directory permissions: chmod u+w ~/.zvt or set ZVT_HOME environment variable to a writable location


path: references/USE_CASES.md
content: # Known Use Cases (KUC)

Total: **42**

## `KUC-101`
**Source**: `ECL/ECLLimitLevel_Truncate.ipynb`

Calculates Expected Credit Loss (ECL) at the limit/tranche level by computing remaining tenor and projecting loan balances with interest, supporting IFRS 9 impairment calculations.

## `KUC-102`
**Source**: `ECL/abAmortization.ipynb`

Computes loan amortization schedules by iteratively calculating interest amounts and remaining balances after each payment, determining total repayment terms.

## `KUC-103`
**Source**: `ECL/amortization.ipynb`

Generates amortization schedules using numpy-financial library functions (PMT, PPMT, IPMT) for calculating periodic payments, principal, and interest breakdown.

## `KUC-104`
**Source**: `LGD/LGDFunctionModel.ipynb`

Develops Loss Given Default (LGD) models using statistical regression techniques with 12-month forward observation windows for non-default populations.

## `KUC-105`
**Source**: `PD/APIBOTMacro.ipynb`

Fetches macroeconomic variables from Bank of Thailand's API including GDP, employment, and trade indicators for integration into credit risk models.

## `KUC-106`
**Source**: `PD/BOTNPLData.ipynb`

Cleans and processes raw NPL (Non-Performing Loan) data from Bank of Thailand, handling inconsistent column structures and formatting for credit risk analysis.

## `KUC-107`
**Source**: `PD/BayesCalibration.ipynb`

Calibrates credit rating transition matrices using Bayesian optimization methods to ensure row stochasticity and alignment with observed migration patterns.

## `KUC-108`
**Source**: `PD/CHAIDSegmentation.ipynb`

Segments used car loan customers using CHAID (Chi-squared Automatic Interaction Detection) decision tree algorithm with optimal binning for credit scoring development.

## `KUC-109`
**Source**: `PD/CooksDStudent.ipynb`

Identifies influential outliers and high-leverage points in PD regression models using Cook's distance and studentized residuals analysis.

## `KUC-110`
**Source**: `PD/HACAdjustment.ipynb`

Adjusts PD regression models for heteroscedasticity and autocorrelation using HAC (Heteroscedasticity and Autocorrelation Consistent) standard errors.

## `KUC-111`
**Source**: `PD/KMVModel.ipynb`

Implements the KMV-Merton structural model to estimate default probabilities from equity prices and market capitalization using option pricing theory.

## `KUC-112`
**Source**: `PD/LassoSelection.ipynb`

Selects optimal macroeconomic variables for PD models using LASSO (Least Absolute Shrinkage and Selection Operator) regression with time series cross-validation.

## `KUC-113`
**Source**: `PD/NRTMatrix.ipynb`

Constructs credit rating transition matrices for non-retail portfolios by counting rating migrations and computing conditional transition probabilities.

## `KUC-114`
**Source**: `PD/NelsonSiegelCurve.ipynb`

Fits Nelson-Siegel-Svensson curves to PD term structures for modeling the relationship between probability of default and time to maturity.

## `KUC-115`
**Source**: `PD/PDAssumedLGD.ipynb`

Defines assumed PD and LGD risk weights by asset class (Strong, Good, Satisfactory, Weak, Default) for regulatory capital and expected loss calculations.

## `KUC-116`
**Source**: `PD/PDCalibration.ipynb`

Calibrates Probability of Default from Through-the-Cycle (TTC) to Point-in-Time (PIT) estimates using central tendency adjustments and risk grade mapping.

## `KUC-117`
**Source**: `PD/PROCVARCLUS.ipynb`

Performs hierarchical variable clustering using VarClusHi algorithm to reduce multicollinearity among macroeconomic variables in PD models.

## `KUC-118`
**Source**: `PD/SilhouetteAnalysis.ipynb`

Evaluates optimal number of clusters in K-means segmentation using silhouette score analysis to determine best customer groupings for PD modeling.

## `KUC-119`
**Source**: `PD/TheoreticalMigrationMatrix.ipynb`

Constructs theoretically grounded migration matrices using parametric distributions and optimization to ensure mathematical consistency and economic plausibility.

## `KUC-120`
**Source**: `PD/allCombinations.ipynb`

Generates each possible combinations of macroeconomic variables within clusters for exhaustive model selection in PD development.

## `KUC-121`
**Source**: `PD/autoCorrTest.ipynb`

Tests for autocorrelation in PD model residuals using ACF plots, Ljung-Box test, and Durbin-Watson statistics to validate time series assumptions.

## `KUC-122`
**Source**: `PD/cci.ipynb`

Calculates Credit Conversion Index (CCI) by measuring downgrade rates and converting to a normalized z-score for stress testing and early warning systems.

## `KUC-123`
**Source**: `PD/chainLadder.ipynb`

Applies actuarial chain ladder methodology to estimate PD curves over time and aging buckets using weighted average calculations.

## `KUC-124`
**Source**: `PD/clusterSelection.ipynb`

Selects representative variables from clusters based on lowest R-square ratio and highest correlation for parsimonious PD model specification.

## `KUC-125`
**Source**: `PD/distributionSelection.ipynb`

Fits and compares multiple statistical distributions (Gamma, Log-normal, Weibull, etc.) to empirical PD risk grade curves for model selection.

## `KUC-126`
**Source**: `PD/externalMatrix.ipynb`

Integrates external credit ratings (e.g., Moody's) and their transition matrices with internal rating systems for PD benchmarking and calibration.

## `KUC-127`
**Source**: `PD/gammaFitting.ipynb`

Fits Gamma cumulative distribution functions to PD risk grade curves using scipy optimization to model default probability term structure.

## `KUC-128`
**Source**: `PD/generatorMatrix.ipynb`

Constructs generator (infinitesimal) matrices for continuous-time credit migration models enabling computation of transition probabilities over arbitrary time horizons.

## `KUC-129`
**Source**: `PD/heteroTest.ipynb`

Tests for heteroscedasticity in PD regression models using White's test and Breusch-Pagan test to validate homoscedasticity assumptions.

## `KUC-130`
**Source**: `PD/lifetimeCalibration.ipynb`

Calibrates lifetime PD curves using through-the-cycle (TTC) reference data and tracks calibration stability over time for IFRS 9 lifetime ECL calculations.

## `KUC-131`
**Source**: `PD/limitPDCurves.ipynb`

Applies limiting constraints to PD curves ensuring monotonicity, non-exceedance of regulatory floors, and compliance with Basel/IFRS 9 requirements.

## `KUC-132`
**Source**: `PD/multicolTest.ipynb`

Tests for multicollinearity among macroeconomic variables using Variance Inflation Factor (VIF) and correlation matrices in PD regression models.

## `KUC-133`
**Source**: `PD/normalityTest.ipynb`

Tests normality of regression residuals using Shapiro-Wilk, Anderson-Darling tests, QQ plots, and histograms for PD model assumption validation.

## `KUC-134`
**Source**: `PD/simplifiedCCI.ipynb`

Computes simplified Credit Conversion Index using z-score normalization of downgrade probabilities for portfolio-level credit stress monitoring.

## `KUC-135`
**Source**: `PD/survivalAnalysis.ipynb`

Applies survival analysis techniques to estimate lifetime default probabilities using Kaplan-Meier curves and Cox proportional hazards for IFRS 9 staging.

## `KUC-136`
**Source**: `PD/timeSeriesKMeans.ipynb`

Clusters macroeconomic time series using Dynamic Time Warping (DTW) distance with K-means algorithm to identify similar economic patterns for PD modeling.

## `KUC-137`
**Source**: `PD/timeSeriesStationary.ipynb`

Analyzes stationarity of macroeconomic time series using ADF tests and seasonal decomposition for proper model specification in PD regression.

## `KUC-138`
**Source**: `PD/transitionMatrix.ipynb`

Constructs empirical credit rating transition matrices from transaction-level data by tracking 12-month forward aging status and computing migration probabilities.

## `KUC-139`
**Source**: `PD/univariateAnalysis1.ipynb`

Performs univariate regression analysis on individual macroeconomic variables to assess their predictive power for ODR (Observed Default Rate) before multivariate modeling.

## `KUC-140`
**Source**: `PD/vasicekBaselRho.ipynb`

Estimates Basel Rho parameter (asset correlation) in the Vasicek single-factor model for regulatory capital calculation and portfolio credit risk.

## `KUC-141`
**Source**: `PD/vasicekTransitionMatrix.ipynb`

Calibrates credit rating transition matrices using the Vasicek asymptotic single risk factor model ensuring consistency with Basel regulatory requirements.

## `KUC-142`
**Source**: `Staging/backwardTransaction.ipynb`

Processes backward-looking transaction data to create performance windows and default flags for credit scoring model development in staging environments.


path: references/WISDOM.md
content: # Cross-Project Wisdom

Total: **10**

## `CW-REGTECH-001` — Input bounds validation before statistical computation
**From**: finance-bp-062--ifrs9, finance-bp-067--firesale_stresstest · **Applicable to**: regtech-compliance

Statistical functions like norm.ppf() and cumprod() have strict input requirements that, if violated, produce infinite or NaN values corrupting entire pipelines. Always validate inputs against domain constraints (DDP in (0,1), counts > 0) before passing to statistical functions. Apply to any statistical or inverse-CDF computation.

## `CW-REGTECH-002` — Graph/topology invariant verification before construction
**From**: finance-bp-060--AMLSim, finance-bp-067--firesale_stresstest · **Applicable to**: regtech-compliance

Before constructing graph structures (transaction networks, transition matrices), verify invariants: sum(in-degrees) = sum(out-degrees), matrix row sums = 1.0, degree sequence length divisibility. This catches data corruption early before expensive graph construction operations. Apply to any bipartite or directed graph generation.

## `CW-REGTECH-003` — Regulatory amortization window discipline
**From**: finance-bp-062--ifrs9 · **Applicable to**: regtech-compliance

IFRS 9 mandates different ECL calculation windows: exactly 12-month for Stage 1 (11 zero-indexed iterations), full remaining tenor for Stage 2/3. Mixing these up violates compliance requirements. Always encode stage-specific window logic explicitly rather than reusing a single loop variable across stages.

## `CW-REGTECH-004` — Fingerprint composition must include all request dimensions
**From**: finance-bp-071--opensanctions · **Applicable to**: regtech-compliance

Cache keys must include all request parameters that affect response content: URL, HTTP method, authentication headers, and request body for state-changing methods. POST requests with different bodies returning identical cache is a silent data corruption bug. Always compose fingerprints from the union of all content-affecting parameters.

## `CW-REGTECH-005` — Floating-point zero-equivalence with explicit epsilon tolerance
**From**: finance-bp-067--firesale_stresstest · **Applicable to**: regtech-compliance

IEEE 754 floating-point precision causes exact zero comparisons to fail in financial calculations. Always use eps=1e-9 tolerance for zero-equivalence checks in market clearing, leverage ratios, and price impact calculations. This prevents division-by-zero crashes and incorrect cash transfers.

## `CW-REGTECH-006` — Stage classification threshold ordering enforcement
**From**: finance-bp-062--ifrs9 · **Applicable to**: regtech-compliance

IFRS 9 SICR thresholds must be ordered: BUCKETS 2-3 trigger Stage 2, BUCKETS >=4 trigger Stage 3. Applying thresholds in wrong order or omitting absolute DPD triggers causes material ECL misstatement. Validate threshold ordering and document bucket-to-stage mapping explicitly.

## `CW-REGTECH-007` — Initialization-before-use dependency ordering
**From**: finance-bp-067--firesale_stresstest · **Applicable to**: regtech-compliance

Operational dependencies must initialize before dependent objects use them: AssetMarket before bank registration, CSV file existence before parsing, entity ID before statement addition. Violations cause AttributeError or FileNotFoundError that abort entire initialization. Always encode dependency ordering explicitly in initialization sequences.

## `CW-REGTECH-008` — Sufficient entity ID collision prevention
**From**: finance-bp-071--opensanctions · **Applicable to**: regtech-compliance

Entity IDs must include enough identifying attributes (dataset prefix, source, identifier type, document number) to guarantee uniqueness. Collisions create false equivalence between unrelated entities, directly causing false positive sanctions matches. Include the maximum available discriminating attributes in ID construction.

## `CW-REGTECH-009` — Hub selection with candidate removal before addition
**From**: finance-bp-060--AMLSim · **Applicable to**: regtech-compliance

When selecting hub accounts for typology placement, always call remove_typology_candidate BEFORE add_node for each selected account. Reversing this order causes hub self-selection (accounts choosing themselves) and duplicate assignment across overlapping patterns. Apply to any allocation algorithm with candidate pooling.

## `CW-REGTECH-010` — Insolvency detection before operational decisions
**From**: finance-bp-067--firesale_stresstest · **Applicable to**: regtech-compliance

Banks below the insolvency threshold (3% leverage) must trigger default immediately, not enter the deleveraging decision logic. Checking operational thresholds before insolvency creates zombie banks with negative equity. Always gate operational decisions on prior insolvency state.


path: references/components/amortization_schedule_generation.md
content: # amortization_schedule_generation (4 classes)

## `amortization.ipynb`
`amortization_schedule_generation/amortization-ipynb.py:0`

## `abAmortization.ipynb`
`amortization_schedule_generation/abamortization-ipynb.py:0`

## `compounding`
`amortization_schedule_generation/compounding.py:0`

## `schedule_type`
`amortization_schedule_generation/schedule-type.py:0`


path: references/components/ecl_computation.md
content: # ecl_computation (3 classes)

## `ECLLimitLevel_Truncate.ipynb`
`ecl_computation/ecllimitlevel-truncate-ipynb.py:0`

## `discount_rate`
`ecl_computation/discount-rate.py:0`

## `probability_weighting`
`ecl_computation/probability-weighting.py:0`


path: references/components/exposure_at_default_-ead-_estimation.md
content: # exposure_at_default_(ead)_estimation (3 classes)

## `ECLLimitLevel_Truncate.ipynb`
`exposure_at_default_(ead)_estimation/ecllimitlevel-truncate-ipynb.py:0`

## `ead_model`
`exposure_at_default_(ead)_estimation/ead-model.py:0`

## `limit_treatment`
`exposure_at_default_(ead)_estimation/limit-treatment.py:0`


path: references/components/forward-looking_pd_adjustment.md
content: # forward-looking_pd_adjustment (5 classes)

## `cci.ipynb`
`forward-looking_pd_adjustment/cci-ipynb.py:0`

## `vasicekTransitionMatrix.ipynb`
`forward-looking_pd_adjustment/vasicektransitionmatrix-ipynb.py:0`

## `simplifiedCCI.ipynb`
`forward-looking_pd_adjustment/simplifiedcci-ipynb.py:0`

## `macro_model`
`forward-looking_pd_adjustment/macro-model.py:0`

## `correlation_parameter`
`forward-looking_pd_adjustment/correlation-parameter.py:0`


path: references/components/ifrs_9_staging_classification.md
content: # ifrs_9_staging_classification (3 classes)

## `backwardTransaction.ipynb`
`ifrs_9_staging_classification/backwardtransaction-ipynb.py:0`

## `sicr_method`
`ifrs_9_staging_classification/sicr-method.py:0`

## `stage_thresholds`
`ifrs_9_staging_classification/stage-thresholds.py:0`


path: references/components/lgd_model_estimation.md
content: # lgd_model_estimation (3 classes)

## `LGDFunctionModel.ipynb`
`lgd_model_estimation/lgdfunctionmodel-ipynb.py:0`

## `lgd_definition`
`lgd_model_estimation/lgd-definition.py:0`

## `discount_method`
`lgd_model_estimation/discount-method.py:0`


path: references/components/survival_analysis_for_pd.md
content: # survival_analysis_for_pd (4 classes)

## `survivalAnalysis.ipynb`
`survival_analysis_for_pd/survivalanalysis-ipynb.py:0`

## `lifetimeCalibration.ipynb`
`survival_analysis_for_pd/lifetimecalibration-ipynb.py:0`

## `survival_function`
`survival_analysis_for_pd/survival-function.py:0`

## `calibration_method`
`survival_analysis_for_pd/calibration-method.py:0`


path: references/components/transaction_staging.md
content: # transaction_staging (3 classes)

## `backwardTransaction.ipynb`
`transaction_staging/backwardtransaction-ipynb.py:0`

## `lag_period`
`transaction_staging/lag-period.py:0`

## `exclusion_rules`
`transaction_staging/exclusion-rules.py:0`


path: references/components/transition_matrix_estimation.md
content: # transition_matrix_estimation (4 classes)

## `transitionMatrix.ipynb`
`transition_matrix_estimation/transitionmatrix-ipynb.py:0`

## `NRTMatrix.ipynb`
`transition_matrix_estimation/nrtmatrix-ipynb.py:0`

## `status_mapping`
`transition_matrix_estimation/status-mapping.py:0`

## `matrix_normalization`
`transition_matrix_estimation/matrix-normalization.py:0`


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)