Credit events
This page lists what a credit event does to an index CDS or a CDO tranche: the function that applies it, its arguments, the settlement it returns, and an example you can run. A credit event, such as a default, triggers settlement on every contract referencing the name; why an index is re-versioned and a tranche erodes from the bottom is covered in how credit products work.
Quick example
The example reads its close date from the desk sheets; load them once and it runs as shown.
This applies one default to a CDX.NA.IG position on ten million: a name of weight 0.8% recovering 35% at auction on 16 November 2026. It settles the index position, then the same event on the 0–3% equity tranche of the same pool.
use chrono::NaiveDate;
use helixio_docs_sheets::SOFR_CLOSE_DATE;
use helixrs::{CdoTranche, CreditEvent, CreditIndexFamily, IndexCreditDefaultSwap};
type Outcome<T> = Result<T, Box<dyn std::error::Error>>;
fn date((year, month, day): (i32, u32, u32)) -> NaiveDate {
NaiveDate::from_ymd_opt(year, month, day).expect("a real calendar date")
}
const NOTIONAL: f64 = 10_000_000.0;
const WEIGHT: f64 = 0.008;
const AUCTION: f64 = 0.35;
fn main() -> Outcome<()> {
let close = date(SOFR_CLOSE_DATE);
let family = "CDX.NA.IG".parse::<CreditIndexFamily>()?.template();
let series = family.on_the_run(close);
let event = CreditEvent {
entity: "ACME".to_owned(),
weight: WEIGHT,
auction_recovery: AUCTION,
event_date: date((2026, 11, 16)),
};
let index = IndexCreditDefaultSwap::standard(&family, close, series, 5, NOTIONAL, true).with_version(1);
let (_, settled) = index.after_credit_event(&event)?;
println!("protection {:.2}", settled.protection);
println!("accrued {:.2}", settled.accrued);
// The equity tranche absorbs the loss; its points are restated on the
// surviving pool.
let equity = CdoTranche::standard(&family, close, series, 5, NOTIONAL, 0.0, 0.03, 0.05, true)?;
let (_, eroded) = equity.after_credit_event(&event)?;
let loss = WEIGHT * (1.0 - AUCTION);
println!("pool loss {loss:.6}");
println!("protection {:.2}", eroded.protection);
println!("detach {:.6}", eroded.detach);
Ok(())
}import datetime as dt
import helixio as hlx
from desk_sheets import SOFR_CLOSE_DATE
FAMILY, NOTIONAL = "CDX.NA.IG", 10_000_000.0
WEIGHT, AUCTION, EVENT = 0.008, 0.35, dt.date(2026, 11, 16)
series = hlx.credit.on_the_run(FAMILY, SOFR_CLOSE_DATE)
index = hlx.products.index_credit_default_swap(FAMILY, SOFR_CLOSE_DATE, series, 5, notional=NOTIONAL)
_, settled = hlx.credit.after_credit_event(index, "ACME", WEIGHT, AUCTION, EVENT)
print(f"protection {settled.protection():.2f}")
print(f"accrued {settled.accrued():.2f}")
# The equity tranche absorbs the loss; its points are restated on the
# surviving pool.
equity = hlx.products.cdo_tranche(
FAMILY, SOFR_CLOSE_DATE, series, 5, pool_notional=NOTIONAL, attach=0.0, detach=0.03, spread=0.05
)
_, eroded = hlx.credit.after_credit_event(equity, "ACME", WEIGHT, AUCTION, EVENT)
loss = WEIGHT * (1.0 - AUCTION)
print(f"pool loss {loss:.6f}")
print(f"protection {eroded.protection():.2f}")
print(f"detach {eroded.detach():.6f}")protection 52000.00
accrued -124.44
pool loss 0.005200
protection 52000.00
detach 0.025000
The index holder receives the name's loss and pays the premium accrued on its weight. The equity tranche absorbs the same loss, and its detachment point, restated on the surviving pool, moves down from 3%.
How it's priced
On notional , a name of weight recovering at settles protection of
with the premium accrued on since the last coupon netted against it. The pool loses of its notional and of its names. For an equity tranche with attachment and detachment , the new detachment on the surviving pool is
API
credit.after_credit_event(instrument, entity, weight, auction_recovery, event_date) returns the
contract after the event and what it settles.
| Argument | Type | Default | Meaning |
|---|---|---|---|
instrument |
Instrument |
required | an index CDS or a CDO tranche |
entity |
str |
required | the defaulted name |
weight |
float |
required | the name's weight in the pool, as a decimal |
auction_recovery |
float |
required | the recovery the auction fixed |
event_date |
date |
required | the date of the event; premium accrues to it |
On an index CDS the settlement is an IndexSettlement, with protection() and accrued(), signed
to the holder, plus entity() and event_date(). On a tranche it is a TrancheSettlement, which
adds write_down(), the recovered amount written off the top, and attach() and detach(), the
tranche's points on the surviving pool. In Rust each contract has an after_credit_event method
taking a CreditEvent.
| Symbol | Meaning | Rust | Python |
|---|---|---|---|
| the event | name, weight, recovery, date | CreditEvent { entity, weight, auction_recovery, event_date } |
the arguments of credit.after_credit_event |
| on an index | re-versioned index and its settlement | IndexCreditDefaultSwap::after_credit_event |
credit.after_credit_event |
| on a tranche | eroded tranche and its settlement | CdoTranche::after_credit_event |
credit.after_credit_event |
| protection settled | IndexSettlement::protection |
IndexSettlement.protection() |
|
| the tranche's new detachment | TrancheSettlement::detach |
TrancheSettlement.detach() |
Defaults and limits
- The new version: the index comes back on its next version, such as
CDX.NA.IG.47v2, with its factor reduced by the name's weight. A market values it on the curve pinned under that version. - Write-downs: only the most senior tranche records a write-down; every other tranche's
write_down()is zero. - Signs: every settled amount is signed to the holder, so the protection a buyer receives is positive and the accrued premium it pays is negative.
- Auction terms follow the credit conventions catalog.
See also
- Source:
crates/helixrs/src/instruments/credit.rs - Related pages:
- How credit products work, the ideas behind settlement.
- Index CDS, for the series and its version.
- CDO tranche, for the tranche before the event.
From the 0.0 line at revision bf7f2e2. Every printed number is that revision's own output.