Financial Stress Composite
Integrates credit spreads, yield-curve inversion, and systemic stress to assess market stress levels.
Abstract
The Financial Stress Composite blends three independent indicators of 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. A robust z‑scored average yields a continuous composite regime indicator: High_Stress, Neutral, or Low_Stress.
1. Data
- STLFSI4 — St. Louis Fed Financial Stress Index (weekly, FRED).
- HY_OAS — ICE BofA U.S. High‑Yield Option‑Adjusted Spread (daily/monthly, FRED).
- T10Y2Y — 10‑Year minus 2‑Year Treasury Yield Spread (daily, FRED).
Resample all inputs to a common monthly frequency (month‑end).
2. Transformation
Because stress increases with higher STLFSI4 and HY spreads but decreases with a steeper yield curve, we invert the curve slope:
Stress\_Curve_t = −T10Y2Y_t
This makes positive z‑scores represent more inversion, hence higher stress.
3. Normalisation
z\_{rob}(X)_t = \dfrac{X_t − \mathrm{median}(X)_{t,w}}{1.4826·\mathrm{MAD}(X)_{t,w}}
with rolling window w = 60 months (minimum 24). Median absolute deviation scaling reduces outlier bias.
4. Composite Construction
Fin\_{Stress,t} = \tfrac{1}{3}\big(z(STLFSI4_t) + z(HY\_OAS_t) + z(−T10Y2Y_t)\big)
5. Regime Mapping
If\ C_t > 0.75 → High\_Stress;\quad |C_t| ≤ 0.75 → Neutral;\quad C_t < −0.75 → Low\_Stress
6. 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)
w = max(min_win, min(win, x.dropna().size))
med = x.rolling(w, min_periods=min_win).median()
mad = (x - med).abs().rolling(w, min_periods=min_win).median()
return (x - med) / (1.4826 * mad.replace(0, np.nan))
f = df_fin_stress.copy()
f["Z_STL"] = robust_z(f["STLFSI4"])
f["Z_HY"] = robust_z(f["HY_OAS"])
f["Z_INV"] = robust_z(-f["T10Y2Y"])
f["Fin_Stress"] = f[["Z_STL","Z_HY","Z_INV"]].mean(axis=1)
hi, lo = 0.75, -0.75
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
display(df_sig_fin_stress.tail())
7. Interpretation
- High_Stress: systemic tension; liquidity constraints likely, risk aversion elevated.
- Neutral: normal functioning of credit and funding markets.
- Low_Stress: ample liquidity, tight spreads, positive credit conditions.
8. Limitations
- HY spreads and curve inversions may overlap conceptually; equal weighting assumes orthogonality.
- STLFSI4 already incorporates many inputs; overlapping signals can double‑count certain dynamics.
- Fixed thresholds (±0.75) may understate stress in high‑volatility regimes; adaptive thresholds recommended for trading use.