Skip to content

Core API Reference

Metrics

Use the metrics module for binary model discrimination and portfolio timing measures. Start with calculate_gini() and calculate_ks() when comparing risk scores against observed outcomes.

cranalytics.metrics

Core risk and portfolio metrics.

calculate_gini(y_true: np.ndarray, y_prob: np.ndarray) -> float

Calculate the binary-model Gini coefficient.

Parameters:

Name Type Description Default
y_true ndarray

Binary observed outcomes.

required
y_prob ndarray

Predicted risk scores or probabilities, where larger values indicate higher risk.

required

Returns:

Type Description
float

Gini coefficient, calculated as 2 * AUC - 1.

Examples:

>>> import numpy as np
>>> from cranalytics import calculate_gini
>>> calculate_gini(np.array([0, 1]), np.array([0.1, 0.9]))
1.0

calculate_ks(y_true: np.ndarray, y_prob: np.ndarray) -> float

Calculate the binary-model Kolmogorov-Smirnov statistic.

Parameters:

Name Type Description Default
y_true ndarray

Binary observed outcomes.

required
y_prob ndarray

Predicted risk scores or probabilities, where larger values indicate higher risk.

required

Returns:

Type Description
float

Maximum absolute difference between cumulative good and bad shares.

Examples:

>>> import numpy as np
>>> from cranalytics import calculate_ks
>>> calculate_ks(np.array([0, 1]), np.array([0.1, 0.9]))
1.0

calculate_classification_metrics(y_true: np.ndarray, y_prob: np.ndarray, threshold: float = 0.5) -> dict[str, float]

Calculate accuracy, precision, recall, and F1 score.

calculate_wal(schedule: pd.DataFrame) -> float

Calculate Weighted Average Life (WAL) in months.

Finance

The finance module contains amortization, present-value, and return helpers. These utilities are building blocks for analysis rather than an end-to-end Loss Forecasting workflow.

cranalytics.finance

Basic financial math utilities used in credit analytics.

generate_amortization_schedule(principal: float, annual_rate: float, term_months: int) -> pd.DataFrame

Generate a standard monthly amortization schedule.

calculate_irr(cash_flows: list[float], initial_investment: float, periods_per_year: int = 12) -> float

Calculate the annualized Internal Rate of Return (IRR) as a decimal.

calculate_npv(cash_flows: list[float], initial_investment: float, discount_rate: float, periods_per_year: int = 12) -> float

Calculate Net Present Value (NPV).

Portfolio

Use the portfolio module for score segmentation and collateral-based recovery diagnostics. segment_fico() only requires a fico_score column; LGD helpers need exposure fields such as principal.

cranalytics.portfolio

Portfolio transforms and loss calculation utilities.

assign_fico_band(fico_score: int, bands: dict[str, tuple[int, int]] | None = None) -> str

Assign a FICO band based on score.

assign_risk_grade(fico_score: int, cutoffs: list[int] | None = None) -> int

Assign a risk grade based on descending FICO score cutoffs.

Parameters:

Name Type Description Default
fico_score int

The FICO score.

required
cutoffs list[int] | None

A descending list of thresholds. If None, it defaults to [800, 750, 700, 650, 600], producing grades 1-6.

None

segment_fico(df: pd.DataFrame, fico_column: str = 'fico_score', bands: dict[str, tuple[int, int]] | None = None, risk_cutoffs: list[int] | None = None) -> pd.DataFrame

Add FICO band and risk grade columns to a portfolio DataFrame.

Parameters:

Name Type Description Default
df DataFrame

Input DataFrame. Only the score column is required.

required
fico_column str

Name of the score column to segment.

'fico_score'
bands dict[str, tuple[int, int]] | None

Optional mapping of band labels to inclusive score ranges.

None
risk_cutoffs list[int] | None

Optional descending thresholds used to assign numeric grades.

None

Returns:

Type Description
DataFrame

Copy of the input DataFrame with fico_band and risk_grade columns.

Examples:

>>> import pandas as pd
>>> from cranalytics import segment_fico
>>> segmented = segment_fico(pd.DataFrame({"fico_score": [780, 640]}))
>>> segmented[["fico_band", "risk_grade"]].astype(str).to_dict("records")
[{'fico_band': '750-799', 'risk_grade': '2'}, {'fico_band': '600-649', 'risk_grade': '5'}]

calculate_fico_mix(df: pd.DataFrame, group_by: list[str] | None = None) -> pd.DataFrame

Calculate the FICO mix (distribution) for a portfolio or vintage.

calculate_lgd(loan_data: pd.DataFrame | pd.Series, haircuts: dict[str, float] | None = None) -> pd.Series | float

Calculate Loss Given Default (LGD) based on collateral.

LGD = 1 - (Recovery Value / Exposure) Recovery Value = Collateral Value * (1 - Haircut)

estimate_recovery(loan_data: pd.DataFrame | pd.Series, haircuts: dict[str, float] | None = None) -> pd.Series | float

Estimate recovery amount based on collateral value and haircuts.