Financial Stress Composite

Integrates broad financial-stress conditions, credit spreads, and the yield-curve slope to assess market stress levels.
Last updated: February 10, 2026

Abstract

The Financial Stress Composite blends three independent indicators of U.S. financial strain: the St. Louis Fed Financial Stress Index (STLFSI4), high-yield option-adjusted spreads (HY OAS), and the yield-curve slope (T10Y2Y). Higher stress corresponds to elevated STLFSI4, wider credit spreads, and deeper yield-curve inversion. Inputs are transformed to a common direction, robustly normalised using rolling median/MAD z-scores, and aggregated into a continuous composite that maps to High_Stress, Neutral, or Low_Stress.

1. Data

All inputs are sourced from FRED and resampled to month-end for consistent cross-signal comparison. Where a series is higher-frequency (daily/weekly), month-end uses the last available observation in the month.

1.1 STLFSI4 — St. Louis Fed Financial Stress Index (weekly)
  • Source: FRED series STLFSI4.
  • What it captures: a broad, multi-market measure of stress spanning funding, credit, and equity-related indicators.
  • Composition note: STLFSI4 is itself a composite; it incorporates multiple spreads and market variables (including measures related to volatility and funding spreads).
  • Practical implication: STLFSI4 can “carry” VIX/TED-like information indirectly, so overlap/double-counting is possible when adding external spread measures.
1.2 HY OAS — ICE BofA U.S. High Yield Option-Adjusted Spread (daily)
  • Source: FRED series BAMLH0A0HYM2.
  • What it captures: compensation for default/liquidity risk in below-investment-grade U.S. corporate bonds, net of embedded options (option-adjusted).
  • Why it matters: widening OAS typically coincides with tighter financial conditions and higher risk premia.
1.3 T10Y2Y — 10-Year minus 2-Year Treasury Yield Spread (daily)
  • Source: FRED series T10Y2Y.
  • What it captures: a term-spread proxy for growth and policy expectations; persistent inversion is historically associated with tighter conditions and elevated recession risk.
  • Directionality: for “stress” interpretation we invert the slope so that more inversion contributes positively to stress.

2. Transformation

Stress rises with higher STLFSI4 and wider HY OAS, but tends to rise as the curve becomes more inverted. To align directions, invert the slope:

Stress_Curve_t = −T10Y2Y_t

This makes higher values indicate more inversion and therefore higher “stress contribution.”

3. Normalisation

Each component is transformed into a robust rolling z-score to reduce outlier sensitivity.

z_{rob}(X)_t = (X_t − median(X)_{t,w}) / (1.4826·MAD(X)_{t,w})
Rolling window w = 60 months (minimum 24). MAD scaling reduces outlier bias and improves robustness in crisis tails.

4. Composite construction

The v1.0 composite used equal weights. In v1.1, the default remains equal-weight, but the framework supports regime-aware dynamic weights (Section 7–8).

C_t = w_{STL,t}·z(STLFSI4_t) + w_{HY,t}·z(HY_OAS_t) + w_{INV,t}·z(−T10Y2Y_t),  with  w_{i,t} ≥ 0,  Σ_i w_{i,t}=1

Default: w_{STL,t}=w_{HY,t}=w_{INV,t}=1/3.

5. Regime mapping

If C_t > 0.75 → High_Stress;  |C_t| ≤ 0.75 → Neutral;  C_t < −0.75 → Low_Stress

Thresholds are intentionally coarse to emphasise regime classification over point forecasts.

6. Data freshness, staleness, and quality flags (v1.1)

Some underlying market series can be stale around holidays, data outages, or vendor delays. Because STLFSI4 is itself a composite that may embed volatility (VIX-like) and funding-spread (TED-like) inputs, staleness can propagate into the composite.

Recommended reporting fields
  • AsOfDate_i: last observation date used for each component at month-end.
  • StaleFlag_i: 1 if AsOfDate_i is older than a chosen tolerance (e.g., 5 trading days) at evaluation time.
  • CompositeConfidence: “High” if no stale components; otherwise “Medium/Low” depending on count and importance.

These flags do not change the historical values; they contextualise reliability of the latest print.

7. Sub-component contributions (v1.1)

To reduce interpretability gaps, publish each component’s contribution to the composite:

Contrib_{i,t} = w_{i,t} · z_i,t

This makes it explicit whether “stress” is being driven by credit, the yield curve, or broad multi-market strain.

8. Dynamic weighting by market regime (v1.1)

v1.1 introduces an optional regime-aware weighting overlay intended to reduce double-counting and improve robustness when one pillar dominates. The objective is not optimisation, but sensible re-weighting when stress is clearly credit- driven vs curve-driven.

Simple, fully FRED-based rule (example)
  • High-stress months: if C_{t-1} > 0.75, increase weight on STLFSI4 and HY OAS, reduce inversion weight (e.g., w_STL=0.40, w_HY=0.40, w_INV=0.20).
  • Low-stress months: if C_{t-1} < -0.75, revert to equal weights (or modestly increase inversion weight if desired).
  • Neutral: use equal weights.

If you prefer a data-driven scheme, an alternative is to set w_{i,t} inversely proportional to each component’s rolling correlation with STLFSI4 (to downweight overlap) while keeping weights bounded (e.g., 0.2–0.5).

9. Implementation (Python)

import pandas as pd
import numpy as np

def robust_z(s, win=60, min_win=24):
    x = pd.to_numeric(s, errors="coerce").astype(float)
    med = x.rolling(win, min_periods=min_win).median()
    mad = (x - med).abs().rolling(win, min_periods=min_win).median()
    return (x - med) / (1.4826 * mad.replace(0, np.nan))

# Expect inputs: STLFSI4 (weekly), BAMLH0A0HYM2 (daily), T10Y2Y (daily)
# All resampled to month-end before applying robust_z.
f = df_fin_stress.copy()

# Transformations
f["Z_STL"] = robust_z(f["STLFSI4"])
f["Z_HY"]  = robust_z(f["HY_OAS"])
f["Z_INV"] = robust_z(-f["T10Y2Y"])   # inversion-aligned

# Default equal weights
w_eq = {"STL": 1/3, "HY": 1/3, "INV": 1/3}

# Optional regime-aware weights (simple example using lagged composite)
hi, lo = 0.75, -0.75
w_hi = {"STL": 0.40, "HY": 0.40, "INV": 0.20}

# First pass composite (equal-weight) to define the lagged regime
f["C_eq"] = (w_eq["STL"]*f["Z_STL"] + w_eq["HY"]*f["Z_HY"] + w_eq["INV"]*f["Z_INV"])

def weights_for_row(c_lag):
    if pd.isna(c_lag):
        return w_eq
    if c_lag > hi:
        return w_hi
    return w_eq

w_stl, w_hy, w_inv = [], [], []
for c_lag in f["C_eq"].shift(1):
    w = weights_for_row(c_lag)
    w_stl.append(w["STL"]); w_hy.append(w["HY"]); w_inv.append(w["INV"])

f["W_STL"], f["W_HY"], f["W_INV"] = w_stl, w_hy, w_inv

# Final composite and contributions
f["Fin_Stress"] = f["W_STL"]*f["Z_STL"] + f["W_HY"]*f["Z_HY"] + f["W_INV"]*f["Z_INV"]
f["Contrib_STL"] = f["W_STL"]*f["Z_STL"]
f["Contrib_HY"]  = f["W_HY"]*f["Z_HY"]
f["Contrib_INV"] = f["W_INV"]*f["Z_INV"]

def regime(v):
    if pd.isna(v):
        return np.nan
    return "High_Stress" if v > hi else ("Low_Stress" if v < lo else "Neutral")

f["Fin_Stress_Regime"] = f["Fin_Stress"].apply(regime)

df_sig_fin_stress = f

10. Interpretation (how to read the signal)

10.1 What the composite is (and is not)
  • It is: a standardised summary of stress across (i) broad multi-market strain (STLFSI4), (ii) corporate credit risk premia (HY OAS), and (iii) curve inversion pressure (−T10Y2Y).
  • It is not: a standalone recession model, nor a precise timing tool. Use it to contextualise regime risk and the “channel” of stress.
10.2 Regime meanings
  • High_Stress: stress is materially above its own long-run distribution. Historically consistent with tightened funding/credit conditions, elevated volatility, and lower risk appetite. Focus on which contribution dominates (credit vs curve vs broad stress).
  • Neutral: conditions are near historical norms. Day-to-day market moves may be noisy; watch for persistence and contribution shifts.
  • Low_Stress: broad conditions are accommodative: tighter spreads, less inversion pressure, and subdued multi-market strain.
10.3 Component-level reading
  • HY OAS dominates: “credit-led stress” (risk premia, default/liquidity concerns). This channel is closely linked to the macro cycle and risk appetite.
  • Inversion dominates: “policy/growth expectations-led stress” (tight front-end policy vs longer-run growth/inflation expectations).
  • STLFSI4 dominates: “system-wide stress” spanning multiple markets (funding, volatility, cross-asset dislocations).
  • Stale flags: treat the latest composite print with caution if one or more components are stale; rely more on the non-stale contributions.

Academic and policy literature supports the core components: the term spread is a widely used leading indicator for recession risk and policy stance, credit spreads contain information about risk premia and predict real activity, and financial-stress indices aggregate cross-market strains into a single stress gauge.

11. Limitations

12. References (interpretation anchors)