Standardized Approach¶
The SA assigns risk weights based on external ratings (CQS) and exposure characteristics (LTV for real estate).
Basic Usage¶
from creditriskengine.rwa.standardized.credit_risk_sa import assign_sa_risk_weight
from creditriskengine.core.types import SAExposureClass, CreditQualityStep, Jurisdiction
# Corporate with rating
rw = assign_sa_risk_weight(SAExposureClass.CORPORATE, CreditQualityStep.CQS_2)
print(f"A-rated corporate: {rw}%") # 50%
# Residential mortgage by LTV
rw = assign_sa_risk_weight(SAExposureClass.RESIDENTIAL_MORTGAGE, ltv=0.75)
print(f"RRE at 75% LTV: {rw}%") # 35%
# UK PRA loan-splitting
from creditriskengine.rwa.standardized.credit_risk_sa import uk_pra_loan_splitting_rre
result = uk_pra_loan_splitting_rre(loan_amount=200_000, property_value=300_000)
print(f"Blended RW: {result['blended_rw']:.1f}%")
SCRA for Banks¶
In jurisdictions not using external ratings:
rw = assign_sa_risk_weight(SAExposureClass.BANK, scra_grade="A") # 40%
rw = assign_sa_risk_weight(SAExposureClass.BANK, scra_grade="B") # 75%
rw = assign_sa_risk_weight(SAExposureClass.BANK, scra_grade="C") # 150%
creditriskengine.rwa.standardized.credit_risk_sa
¶
Standardized Approach (SA) for Credit Risk — BCBS d424 CRE20.
Risk weight assignment logic for all SA exposure classes. Supports jurisdiction-specific overrides via YAML config.
get_sovereign_risk_weight(cqs, jurisdiction=Jurisdiction.BCBS, is_domestic_own_currency=False)
¶
Risk weight for sovereign exposures.
Reference: BCBS CRE20.7, Table 1.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cqs
|
CreditQualityStep
|
Credit quality step. |
required |
jurisdiction
|
Jurisdiction
|
Regulatory jurisdiction. |
BCBS
|
is_domestic_own_currency
|
bool
|
If True, domestic sovereign in own currency. |
False
|
Returns:
| Type | Description |
|---|---|
float
|
Risk weight as percentage. |
Source code in creditriskengine\rwa\standardized\credit_risk_sa.py
get_bank_risk_weight(cqs=None, jurisdiction=Jurisdiction.BCBS, scra_grade=None, is_short_term=False)
¶
Risk weight for bank exposures.
Uses ECRA (External Credit Risk Assessment) if CQS provided, otherwise SCRA (Standardized Credit Risk Assessment).
Reference: BCBS CRE20.15-20.21.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cqs
|
CreditQualityStep | None
|
Credit quality step (for ECRA). |
None
|
jurisdiction
|
Jurisdiction
|
Regulatory jurisdiction. |
BCBS
|
scra_grade
|
str | None
|
SCRA grade A/B/C (when ECRA not used). |
None
|
is_short_term
|
bool
|
If True, use short-term claim risk weights. |
False
|
Returns:
| Type | Description |
|---|---|
float
|
Risk weight as percentage. |
Source code in creditriskengine\rwa\standardized\credit_risk_sa.py
get_corporate_risk_weight(cqs, jurisdiction=Jurisdiction.BCBS, is_investment_grade=None, is_sme=False)
¶
Risk weight for corporate exposures.
Reference: BCBS CRE20.28-20.32, Table 7.
UK PRA divergence (PS9/24, para 3.17): Unrated investment-grade corporates = 65%.
EU CRR3 Art. 501 — SME supporting factor: Exposures <= EUR 2.5M: multiply RW by 0.7619 Exposures > EUR 2.5M: 0.7619 for first EUR 2.5M, 0.85 for remainder
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cqs
|
CreditQualityStep
|
Credit quality step. |
required |
jurisdiction
|
Jurisdiction
|
Regulatory jurisdiction. |
BCBS
|
is_investment_grade
|
bool | None
|
For UK PRA unrated corporate treatment. |
None
|
is_sme
|
bool
|
If True and jurisdiction supports it, apply SME factor. |
False
|
Returns:
| Type | Description |
|---|---|
float
|
Risk weight as percentage. |
Source code in creditriskengine\rwa\standardized\credit_risk_sa.py
get_residential_re_risk_weight(ltv, jurisdiction=Jurisdiction.BCBS, is_cashflow_dependent=False, is_income_producing=False)
¶
Risk weight for residential real estate exposures.
Reference: BCBS CRE20.71-20.86, Tables 12-13. Whole-loan approach (BCBS/EU CRR3).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ltv
|
float
|
Loan-to-value ratio (e.g., 0.75 for 75%). |
required |
jurisdiction
|
Jurisdiction
|
Regulatory jurisdiction. |
BCBS
|
is_cashflow_dependent
|
bool
|
If True, use cashflow-dependent table. |
False
|
is_income_producing
|
bool
|
If True, treated as income-producing. |
False
|
Returns:
| Type | Description |
|---|---|
float
|
Risk weight as percentage. |
Source code in creditriskengine\rwa\standardized\credit_risk_sa.py
uk_pra_loan_splitting_rre(loan_amount, property_value, counterparty_rw=100.0, is_cashflow_dependent=False)
¶
UK PRA loan-splitting for residential real estate (PS9/24).
The UK PRA diverges from the EU/BCBS whole-loan approach by splitting each residential mortgage into two tranches:
- Secured tranche: The portion of the loan up to the LTV threshold (55% of property value). This tranche receives the lower LTV-based risk weight from the RRE table.
- Unsecured tranche: The remainder of the loan above the threshold. This tranche receives the counterparty risk weight (typically 100% for unrated corporates/retail).
The blended risk weight is the EAD-weighted average of both tranches.
Reference: PRA PS9/24, Chapter 4 (Real Estate).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
loan_amount
|
float
|
Outstanding loan amount. |
required |
property_value
|
float
|
Current property value. |
required |
counterparty_rw
|
float
|
Risk weight for the unsecured tranche (default 100%). |
100.0
|
is_cashflow_dependent
|
bool
|
If True, use cashflow-dependent RRE table. |
False
|
Returns:
| Type | Description |
|---|---|
dict[str, float]
|
Dict with: - 'secured_amount': Amount in the secured tranche. - 'unsecured_amount': Amount in the unsecured tranche. - 'secured_rw': Risk weight for the secured tranche (%). - 'unsecured_rw': Risk weight for the unsecured tranche (%). - 'blended_rw': EAD-weighted blended risk weight (%). - 'ltv': Loan-to-value ratio. |
Source code in creditriskengine\rwa\standardized\credit_risk_sa.py
276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 | |
get_commercial_re_risk_weight(ltv, counterparty_rw=100.0, is_cashflow_dependent=False, is_adc=False, is_presold_residential=False)
¶
Risk weight for commercial real estate exposures.
Reference: BCBS CRE20.87-20.98, Tables 14-15.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ltv
|
float
|
Loan-to-value ratio. |
required |
counterparty_rw
|
float
|
Risk weight of the counterparty. |
100.0
|
is_cashflow_dependent
|
bool
|
If True, use IPRE table (Table 15). |
False
|
is_adc
|
bool
|
If True, Land ADC treatment (150%). |
False
|
is_presold_residential
|
bool
|
If True and ADC, use 100%. |
False
|
Returns:
| Type | Description |
|---|---|
float
|
Risk weight as percentage. |
Source code in creditriskengine\rwa\standardized\credit_risk_sa.py
get_defaulted_risk_weight(specific_provisions_pct, is_rre_secured=False)
¶
Risk weight for defaulted exposures.
Reference: BCBS CRE20.99-20.101.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
specific_provisions_pct
|
float
|
Specific provisions as % of outstanding. |
required |
is_rre_secured
|
bool
|
If secured by residential real estate. |
False
|
Returns:
| Type | Description |
|---|---|
float
|
Risk weight as percentage. |
Source code in creditriskengine\rwa\standardized\credit_risk_sa.py
get_retail_risk_weight(is_regulatory_retail=True)
¶
Risk weight for retail exposures.
Reference: BCBS CRE20.65.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
is_regulatory_retail
|
bool
|
If True, meets regulatory retail criteria. |
True
|
Returns:
| Type | Description |
|---|---|
float
|
Risk weight as percentage (75% or 100%). |
Source code in creditriskengine\rwa\standardized\credit_risk_sa.py
get_equity_risk_weight(is_listed=True, is_speculative=False)
¶
Risk weight for equity exposures.
Reference: BCBS CRE20.49-20.58.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
is_listed
|
bool
|
If True, listed equity. |
True
|
is_speculative
|
bool
|
If True, speculative unlisted equity. |
False
|
Returns:
| Type | Description |
|---|---|
float
|
Risk weight as percentage. |
Source code in creditriskengine\rwa\standardized\credit_risk_sa.py
get_subordinated_debt_risk_weight()
¶
Risk weight for subordinated debt.
Reference: BCBS CRE20.49.
Returns:
| Type | Description |
|---|---|
float
|
150% risk weight. |
get_covered_bond_risk_weight(cqs, is_qualifying=True, issuer_cqs=None)
¶
Risk weight for covered bond exposures.
Reference: BCBS CRE20.60-67, Table 10.
Qualifying covered bonds receive preferential risk weights based on the bond's own CQS. Non-qualifying covered bonds, or unrated qualifying covered bonds, fall back to the issuing bank's risk weight.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cqs
|
CreditQualityStep
|
Credit quality step of the covered bond. |
required |
is_qualifying
|
bool
|
If True, bond meets CRE20.61-66 qualifying criteria. |
True
|
issuer_cqs
|
CreditQualityStep | None
|
CQS of the issuing bank (used for unrated or non-qualifying bonds). |
None
|
Returns:
| Type | Description |
|---|---|
float
|
Risk weight as percentage. |
Source code in creditriskengine\rwa\standardized\credit_risk_sa.py
get_mdb_risk_weight(mdb_category=1, cqs=CreditQualityStep.UNRATED)
¶
Risk weight for multilateral development bank exposures.
Reference: BCBS CRE20.8-9.
Qualifying MDBs (Category 1) receive 0% risk weight. Category 2 MDBs are treated using the bank ECRA table. Non-qualifying MDBs use the corporate risk weight table.
Categories: - Category 1 (qualifying): IBRD, IFC, ADB, AfDB, EBRD, IADB, EIB, etc. These receive 0% RW per CRE20.8. - Category 2: Other MDBs that meet some but not all qualifying criteria. Use bank ECRA table per CRE20.9. - Non-qualifying (category 3+): Use corporate risk weight table.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mdb_category
|
int
|
MDB category (1 = qualifying, 2 = bank table, 3+ = corporate table). |
1
|
cqs
|
CreditQualityStep
|
Credit quality step from external rating. |
UNRATED
|
Returns:
| Type | Description |
|---|---|
float
|
Risk weight as percentage. |
Source code in creditriskengine\rwa\standardized\credit_risk_sa.py
assign_sa_risk_weight(exposure_class, cqs=CreditQualityStep.UNRATED, jurisdiction=Jurisdiction.BCBS, ltv=None, counterparty_rw=100.0, is_investment_grade=None, is_sme=False, is_cashflow_dependent=False, is_income_producing=False, is_adc=False, is_presold_residential=False, is_domestic_own_currency=False, specific_provisions_pct=0.0, is_rre_secured=False, is_listed=True, is_speculative=False, is_regulatory_retail=True, scra_grade=None, is_short_term=False, is_qualifying=True, issuer_cqs=None, mdb_category=1, config=None)
¶
Assign SA risk weight based on exposure class and parameters.
Master dispatcher that routes to the appropriate risk weight function.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
exposure_class
|
SAExposureClass
|
SA exposure class per BCBS CRE20. |
required |
cqs
|
CreditQualityStep
|
Credit quality step from external rating. |
UNRATED
|
jurisdiction
|
Jurisdiction
|
Regulatory jurisdiction. |
BCBS
|
ltv
|
float | None
|
Loan-to-value ratio for real estate. |
None
|
counterparty_rw
|
float
|
Counterparty risk weight for CRE. |
100.0
|
is_investment_grade
|
bool | None
|
For UK unrated corporate treatment. |
None
|
is_sme
|
bool
|
For EU SME supporting factor. |
False
|
is_cashflow_dependent
|
bool
|
For real estate cashflow dependency. |
False
|
is_income_producing
|
bool
|
For income-producing property. |
False
|
is_adc
|
bool
|
For land ADC exposures. |
False
|
is_presold_residential
|
bool
|
For pre-sold ADC. |
False
|
is_domestic_own_currency
|
bool
|
For domestic sovereign treatment. |
False
|
specific_provisions_pct
|
float
|
For defaulted exposures. |
0.0
|
is_rre_secured
|
bool
|
For defaulted RRE-secured exposures. |
False
|
is_listed
|
bool
|
For equity classification. |
True
|
is_speculative
|
bool
|
For speculative equity. |
False
|
is_regulatory_retail
|
bool
|
For retail qualification. |
True
|
scra_grade
|
str | None
|
SCRA grade for banks (A/B/C). |
None
|
is_short_term
|
bool
|
For short-term bank claims (CRE20.17). |
False
|
is_qualifying
|
bool
|
For covered bonds qualifying criteria (CRE20.61-66). |
True
|
issuer_cqs
|
CreditQualityStep | None
|
Issuing bank CQS for covered bonds. |
None
|
mdb_category
|
int
|
MDB category (1=qualifying, 2=bank, 3+=corporate). |
1
|
config
|
dict[str, Any] | None
|
Optional jurisdiction config dict. |
None
|
Returns:
| Type | Description |
|---|---|
float
|
Risk weight as percentage. |
Source code in creditriskengine\rwa\standardized\credit_risk_sa.py
545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 | |