Metadata-Version: 2.4
Name: cranalytics
Version: 0.2.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: 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

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
```

Latest preview release from TestPyPI:

Current preview builds are published to TestPyPI. Use the TestPyPI index for
`cranalytics` and keep PyPI as the fallback source for dependencies.

```bash
uv pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple cranalytics
# or: python -m pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple cranalytics
```

Project page:

- https://test.pypi.org/project/cranalytics/

Stable install from PyPI:

Keep the standard install path separate. Once a production release is published
to PyPI, these should remain the default commands.

```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 [`docs/choose_your_path.md`](docs/choose_your_path.md) and [`docs/reference/workflow_map.md`](docs/reference/workflow_map.md) to find the right workflow.

Hosted docs:

- Deployment target: Vercel
- Repo-owned deploy contract: `vercel.json`

- 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-readiness your_rollforward_data.csv --output-dir rollforward_readiness_out`

- Learn Workflow 4 with the tutorial: [`docs/tutorials/feature_analytics.md`](docs/tutorials/feature_analytics.md)
- Learn Workflow 5 with the tutorial: [`docs/tutorials/ml_modeling.md`](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-readiness 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 [`docs/choose_your_path.md`](docs/choose_your_path.md) for narrative guidance
or [`docs/reference/workflow_map.md`](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-readiness 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-readiness` is a preflight
diagnostic. For the full monthly operating workflow, use
`cranalytics rollforward-workflow <input.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, use `docs/reference/input_data_contracts.md`.
2. Run the preflight diagnostic:

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

3. Run the canonical operating workflow:

```bash
cranalytics rollforward-workflow 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`.

Legacy CLI aliases remain supported.

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_workflow import run_rollforward_workflow

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

result = run_rollforward_workflow(
    df,
    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.early_performance import rank_features_by_separation
from cranalytics.model_development import (
    engineer_loan_features,
    fit_woe_binning,
    lift_gain_table,
)

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.forecasting_bridge import forecast_calendar_chargeoff_from_predictions
from cranalytics.predictive_backtest import run_predictive_backtest
from cranalytics.predictive_modeling import score_model, train_binary_model
from cranalytics.predictive_targets import build_targets

# 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`

Use `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/` directory in the repository:

- `examples/lendingclub_full_pipeline.py` — End-to-end pipeline on 35k LendingClub loans: FICO segmentation, LGD, vintage curves, survival analysis, loss forecasting, and simulation.
- `examples/streamlit-demos/` — Interactive Streamlit dashboard for portfolio diagnostics.

## Documentation

- Hosted docs deployment target: Vercel
- Deploy contract: `vercel.json`
- Docs index: `docs/index.md`
- Choose your path: `docs/choose_your_path.md`
- Getting started: `docs/getting_started.md`
- Lifetime loss tutorial: `docs/tutorials/lifetime_loss_forecasting.md`
- FICO segmentation tutorial: `docs/tutorials/fico_segmentation.md`
- Claude skills guide: `docs/tutorials/claude_skills_getting_started.md`
- API reference: `docs/api/core.md`, `docs/api/engine.md`, `docs/api/predictive.md`, `docs/api/rollforward.md`

## Development

Run tests:

```bash
python -m pytest
```

## License

MIT (see `LICENSE`).
