Metadata-Version: 2.5
Name: cranalytics
Version: 0.3.0
Summary: Core credit risk analytics engine with vintage forecasting, FICO segmentation, and portfolio modeling
Project-URL: Homepage, https://github.com/ClaySheffler/cranalytics
Project-URL: Documentation, https://github.com/ClaySheffler/cranalytics/tree/main/docs
Project-URL: Repository, https://github.com/ClaySheffler/cranalytics
Project-URL: Issues, https://github.com/ClaySheffler/cranalytics/issues
Project-URL: Changelog, https://github.com/ClaySheffler/cranalytics/blob/main/CHANGELOG.md
Project-URL: CI, https://github.com/ClaySheffler/cranalytics/actions/workflows/ci.yml
Author-email: Clay Sheffler <clay.sheffler@gmail.com>
License-Expression: MIT
License-File: LICENSE
Keywords: FICO segmentation,credit risk,forecasting,portfolio modeling,vintage analysis
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Office/Business :: Financial
Requires-Python: >=3.10
Requires-Dist: lifelines
Requires-Dist: matplotlib>=3.5.0
Requires-Dist: numpy
Requires-Dist: numpy-financial
Requires-Dist: pandas
Requires-Dist: pandera>=0.17.0
Requires-Dist: plotly>=5.0.0
Requires-Dist: pooch>=1.9.0
Requires-Dist: pyarrow>=23.0.1
Requires-Dist: pydantic>=2
Requires-Dist: scikit-learn
Requires-Dist: scipy
Requires-Dist: seaborn>=0.12.0
Requires-Dist: statsmodels
Provides-Extra: lightgbm
Requires-Dist: lightgbm>=4.0; extra == 'lightgbm'
Provides-Extra: ml
Requires-Dist: optbinning>=0.19.0; extra == 'ml'
Provides-Extra: xgboost
Requires-Dist: xgboost>=1.7.0; extra == 'xgboost'
Description-Content-Type: text/markdown

# cranalytics - Credit Risk Analytics

[![PyPI version](https://img.shields.io/pypi/v/cranalytics.svg)](https://pypi.org/project/cranalytics/)
[![Python versions](https://img.shields.io/pypi/pyversions/cranalytics.svg)](https://pypi.org/project/cranalytics/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

DataFrame-first credit risk analytics for five core workflows plus advanced and
supporting paths:

1. Vintage curve fitting
2. Lifetime loss forecasting
3. FICO segmentation & portfolio diagnostics
4. Feature analytics
5. ML modeling — binary loan performance flags
6. Survival analysis
7. Portfolio simulation
8. Rollforward workflow diagnostics

The base install includes every documented workflow in this repo, including
visualization and survival analysis. If you choose an external modeling backend
such as `optbinning`, `xgboost`, or `lightgbm`, install that backend directly.

## Installation

Recommended environment:

- Official CPython 3.11 or 3.12 is the easiest path
- Python 3.10+ is supported
- Upgrade `pip` first so binary wheels for `numpy`, `scipy`, and `pyarrow` resolve cleanly

```bash
python -m pip install --upgrade pip
```

Install from PyPI:

```bash
uv add cranalytics
# or: python -m pip install cranalytics
```

If install fails on compiled dependencies:

- Upgrade `pip` first
- Prefer official CPython over alternative interpreters when validating wheels
- On Windows, install or update the Microsoft Visual C++ Redistributable if `pyarrow` fails to import after install
- If you already use conda/mamba, `conda-forge` can be the simplest fallback for scientific dependencies

From source:

```bash
uv pip install -e .
# or: python -m pip install -e .
```

Development dependencies (testing, linting, docs):

```bash
uv sync --group dev
```

## Choose Your Path

After install, the canonical first command is `cranalytics quickstart`. Once you
know your question or data shape, use the [workflow guide](https://github.com/ClaySheffler/cranalytics/blob/main/docs/choose_your_path.md) and [workflow map](https://github.com/ClaySheffler/cranalytics/blob/main/docs/reference/workflow_map.md) to find the right workflow.

- If you already know the workflow and want to skip the menu, jump straight to the packaged demo or command that matches your first win:
- Vintage: fitted curve and ultimate loss estimate
  `python -m cranalytics.examples.core_vintage`
- Lifetime Loss: reserve estimate on a mock portfolio
  `python -m cranalytics.examples.core_lifetime_loss`
- FICO Segmentation: FICO-band table and mix diagnostics
  `python -m cranalytics.examples.core_segmentation`
- Feature Analytics: ranked feature table
  `python -m cranalytics.examples.core_feature_analytics`
- ML Modeling: fold-level backtest summary table
  `python -m cranalytics.examples.core_ml_modeling`
- Rollforward: readiness report directory and diagnostics
  `cranalytics rollforward check your_rollforward_data.csv --output-dir rollforward_readiness_out`

- Learn Workflow 4 with the tutorial: [feature_analytics.md](https://github.com/ClaySheffler/cranalytics/blob/main/docs/tutorials/feature_analytics.md)
- Learn Workflow 5 with the tutorial: [ml_modeling.md](https://github.com/ClaySheffler/cranalytics/blob/main/docs/tutorials/ml_modeling.md)
- Analyze time-to-default or prepayment timing:
  `python -m cranalytics.examples.core_survival`
- Start from aggregated monthly rollforward data:
  `cranalytics rollforward check your_rollforward_data.csv --output-dir rollforward_readiness_out`

## Start Here (After Install)

### 1) Verify your install

```bash
python -c "import cranalytics as ca; print(ca.__version__)"
```

Note: install name is `cranalytics`, import namespace is `cranalytics`.

### 2) Run the quickstart

```bash
cranalytics quickstart
```

Pick any workflow from the menu. Each runs in under 30 seconds with
synthetic data, narrated output, and a summary of what data you need to run
it on your own portfolio.

### 3) Install bundled Claude skills (optional)

Preview install actions first:

```bash
cranalytics install-skills --dry-run
```

Install all skills:

```bash
cranalytics install-skills --yes
```

Bundled skill names:

- `vintage-loss-curves`
- `loss-forecasting`
- `portfolio-diagnostics`
- `predictive-credit-modeling`

Install only one skill:

```bash
cranalytics install-skills --skill vintage-loss-curves
```

Control conflict behavior on reinstall:

```bash
cranalytics install-skills --conflict overwrite  # default
cranalytics install-skills --conflict skip
```

Show package and skills bundle version:

```bash
cranalytics install-skills --version
```

Why use `--dry-run`?

- Confirms which Claude skills path will be used
- Shows exactly what will be installed/updated/skipped
- Prevents accidental overwrite during validation

### 4) Pick a workflow and get one first win

Use the [workflow guide](https://github.com/ClaySheffler/cranalytics/blob/main/docs/choose_your_path.md) for narrative guidance
or the [workflow map](https://github.com/ClaySheffler/cranalytics/blob/main/docs/reference/workflow_map.md) for a
compact command/input/output matrix. Then run one workflow end-to-end and look
for its first successful output before going deeper into API details. If you are
new, prefer `cranalytics quickstart` first and treat direct demo commands as a
shortcut once you already know the right path.

### 5) Run packaged examples (works from an installed package)

```bash
python -m cranalytics.examples.core_vintage
python -m cranalytics.examples.core_lifetime_loss
python -m cranalytics.examples.core_segmentation
```

Or use the CLI:

```bash
cranalytics demo --list
cranalytics demo lifetime-loss
```

### 6) Generate a readiness report on your own rollforward data

```bash
cranalytics rollforward check your_rollforward_data.csv --output-dir rollforward_readiness_out
```

This command produces schema diagnostics, holdout forecast-vs-actual outputs,
baseline comparison metrics, and two onboarding charts to help new users
build trust before operational usage. `rollforward check` is a preflight
diagnostic. For the full monthly operating workflow, use
`cranalytics rollforward run your_rollforward_data.csv`.

### First-Time Rollforward Workflow

If you are running the Rollforward workflow for the first time:

1. Prepare aggregated monthly rollforward data with these logical fields:
   `segment_id`, `month_on_book`, `payments`, `chargeoffs`,
   `outstanding_balance`. Common aliases such as `segment`, `mob`,
   `payment`, `chargeoff`, and `balance` are accepted. For the full Rollforward
   contract and alias table, see [input_data_contracts.md](https://github.com/ClaySheffler/cranalytics/blob/main/docs/reference/input_data_contracts.md).
2. Run the preflight diagnostic:

```bash
cranalytics rollforward check your_rollforward_data.csv --output-dir rollforward_readiness_out
```

3. Run the canonical operating workflow:

```bash
cranalytics rollforward run your_rollforward_data.csv --output-dir rollforward_out
```

4. Review the main outputs in `rollforward_out/`:
   `committee_summary.md`, `champion_selection.json`,
   `variant_summary.csv`, `segment_kpis.csv`, `schema_issues.csv`, and
   `normalized_rollforward_data.csv`.


CLI note: the CLI currently reads CSV inputs. If your source data is stored as
Parquet or comes directly from a warehouse, load it into a pandas DataFrame and
use the Python API instead:

```python
from pathlib import Path
import pandas as pd
from cranalytics.rollforward import Rollforward

df = pd.read_parquet("your_rollforward_data.parquet")

result = Rollforward(df).run(
    mode="workflow",
    output_dir=Path("rollforward_out"),
    holdout_months=6,
    min_train_months=12,
    step_months=3,
)

print(result.status, result.champion)
```

## Core Workflows

### 1) Vintage Curve Fitting

```python
import numpy as np
from cranalytics.vintage import CurveFitter

mob = np.arange(1, 25)
losses = np.array([
    0.001, 0.003, 0.006, 0.010, 0.014, 0.018, 0.022, 0.026,
    0.030, 0.033, 0.036, 0.039, 0.041, 0.043, 0.045, 0.047,
    0.048, 0.049, 0.050, 0.051, 0.052, 0.052, 0.053, 0.053
])

fitter = CurveFitter(method="weibull")
fitter.fit(mob, losses)
forecast = fitter.forecast(np.arange(1, 61))
print(f"Ultimate loss rate: {fitter.ultimate_:.3%}")
```

### 2) Lifetime Loss Forecasting

```python
import pandas as pd
from cranalytics.loss_forecasting import forecast_lifetime_loss

portfolio_df = pd.DataFrame({
    "loan_id": ["L101", "L102", "L103"],
    "principal": [10000, 15000, 8000],
    "annual_rate": [0.08, 0.10, 0.09],
    "term_months": [36, 36, 24],
    "start_date": [
        pd.Timestamp("2024-01-01"),
        pd.Timestamp("2024-02-01"),
        pd.Timestamp("2024-01-15"),
    ],
    "status": ["Current", "Delinquent", "Current"],
    "fico_score": [720, 640, 700],
})

states = ["Current", "Delinquent", "Default"]
migration_matrix = pd.DataFrame(
    [[0.95, 0.04, 0.01], [0.10, 0.80, 0.10], [0.00, 0.00, 1.00]],
    index=states,
    columns=states,
)

lifetime_loss = forecast_lifetime_loss(
    portfolio_df,
    migration_matrix,
    lgd=0.55,
    as_of_date=pd.Timestamp("2024-02-01"),
)
print(f"Estimated Lifetime Loss: ${lifetime_loss:,.2f}")
```

### 3) FICO Segmentation & Portfolio Diagnostics

```python
import pandas as pd
from cranalytics.portfolio import calculate_fico_mix, calculate_lgd, segment_fico

df = pd.DataFrame({
    "loan_id": [1, 2, 3],
    "fico_score": [780, 650, 590],
    "principal": [10000.0, 15000.0, 8000.0],
    "collateral_value": [7000.0, 4000.0, 0.0],
    "collateral_type": ["Vehicle", "Cash", "Unsecured"],
})

segmented = segment_fico(df)
print(segmented[["fico_score", "fico_band", "risk_grade"]])

mix = calculate_fico_mix(segmented)
print(mix)

lgd = calculate_lgd(df)
print(lgd)
```

### 4) Credit Risk Feature Analytics

Engineer ML-ready features from raw loan data and assess predictive power before training.

```python
import pandas as pd

from cranalytics.feature_analytics import (
    engineer_loan_features,
    fit_woe_binning,
    lift_gain_table,
    rank_features_by_separation,
)

ref_date = pd.Timestamp("2025-12-31")
train = engineer_loan_features(train_df, as_of_date=ref_date)

# Rank features by IV / Gini / KS before committing to model
ranking = rank_features_by_separation(train, feature_cols=feature_cols, flag_col="fpf60")

# Optimal WoE binning (optional external dependency: optbinning)
process = fit_woe_binning(train, feature_cols=feature_cols, target_col="fpf60")
X_woe = process.transform(train[feature_cols], metric="woe")
```

### 5) ML Modeling — Binary Loan Performance Flags

Thin wrappers over sklearn/xgboost for the full lending model lifecycle: target construction, temporal backtesting, scoring, and bridging loan-level predictions to calendar-month charge-off dollars.

```python
from cranalytics.predictive import (
    build_targets,
    forecast_calendar_chargeoff_from_predictions,
    run_predictive_backtest,
    score_model,
    train_binary_model,
)

# Derive targets from monthly performance panel
targets = build_targets(panel_df, mode="panel", targets=["fpf30_flag", "dq30_mob6_flag"])

# Train with temporal OOT validation
backtest = run_predictive_backtest(
    df, feature_cols, target_col="fpf30_flag",
    split_col="origination_month", model_family="hgb_classifier",
)

# Train final model and score active book
estimator, metadata, diagnostics = train_binary_model(
    train_df, feature_cols, target_col="fpf30_flag", model_family="logistic"
)
scored = score_model(active_df, estimator, feature_cols, output_col="fpf30_prob")

# Bridge to calendar charge-off dollars
forecast = forecast_calendar_chargeoff_from_predictions(scored, hazard_curves=curves)
```

## Input Requirements (Lifetime Loss)

For onboarding, the minimum portfolio shape is `loan_id`, `principal`,
`annual_rate`, `term_months`, `start_date`, and `status`, plus transition input
in one of three shapes:

- a square transition matrix whose rows and columns share the same states
- a transition ledger with `loan_id`, `period`, and `status`
- a loan history panel with `loan_id`, `fund_date`, and `as_of_date`

See [input_data_contracts.md](https://github.com/ClaySheffler/cranalytics/blob/main/docs/reference/input_data_contracts.md) for the full portfolio contract,
accepted `status` values, numeric ranges, and transition-input rules.

## Advanced Modules

- `cranalytics.vintage`: smoothing and model comparison utilities
- `cranalytics.viz`: plotly/matplotlib visualizations
- `cranalytics.survival`: Kaplan-Meier/Cox/competing risks

Visualization and survival dependencies are included in the base install.

For smoothing and validation utilities, strict behavior is default. Use `strict=False` in comparison and validation helpers for best-effort fallback behavior.

## Examples

### Packaged Demos

The following examples are included in the package and can be run directly after installation:

```bash
# Basic vintage analysis and curve fitting
python -m cranalytics.examples.core_vintage

# Lifetime loss forecasting with transition inputs
python -m cranalytics.examples.core_lifetime_loss

# Portfolio segmentation and mix analysis
python -m cranalytics.examples.core_segmentation

# Survival analysis (Kaplan-Meier and Cox PH)
python -m cranalytics.examples.core_survival
```

You can also use the CLI to discover and run demos:

```bash
cranalytics demo --list
cranalytics demo vintage
cranalytics demo lifetime-loss
cranalytics demo segmentation
cranalytics demo survival
```

### Advanced Examples

For more complex workflows, see the [`examples/`](https://github.com/ClaySheffler/cranalytics/tree/main/examples) directory in the repository:

- [lendingclub_full_pipeline.py](https://github.com/ClaySheffler/cranalytics/blob/main/examples/lendingclub_full_pipeline.py) — End-to-end pipeline on 35k LendingClub loans: FICO segmentation, LGD, vintage curves, survival analysis, loss forecasting, and simulation.
- [streamlit-demos/](https://github.com/ClaySheffler/cranalytics/tree/main/examples/streamlit-demos) — Interactive Streamlit dashboard for portfolio diagnostics.

## Documentation

Full docs live in the [docs/](https://github.com/ClaySheffler/cranalytics/tree/main/docs) directory on GitHub.
- Deployment target: Vercel (configured via `vercel.json`)

- [Getting started](https://github.com/ClaySheffler/cranalytics/blob/main/docs/getting_started.md)
- [Choose your path](https://github.com/ClaySheffler/cranalytics/blob/main/docs/choose_your_path.md)
- [Lifetime loss tutorial](https://github.com/ClaySheffler/cranalytics/blob/main/docs/tutorials/lifetime_loss_forecasting.md)
- [FICO segmentation tutorial](https://github.com/ClaySheffler/cranalytics/blob/main/docs/tutorials/fico_segmentation.md)
- [Feature analytics tutorial](https://github.com/ClaySheffler/cranalytics/blob/main/docs/tutorials/feature_analytics.md)
- [ML modeling tutorial](https://github.com/ClaySheffler/cranalytics/blob/main/docs/tutorials/ml_modeling.md)
- [Claude skills guide](https://github.com/ClaySheffler/cranalytics/blob/main/docs/tutorials/claude_skills_getting_started.md)
- [API reference](https://github.com/ClaySheffler/cranalytics/tree/main/docs/api)

## Development

Run tests:

```bash
python -m pytest
```

## License

MIT (see `LICENSE`).
