Skip to content

junsier9/QF609-Project-Risk_Analysis

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

QF609 AY2025-2026 Group Project

IRRBB (Basel) for Non-Maturity Deposits (NMD)

Project Purpose

This project develops an end-to-end Python research pipeline to measure Interest Rate Risk in the Banking Book (IRRBB) for a Non-Maturity Deposit cohort under Basel-style assumptions.

Using data up to 31-Dec-2023, the framework estimates behavioural maturity (deposit decay), applies regulatory slotting constraints (including the 5-year cap), and quantifies risk through scenario-based ΔEVE and ΔNII (1-year horizon) measures.

Research Workflow

The implementation follows a transparent research process:

  1. Data ingestion and quality checks

    • Load historical NMD balance, inflow, and outflow data.
    • Parse and normalize curve tenors/rates.
    • Diagnose accounting identity consistency: (Balance_t \approx Balance_{t-1} + Inflow_t - Outflow_t).
  2. Behavioural modelling for NMD

    • Build a retention/decay profile from cohort-level balance flow behaviour.
    • Fit a mixture-exponential survival representation.
    • Convert survival to monthly runoff weights and enforce Basel 5-year cap.
  3. Basel slotting and repricing profile construction

    • Use calculation-date balance as the notional base.
    • Allocate behavioural balances into monthly repricing buckets.
    • Validate that slotted totals reconcile to the starting balance.
  4. Curve and shock scenario design

    • Build a base zero-curve object with tenor interpolation.
    • Apply four supervisory-style rate shocks:
      • parallel_up
      • parallel_down
      • short_up_taper
      • flattener
  5. Risk computation and reporting

    • Revalue slotting cashflows for EVE under base and shocked curves.
    • Estimate NII sensitivity (1Y window) using repricing buckets.
    • Export scenario results and identify worst-case ΔEVE and ΔNII.

Inputs

Place data files in data/:

  • group-proj-1-data.xlsx (required)
    • Columns: Date, Balance, Inflow, Outflow (Netflow optional)
  • group-proj-1-curve.xlsx (required)
    • Columns: Tenor, ZeroRate
  • group-proj-1-demo.xlsx (optional reference)

If Excel inputs are unavailable, the project falls back to committed samples:

  • data/sample_data.csv
  • data/sample_curve.csv

Outputs

Running the pipeline writes artifacts to outputs/:

  • decay_profile.csv
  • slotting_table.csv
  • scenario_results.csv
  • worst_case.json
  • plot_decay.png
  • plot_slotting.png
  • plot_scenarios.png

Repository Structure

.
├─ data/
│  ├─ group-proj-1-data.xlsx              (manually provided, not committed)
│  ├─ group-proj-1-curve.xlsx             (manually provided, not committed)
│  ├─ group-proj-1-demo.xlsx              (optional reference, not committed)
│  ├─ sample_data.csv                     (development/testing fallback)
│  └─ sample_curve.csv                    (development/testing fallback)
├─ notebooks/
│  ├─ 01_eda_decay.ipynb                  (exploration and diagnostics)
│  └─ 02_results_plots.ipynb              (figures and tables)
├─ src/
│  ├─ io/
│  │  ├─ loaders.py                       # load Excel/CSV and normalize tenor units
│  │  └─ validators.py                    # balance identity diagnostics
│  ├─ nmd/
│  │  ├─ preprocess.py                    # feature engineering for NMD behaviour
│  │  ├─ decay_model.py                   # mixture-exponential survival modelling
│  │  ├─ basel_slotting.py                # core split, 5Y cap, bucket allocation
│  │  └─ repricing_profile.py             # repricing table outputs
│  ├─ curve/
│  │  ├─ curve.py                         # zero-curve object and interpolation
│  │  └─ shocks.py                        # scenario shock generators
│  ├─ irrbb/
│  │  ├─ eve.py                           # PV and ΔEVE calculations
│  │  ├─ nii.py                           # 1Y-window ΔNII calculations
│  │  └─ report.py                        # worst-case aggregation and exports
│  └─ config.py                           # model and scenario configuration
├─ run.py                                 # one-command pipeline execution
└─ README.md

Environment Setup

Use Python 3.10+.

Install dependencies:

pip install -r requirements.txt

Run the project:

python -m src.run

Notes on Modelling Choices

  • Tenors support D/W/M/Y suffixes and are normalized to year units.
  • Zero rates are normalized if expressed in percentage format.
  • Curve interpolation is linear in (tenor_years, zero_rate) space.
  • Discounting uses continuous compounding for EVE calculations.
  • NII is computed over a one-year horizon using bucket repricing approximation.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors