Repository files navigation

U.S. Recession Probability Model — 12-Month Ahead

License: MITPython 3.8+Open In ColabGitHub starsWeekly Report

A five-model ensemble that estimates the probability of a U.S. recession occurring within the next 12 months, using 37 FRED indicators across eight macroeconomic categories. Generates an automated weekly investment committee briefing with embedded charts via Claude API.

Built on the academic framework established by Estrella and Mishkin (1996, 1998) and currently used by the New York Fed and Cleveland Fed.


What This Does

Every Monday morning, a GitHub Actions pipeline:

  1. Pulls the latest data from the Federal Reserve's FRED database (37 indicators)
  2. Runs a probit regression with BIC-based feature selection and economic sign constraints
  3. Computes a five-model ensemble probability with bootstrap confidence intervals
  4. Generates 7 charts covering probability trends, indicator dashboards, model comparison, sensitivity triggers, and historical context
  5. Sends Claude API the model output + charts, which writes a structured investment committee memo
  6. Delivers the memo via email with all charts embedded inline

The ensemble averages across five methodologically distinct models: NY Fed spread-only, Wright two-factor, BIC-selected multivariate, Estrella-Mishkin closed-form, and Chauvet-Piger Markov-switching.


Quick Start

Option A: Google Colab (interactive exploration)

  1. Open Recession_Probability_Model.ipynb in Google Colab
  2. Get a free FRED API key at https://fred.stlouisfed.org/docs/api/fred/
  3. Run all cells — handles installation, data fetching, modeling, and visualization

Option B: Automated weekly reports (fork and deploy)

  1. Fork this repository

  2. Add GitHub Secrets (Settings > Secrets and variables > Actions):

    SecretRequiredDescription
    FRED_API_KEYYesFree key from https://fred.stlouisfed.org/docs/api/fred/
    ANTHROPIC_API_KEYYesClaude API key from https://console.anthropic.com/
    MAIL_USERNAMENoGmail address for sending reports
    MAIL_PASSWORDNoGmail app password (from https://myaccount.google.com/apppasswords)
    MAIL_PORTNoSMTP port, typically 587
    EMAIL_TONoRecipient email(s), comma-separated
  3. Enable the workflow: Actions tab > "Weekly Recession Probability Report" > Enable

  4. Test: Click "Run workflow" to trigger immediately

Without Gmail credentials, the email report is saved as an HTML file in the workflow artifacts.

Option C: Run locally

git clone https://github.com/SecondOrderEdge/Recession_Probability_Model.git
cd Recession_Probability_Model
pip install -r requirements.txt
export FRED_API_KEY="your-key"export ANTHROPIC_API_KEY="your-key"
python automation/daily_report.py # Fetch data, run model, generate charts
python automation/generate_email.py # Generate email via Claude API

Output files are written to automation/output/.


How It Works

The Probit Framework

The core statistical model is a probit regression:

P(Recession_{t+12} = 1 | X_t) = Phi(a_0 + a_1 * X_t)

where Phi(.) is the standard normal CDF, X_t is a vector of economic indicators observed at time t, and the forecast horizon is 12 months. The probit maps a linear combination of indicators into a probability bounded between 0 and 1, connecting naturally to latent-variable models where an unobserved "economic health" index crosses a threshold during recessions.

Five-Model Ensemble

Rather than relying on any single specification, the headline probability is an equal-weighted average of five methodologically distinct models:

ModelFeaturesMethodologyReference
NY Fed BaselineYield curve spread onlyRe-estimated probitEstrella & Mishkin (1998)
Wright ExtensionSpread + Federal Funds RateRe-estimated probitWright (2006)
BIC-SelectedData-driven optimal setRe-estimated probit with sign constraintsForward stepwise BIC
Estrella-MishkinYield curve spreadClosed-form with 2006 parametersEstrella & Trubin (2006)
Chauvet-PigerMarkov-switching modelIndependent FRED series (RECPROUSM156N)Chauvet & Piger

This diversifies across model complexity (1 variable to 7+), estimation approach (re-estimated vs. frozen parameters vs. Markov-switching), and the fundamental question of whether the yield curve alone is sufficient or multi-factor models add value.

Feature Selection: BIC with Sign Constraints

Recessions are rare (~15% of months since 1967). With 30+ candidate features and only ~6 recession episodes in the sample, overfitting is the primary risk. The model uses forward stepwise BIC selection with three safeguards:

  1. BIC penalty: Penalizes complexity more aggressively than AIC, enforcing the parsimony that Berge (2014) showed dominates at the 12-month horizon
  2. Separation detection: Rejects any feature combination that produces quasi-complete separation (coefficients > 100, nan standard errors, or pseudo R-squared > 0.99)
  3. Economic sign constraints: Ensures coefficients align with theory before accepting a candidate:
IndicatorRequired SignEconomic Logic
SPREADNegativeLower spread = higher recession risk
UNRATE_CHG3PositiveRising unemployment = higher recession risk
UMCSENTNegativeLower sentiment = higher recession risk
BUSLOANS_YOYNegativeCredit contraction = higher recession risk

If no valid combination passes all three checks, the model falls back to the Wright two-variable specification (spread + fed funds rate).

Dependent Variable Construction

The dependent variable is configurable:

  • Point-in-time ("point"): y_t = 1 if in recession at month t+12. Used by the NY Fed.
  • Any-in-window ("window"): y_t = 1 if recession occurs at any point during months t+1 through t+12. Produces higher, more persistent probabilities.

The Boston Fed (2020) documented "considerable dispersion" between these approaches. The notebook compares both side-by-side.

Variable Transformations

Transforms are metadata-driven via the SERIES_CONFIG dictionary:

  • Year-over-year percent change ("yoy"): For non-stationary level series (INDPRO, CPI, Housing Starts, Payrolls). Removes trend, preserves cyclical signal.
  • Levels ("level"): For stationary/bounded series (spreads, rates, normalized indexes).
  • Derived features: SPREAD (= GS10 - TB3MS) for pre-1982 monthly history; UNRATE_CHG3 for Sahm-style unemployment momentum.

Estimation: Expanding Windows

Uses expanding-window (not rolling) estimation because recessions are too rare for rolling windows to produce stable estimates. Minimum training window: 120 months (10 years). Each month's probability is generated from a model trained only on data available at that point — no lookahead bias.

Robustness Checks

The notebook includes five robustness checks:

  1. Bootstrap 90% CI — 1,000 resamples to quantify uncertainty around the point estimate
  2. Leave-one-recession-out — Trains on all recessions except one, tests detection on the held-out episode
  3. Penalized probit — L2-regularized logistic regression to verify quasi-separation isn't distorting estimates
  4. Model consensus — Measures agreement across all five specifications
  5. Sensitivity triggers — Binary search for the exact indicator value that would push probability to 30% or 50%

Trend Attribution

The weekly report decomposes the 24-month probability change into per-indicator contributions using partial effects (coefficient x change in variable x normal PDF at the current linear index). This identifies which indicators are driving the probability up or down.


Data Universe — 37 FRED Series Across 8 Categories

CategorySeriesTransform
National ActivityCFNAI, CFNAIMA3, GDPC1, USSLINDLevel / YoY
IndustrialINDPRO, BSCICP02USM460S (OECD Mfg Confidence), TCU, DGORDER, IPMANYoY / Level
ConsumerUMCSENT, PCECC96, DSPIC96, RSAFSLevel / YoY
Labor MarketUNRATE, ICSA, PAYEMS, JTSJOLLevel / YoY
InflationCPIAUCSL, PCEPILFE, PCEPI, CPILFESL, PPIACOYoY
HousingHOUST, PERMIT, HSN1F, CSUSHPISAYoY
Banking/CreditBAA10YM, BUSLOANS, DRALACBS, DRTSCILMLevel / YoY
YieldsT10Y3M, T10Y2Y, GS10, TB3MS, FEDFUNDSLevel

Non-monthly series are resampled: weekly (ICSA) to monthly mean, daily (T10Y3M, T10Y2Y) to month-end, quarterly (GDPC1, DRALACBS, DRTSCILM) forward-filled to monthly. Features with less than 80% coverage of the target period are excluded to prevent short-history series from shrinking the sample.


Weekly Email Report

The automated email includes:

SectionContent
IC SummarySnapshot table (probability, direction, risk driver, offset), model range, portfolio positioning (equities, fixed income, credit, hedging)
Executive SummaryEnsemble headline, model consensus, divergence framing
Key IndicatorsFour macro buckets (Growth, Inflation, Policy, Market Signals) — two sentences each
Model DivergenceStructured yield curve analysis: historical track record, three structural factors (QE, foreign CB demand, Basel III), judgment call
WatchlistTrigger levels: exact values each indicator needs to reach for 30%/50% probability, ranked by proximity
Adverse ScenarioTail risk classification, three real-world triggers, hedging framework tied to ensemble level
What Would Change Our ViewFive hardcoded thresholds (spread < -1%, core CPI < 1.5%, housing -15% YoY, claims > 300K, ensemble > 20%)
Data Currency NoticeData-through date and lagged series disclosure

Seven charts embedded inline: probability gauge, ensemble trend, indicator percentile dashboard, model comparison, indicator sparklines, full historical probability, and sensitivity trigger levels.


Configuration

All modeling choices are set in a single configuration block:

ParameterDefaultDescription
TARGET_DEFINITION"point""point" = recession at month t+12; "window" = any recession in months t+1 through t+12
OBS_START"1967-01-01"Observation start date
MIN_WINDOW120Minimum expanding-window training size (months)
MAX_FEATURES_BIC9Maximum features for BIC selection
THRESHOLD_WARNING30Warning probability level (%)
THRESHOLD_ELEVATED50Elevated probability level (%)

Project Structure

Recession_Probability_Model/
├── Recession_Probability_Model.ipynb # Interactive notebook (Google Colab)
├── automation/
│ ├── daily_report.py # Model run, charts, summary JSON
│ ├── generate_email.py # Claude API email composition + Gmail delivery
│ └── output/ # Generated charts, summaries, emails
├── .github/workflows/
│ └── daily_recession_report.yml # GitHub Actions weekly schedule
├── requirements.txt
├── .gitignore
├── LICENSE # MIT
└── README.md

Dependencies

PackageVersionPurpose
fredapi>= 0.5.0FRED API data access
statsmodels>= 0.14Probit regression, marginal effects, summary statistics
scikit-learn>= 1.3AUROC and Brier Score evaluation
matplotlib>= 3.7Charts and visualizations
pandas>= 2.0Data manipulation and time series alignment
numpy>= 1.24Numerical operations
scipy>= 1.10Normal CDF/PDF for probit predictions
anthropic>= 0.40Claude API for email narrative generation

Install all: pip install -r requirements.txt


Evaluation Metrics

MetricWhat It Measures
AUROCDiscrimination ability (1.0 = perfect, 0.5 = random)
Brier ScoreMean squared probability error (lower = better)
Pseudo R-squaredVariance explained vs. intercept-only model
AICFit-complexity tradeoff (lighter penalty)
BICFit-complexity tradeoff (heavier penalty — primary selection criterion)

Known Limitations

  • Trained on ~6 independent recession episodes — limited sample for generalization
  • Assumes future recessions resemble historical patterns — novel mechanisms (pandemics, geopolitical shocks) may not be captured
  • 12-month horizon is long — conditions can change materially within the window
  • FRED data has publication lags (1-3 months) — the latest reading may reflect conditions from 1-2 months ago
  • The model assigns a negative coefficient to inflation, reflecting demand-collapse recessions — this may understate stagflation risk where inflation and growth weakness occur simultaneously
  • Feature selection (BIC) is in-sample — the optimal feature set may differ in future regimes
  • The model should be one input among many — not a sole basis for allocation decisions

References

  1. Estrella, A. & Mishkin, F.S. (1998). "Predicting U.S. Recessions: Financial Variables as Leading Indicators." Review of Economics and Statistics, 80(1), 45-61.

  2. Wright, J.H. (2006). "The Yield Curve and Predicting Recessions." Federal Reserve Board FEDS Working Paper No. 2006-07.

  3. Kauppi, H. & Saikkonen, P. (2008). "Predicting U.S. Recessions with Dynamic Binary Response Models." Review of Economics and Statistics, 90(4), 777-791.

  4. Berge, T.J. (2014). "Predicting Recessions with Leading Indicators: Model Averaging and Links to the Financial Crisis." Federal Reserve Bank of Kansas City Working Paper.

  5. Berge, T.J. & Jorda, O. (2011). "Evaluating the Classification of Economic Activity into Recessions and Expansions." American Economic Journal: Macroeconomics.

  6. Federal Reserve Board FEDS Notes (2018, 2019). Comparative evaluation of six probit recession models.

  7. Boston Fed (2020). On dispersion in predicted recession probabilities from dependent variable construction choices.

  8. McCracken, M.W. & Ng, S. (2016). "FRED-MD: A Monthly Database for Macroeconomic Research." Journal of Business & Economic Statistics, 34(4), 574-589.

  9. Sahm, C. (2019). "Direct Stimulus Payments to Individuals." Brookings Institution. — Introduced the Sahm Rule.

  10. Bellego, C. & Ferrara, L. (2009). "Forecasting Euro Area Recessions Using Time-Varying Binary Response Models for Financial Variables." ECB Working Paper.


Contributing

Contributions are welcome. If you'd like to extend the model:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/your-feature)
  3. Make your changes and test locally with python automation/daily_report.py
  4. Submit a pull request with a clear description of what changed and why

Areas where contributions would be particularly valuable:

  • Additional model specifications (dynamic probit, Bayesian Model Averaging)
  • Alternative data sources beyond FRED
  • International recession models (EU, UK, Japan)
  • Dashboard/web UI for the weekly report

Disclaimer

This project is for educational and research purposes only. It is not financial advice, investment advice, or a recommendation to buy, sell, or hold any security or financial instrument. The model output should not be used as the sole basis for any investment decision. Past recession-prediction accuracy does not guarantee future performance. Economic models are inherently uncertain and can fail without warning, particularly during novel economic conditions. The authors assume no liability for any financial losses incurred from the use of this model. Consult a qualified financial advisor before making investment decisions.


License

MIT License. See LICENSE for details.


Suggested Repository Topics

recessionmacroeconomicsprobityield-curvefred-apieconomic-forecastingrecession-probabilitynbertime-seriespythonstatsmodelsclaude-apigithub-actions

About

Estimates 12-month-ahead U.S. recession probability using a five-model ensemble across 37 Federal Reserve indicators. Generates automated weekly investment committee briefings with embedded charts via GitHub Actions and Claude API.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

U.S. Recession Probability Model — 12-Month Ahead

License: MITPython 3.8+Open In ColabGitHub starsWeekly Report

A five-model ensemble that estimates the probability of a U.S. recession occurring within the next 12 months, using 37 FRED indicators across eight macroeconomic categories. Generates an automated weekly investment committee briefing with embedded charts via Claude API.

Built on the academic framework established by Estrella and Mishkin (1996, 1998) and currently used by the New York Fed and Cleveland Fed.


What This Does

Every Monday morning, a GitHub Actions pipeline:

  1. Pulls the latest data from the Federal Reserve's FRED database (37 indicators)
  2. Runs a probit regression with BIC-based feature selection and economic sign constraints
  3. Computes a five-model ensemble probability with bootstrap confidence intervals
  4. Generates 7 charts covering probability trends, indicator dashboards, model comparison, sensitivity triggers, and historical context
  5. Sends Claude API the model output + charts, which writes a structured investment committee memo
  6. Delivers the memo via email with all charts embedded inline

The ensemble averages across five methodologically distinct models: NY Fed spread-only, Wright two-factor, BIC-selected multivariate, Estrella-Mishkin closed-form, and Chauvet-Piger Markov-switching.


Quick Start

Option A: Google Colab (interactive exploration)

  1. Open Recession_Probability_Model.ipynb in Google Colab
  2. Get a free FRED API key at https://fred.stlouisfed.org/docs/api/fred/
  3. Run all cells — handles installation, data fetching, modeling, and visualization

Option B: Automated weekly reports (fork and deploy)

  1. Fork this repository

  2. Add GitHub Secrets (Settings > Secrets and variables > Actions):

    SecretRequiredDescription
    FRED_API_KEYYesFree key from https://fred.stlouisfed.org/docs/api/fred/
    ANTHROPIC_API_KEYYesClaude API key from https://console.anthropic.com/
    MAIL_USERNAMENoGmail address for sending reports
    MAIL_PASSWORDNoGmail app password (from https://myaccount.google.com/apppasswords)
    MAIL_PORTNoSMTP port, typically 587
    EMAIL_TONoRecipient email(s), comma-separated
  3. Enable the workflow: Actions tab > "Weekly Recession Probability Report" > Enable

  4. Test: Click "Run workflow" to trigger immediately

Without Gmail credentials, the email report is saved as an HTML file in the workflow artifacts.

Option C: Run locally

git clone https://github.com/SecondOrderEdge/Recession_Probability_Model.git
cd Recession_Probability_Model
pip install -r requirements.txt
export FRED_API_KEY="your-key"export ANTHROPIC_API_KEY="your-key"
python automation/daily_report.py # Fetch data, run model, generate charts
python automation/generate_email.py # Generate email via Claude API

Output files are written to automation/output/.


How It Works

The Probit Framework

The core statistical model is a probit regression:

P(Recession_{t+12} = 1 | X_t) = Phi(a_0 + a_1 * X_t)

where Phi(.) is the standard normal CDF, X_t is a vector of economic indicators observed at time t, and the forecast horizon is 12 months. The probit maps a linear combination of indicators into a probability bounded between 0 and 1, connecting naturally to latent-variable models where an unobserved "economic health" index crosses a threshold during recessions.

Five-Model Ensemble

Rather than relying on any single specification, the headline probability is an equal-weighted average of five methodologically distinct models:

ModelFeaturesMethodologyReference
NY Fed BaselineYield curve spread onlyRe-estimated probitEstrella & Mishkin (1998)
Wright ExtensionSpread + Federal Funds RateRe-estimated probitWright (2006)
BIC-SelectedData-driven optimal setRe-estimated probit with sign constraintsForward stepwise BIC
Estrella-MishkinYield curve spreadClosed-form with 2006 parametersEstrella & Trubin (2006)
Chauvet-PigerMarkov-switching modelIndependent FRED series (RECPROUSM156N)Chauvet & Piger

This diversifies across model complexity (1 variable to 7+), estimation approach (re-estimated vs. frozen parameters vs. Markov-switching), and the fundamental question of whether the yield curve alone is sufficient or multi-factor models add value.

Feature Selection: BIC with Sign Constraints

Recessions are rare (~15% of months since 1967). With 30+ candidate features and only ~6 recession episodes in the sample, overfitting is the primary risk. The model uses forward stepwise BIC selection with three safeguards:

  1. BIC penalty: Penalizes complexity more aggressively than AIC, enforcing the parsimony that Berge (2014) showed dominates at the 12-month horizon
  2. Separation detection: Rejects any feature combination that produces quasi-complete separation (coefficients > 100, nan standard errors, or pseudo R-squared > 0.99)
  3. Economic sign constraints: Ensures coefficients align with theory before accepting a candidate:
IndicatorRequired SignEconomic Logic
SPREADNegativeLower spread = higher recession risk
UNRATE_CHG3PositiveRising unemployment = higher recession risk
UMCSENTNegativeLower sentiment = higher recession risk
BUSLOANS_YOYNegativeCredit contraction = higher recession risk

If no valid combination passes all three checks, the model falls back to the Wright two-variable specification (spread + fed funds rate).

Dependent Variable Construction

The dependent variable is configurable:

  • Point-in-time ("point"): y_t = 1 if in recession at month t+12. Used by the NY Fed.
  • Any-in-window ("window"): y_t = 1 if recession occurs at any point during months t+1 through t+12. Produces higher, more persistent probabilities.

The Boston Fed (2020) documented "considerable dispersion" between these approaches. The notebook compares both side-by-side.

Variable Transformations

Transforms are metadata-driven via the SERIES_CONFIG dictionary:

  • Year-over-year percent change ("yoy"): For non-stationary level series (INDPRO, CPI, Housing Starts, Payrolls). Removes trend, preserves cyclical signal.
  • Levels ("level"): For stationary/bounded series (spreads, rates, normalized indexes).
  • Derived features: SPREAD (= GS10 - TB3MS) for pre-1982 monthly history; UNRATE_CHG3 for Sahm-style unemployment momentum.

Estimation: Expanding Windows

Uses expanding-window (not rolling) estimation because recessions are too rare for rolling windows to produce stable estimates. Minimum training window: 120 months (10 years). Each month's probability is generated from a model trained only on data available at that point — no lookahead bias.

Robustness Checks

The notebook includes five robustness checks:

  1. Bootstrap 90% CI — 1,000 resamples to quantify uncertainty around the point estimate
  2. Leave-one-recession-out — Trains on all recessions except one, tests detection on the held-out episode
  3. Penalized probit — L2-regularized logistic regression to verify quasi-separation isn't distorting estimates
  4. Model consensus — Measures agreement across all five specifications
  5. Sensitivity triggers — Binary search for the exact indicator value that would push probability to 30% or 50%

Trend Attribution

The weekly report decomposes the 24-month probability change into per-indicator contributions using partial effects (coefficient x change in variable x normal PDF at the current linear index). This identifies which indicators are driving the probability up or down.


Data Universe — 37 FRED Series Across 8 Categories

CategorySeriesTransform
National ActivityCFNAI, CFNAIMA3, GDPC1, USSLINDLevel / YoY
IndustrialINDPRO, BSCICP02USM460S (OECD Mfg Confidence), TCU, DGORDER, IPMANYoY / Level
ConsumerUMCSENT, PCECC96, DSPIC96, RSAFSLevel / YoY
Labor MarketUNRATE, ICSA, PAYEMS, JTSJOLLevel / YoY
InflationCPIAUCSL, PCEPILFE, PCEPI, CPILFESL, PPIACOYoY
HousingHOUST, PERMIT, HSN1F, CSUSHPISAYoY
Banking/CreditBAA10YM, BUSLOANS, DRALACBS, DRTSCILMLevel / YoY
YieldsT10Y3M, T10Y2Y, GS10, TB3MS, FEDFUNDSLevel

Non-monthly series are resampled: weekly (ICSA) to monthly mean, daily (T10Y3M, T10Y2Y) to month-end, quarterly (GDPC1, DRALACBS, DRTSCILM) forward-filled to monthly. Features with less than 80% coverage of the target period are excluded to prevent short-history series from shrinking the sample.


Weekly Email Report

The automated email includes:

SectionContent
IC SummarySnapshot table (probability, direction, risk driver, offset), model range, portfolio positioning (equities, fixed income, credit, hedging)
Executive SummaryEnsemble headline, model consensus, divergence framing
Key IndicatorsFour macro buckets (Growth, Inflation, Policy, Market Signals) — two sentences each
Model DivergenceStructured yield curve analysis: historical track record, three structural factors (QE, foreign CB demand, Basel III), judgment call
WatchlistTrigger levels: exact values each indicator needs to reach for 30%/50% probability, ranked by proximity
Adverse ScenarioTail risk classification, three real-world triggers, hedging framework tied to ensemble level
What Would Change Our ViewFive hardcoded thresholds (spread < -1%, core CPI < 1.5%, housing -15% YoY, claims > 300K, ensemble > 20%)
Data Currency NoticeData-through date and lagged series disclosure

Seven charts embedded inline: probability gauge, ensemble trend, indicator percentile dashboard, model comparison, indicator sparklines, full historical probability, and sensitivity trigger levels.


Configuration

All modeling choices are set in a single configuration block:

ParameterDefaultDescription
TARGET_DEFINITION"point""point" = recession at month t+12; "window" = any recession in months t+1 through t+12
OBS_START"1967-01-01"Observation start date
MIN_WINDOW120Minimum expanding-window training size (months)
MAX_FEATURES_BIC9Maximum features for BIC selection
THRESHOLD_WARNING30Warning probability level (%)
THRESHOLD_ELEVATED50Elevated probability level (%)

Project Structure

Recession_Probability_Model/
├── Recession_Probability_Model.ipynb # Interactive notebook (Google Colab)
├── automation/
│ ├── daily_report.py # Model run, charts, summary JSON
│ ├── generate_email.py # Claude API email composition + Gmail delivery
│ └── output/ # Generated charts, summaries, emails
├── .github/workflows/
│ └── daily_recession_report.yml # GitHub Actions weekly schedule
├── requirements.txt
├── .gitignore
├── LICENSE # MIT
└── README.md

Dependencies

PackageVersionPurpose
fredapi>= 0.5.0FRED API data access
statsmodels>= 0.14Probit regression, marginal effects, summary statistics
scikit-learn>= 1.3AUROC and Brier Score evaluation
matplotlib>= 3.7Charts and visualizations
pandas>= 2.0Data manipulation and time series alignment
numpy>= 1.24Numerical operations
scipy>= 1.10Normal CDF/PDF for probit predictions
anthropic>= 0.40Claude API for email narrative generation

Install all: pip install -r requirements.txt


Evaluation Metrics

MetricWhat It Measures
AUROCDiscrimination ability (1.0 = perfect, 0.5 = random)
Brier ScoreMean squared probability error (lower = better)
Pseudo R-squaredVariance explained vs. intercept-only model
AICFit-complexity tradeoff (lighter penalty)
BICFit-complexity tradeoff (heavier penalty — primary selection criterion)

Known Limitations

  • Trained on ~6 independent recession episodes — limited sample for generalization
  • Assumes future recessions resemble historical patterns — novel mechanisms (pandemics, geopolitical shocks) may not be captured
  • 12-month horizon is long — conditions can change materially within the window
  • FRED data has publication lags (1-3 months) — the latest reading may reflect conditions from 1-2 months ago
  • The model assigns a negative coefficient to inflation, reflecting demand-collapse recessions — this may understate stagflation risk where inflation and growth weakness occur simultaneously
  • Feature selection (BIC) is in-sample — the optimal feature set may differ in future regimes
  • The model should be one input among many — not a sole basis for allocation decisions

References

  1. Estrella, A. & Mishkin, F.S. (1998). "Predicting U.S. Recessions: Financial Variables as Leading Indicators." Review of Economics and Statistics, 80(1), 45-61.

  2. Wright, J.H. (2006). "The Yield Curve and Predicting Recessions." Federal Reserve Board FEDS Working Paper No. 2006-07.

  3. Kauppi, H. & Saikkonen, P. (2008). "Predicting U.S. Recessions with Dynamic Binary Response Models." Review of Economics and Statistics, 90(4), 777-791.

  4. Berge, T.J. (2014). "Predicting Recessions with Leading Indicators: Model Averaging and Links to the Financial Crisis." Federal Reserve Bank of Kansas City Working Paper.

  5. Berge, T.J. & Jorda, O. (2011). "Evaluating the Classification of Economic Activity into Recessions and Expansions." American Economic Journal: Macroeconomics.

  6. Federal Reserve Board FEDS Notes (2018, 2019). Comparative evaluation of six probit recession models.

  7. Boston Fed (2020). On dispersion in predicted recession probabilities from dependent variable construction choices.

  8. McCracken, M.W. & Ng, S. (2016). "FRED-MD: A Monthly Database for Macroeconomic Research." Journal of Business & Economic Statistics, 34(4), 574-589.

  9. Sahm, C. (2019). "Direct Stimulus Payments to Individuals." Brookings Institution. — Introduced the Sahm Rule.

  10. Bellego, C. & Ferrara, L. (2009). "Forecasting Euro Area Recessions Using Time-Varying Binary Response Models for Financial Variables." ECB Working Paper.


Contributing

Contributions are welcome. If you'd like to extend the model:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/your-feature)
  3. Make your changes and test locally with python automation/daily_report.py
  4. Submit a pull request with a clear description of what changed and why

Areas where contributions would be particularly valuable:

  • Additional model specifications (dynamic probit, Bayesian Model Averaging)
  • Alternative data sources beyond FRED
  • International recession models (EU, UK, Japan)
  • Dashboard/web UI for the weekly report

Disclaimer

This project is for educational and research purposes only. It is not financial advice, investment advice, or a recommendation to buy, sell, or hold any security or financial instrument. The model output should not be used as the sole basis for any investment decision. Past recession-prediction accuracy does not guarantee future performance. Economic models are inherently uncertain and can fail without warning, particularly during novel economic conditions. The authors assume no liability for any financial losses incurred from the use of this model. Consult a qualified financial advisor before making investment decisions.


License

MIT License. See LICENSE for details.


Suggested Repository Topics

recessionmacroeconomicsprobityield-curvefred-apieconomic-forecastingrecession-probabilitynbertime-seriespythonstatsmodelsclaude-apigithub-actions

About

Estimates 12-month-ahead U.S. recession probability using a five-model ensemble across 37 Federal Reserve indicators. Generates automated weekly investment committee briefings with embedded charts via GitHub Actions and Claude API.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

U.S. Recession Probability Model — 12-Month Ahead

License: MITPython 3.8+Open In ColabGitHub starsWeekly Report

A five-model ensemble that estimates the probability of a U.S. recession occurring within the next 12 months, using 37 FRED indicators across eight macroeconomic categories. Generates an automated weekly investment committee briefing with embedded charts via Claude API.

Built on the academic framework established by Estrella and Mishkin (1996, 1998) and currently used by the New York Fed and Cleveland Fed.


What This Does

Every Monday morning, a GitHub Actions pipeline:

  1. Pulls the latest data from the Federal Reserve's FRED database (37 indicators)
  2. Runs a probit regression with BIC-based feature selection and economic sign constraints
  3. Computes a five-model ensemble probability with bootstrap confidence intervals
  4. Generates 7 charts covering probability trends, indicator dashboards, model comparison, sensitivity triggers, and historical context
  5. Sends Claude API the model output + charts, which writes a structured investment committee memo
  6. Delivers the memo via email with all charts embedded inline

The ensemble averages across five methodologically distinct models: NY Fed spread-only, Wright two-factor, BIC-selected multivariate, Estrella-Mishkin closed-form, and Chauvet-Piger Markov-switching.


Quick Start

Option A: Google Colab (interactive exploration)

  1. Open Recession_Probability_Model.ipynb in Google Colab
  2. Get a free FRED API key at https://fred.stlouisfed.org/docs/api/fred/
  3. Run all cells — handles installation, data fetching, modeling, and visualization

Option B: Automated weekly reports (fork and deploy)

  1. Fork this repository

  2. Add GitHub Secrets (Settings > Secrets and variables > Actions):

    SecretRequiredDescription
    FRED_API_KEYYesFree key from https://fred.stlouisfed.org/docs/api/fred/
    ANTHROPIC_API_KEYYesClaude API key from https://console.anthropic.com/
    MAIL_USERNAMENoGmail address for sending reports
    MAIL_PASSWORDNoGmail app password (from https://myaccount.google.com/apppasswords)
    MAIL_PORTNoSMTP port, typically 587
    EMAIL_TONoRecipient email(s), comma-separated
  3. Enable the workflow: Actions tab > "Weekly Recession Probability Report" > Enable

  4. Test: Click "Run workflow" to trigger immediately

Without Gmail credentials, the email report is saved as an HTML file in the workflow artifacts.

Option C: Run locally

git clone https://github.com/SecondOrderEdge/Recession_Probability_Model.git
cd Recession_Probability_Model
pip install -r requirements.txt
export FRED_API_KEY="your-key"export ANTHROPIC_API_KEY="your-key"
python automation/daily_report.py # Fetch data, run model, generate charts
python automation/generate_email.py # Generate email via Claude API

Output files are written to automation/output/.


How It Works

The Probit Framework

The core statistical model is a probit regression:

P(Recession_{t+12} = 1 | X_t) = Phi(a_0 + a_1 * X_t)

where Phi(.) is the standard normal CDF, X_t is a vector of economic indicators observed at time t, and the forecast horizon is 12 months. The probit maps a linear combination of indicators into a probability bounded between 0 and 1, connecting naturally to latent-variable models where an unobserved "economic health" index crosses a threshold during recessions.

Five-Model Ensemble

Rather than relying on any single specification, the headline probability is an equal-weighted average of five methodologically distinct models:

ModelFeaturesMethodologyReference
NY Fed BaselineYield curve spread onlyRe-estimated probitEstrella & Mishkin (1998)
Wright ExtensionSpread + Federal Funds RateRe-estimated probitWright (2006)
BIC-SelectedData-driven optimal setRe-estimated probit with sign constraintsForward stepwise BIC
Estrella-MishkinYield curve spreadClosed-form with 2006 parametersEstrella & Trubin (2006)
Chauvet-PigerMarkov-switching modelIndependent FRED series (RECPROUSM156N)Chauvet & Piger

This diversifies across model complexity (1 variable to 7+), estimation approach (re-estimated vs. frozen parameters vs. Markov-switching), and the fundamental question of whether the yield curve alone is sufficient or multi-factor models add value.

Feature Selection: BIC with Sign Constraints

Recessions are rare (~15% of months since 1967). With 30+ candidate features and only ~6 recession episodes in the sample, overfitting is the primary risk. The model uses forward stepwise BIC selection with three safeguards:

  1. BIC penalty: Penalizes complexity more aggressively than AIC, enforcing the parsimony that Berge (2014) showed dominates at the 12-month horizon
  2. Separation detection: Rejects any feature combination that produces quasi-complete separation (coefficients > 100, nan standard errors, or pseudo R-squared > 0.99)
  3. Economic sign constraints: Ensures coefficients align with theory before accepting a candidate:
IndicatorRequired SignEconomic Logic
SPREADNegativeLower spread = higher recession risk
UNRATE_CHG3PositiveRising unemployment = higher recession risk
UMCSENTNegativeLower sentiment = higher recession risk
BUSLOANS_YOYNegativeCredit contraction = higher recession risk

If no valid combination passes all three checks, the model falls back to the Wright two-variable specification (spread + fed funds rate).

Dependent Variable Construction

The dependent variable is configurable:

  • Point-in-time ("point"): y_t = 1 if in recession at month t+12. Used by the NY Fed.
  • Any-in-window ("window"): y_t = 1 if recession occurs at any point during months t+1 through t+12. Produces higher, more persistent probabilities.

The Boston Fed (2020) documented "considerable dispersion" between these approaches. The notebook compares both side-by-side.

Variable Transformations

Transforms are metadata-driven via the SERIES_CONFIG dictionary:

  • Year-over-year percent change ("yoy"): For non-stationary level series (INDPRO, CPI, Housing Starts, Payrolls). Removes trend, preserves cyclical signal.
  • Levels ("level"): For stationary/bounded series (spreads, rates, normalized indexes).
  • Derived features: SPREAD (= GS10 - TB3MS) for pre-1982 monthly history; UNRATE_CHG3 for Sahm-style unemployment momentum.

Estimation: Expanding Windows

Uses expanding-window (not rolling) estimation because recessions are too rare for rolling windows to produce stable estimates. Minimum training window: 120 months (10 years). Each month's probability is generated from a model trained only on data available at that point — no lookahead bias.

Robustness Checks

The notebook includes five robustness checks:

  1. Bootstrap 90% CI — 1,000 resamples to quantify uncertainty around the point estimate
  2. Leave-one-recession-out — Trains on all recessions except one, tests detection on the held-out episode
  3. Penalized probit — L2-regularized logistic regression to verify quasi-separation isn't distorting estimates
  4. Model consensus — Measures agreement across all five specifications
  5. Sensitivity triggers — Binary search for the exact indicator value that would push probability to 30% or 50%

Trend Attribution

The weekly report decomposes the 24-month probability change into per-indicator contributions using partial effects (coefficient x change in variable x normal PDF at the current linear index). This identifies which indicators are driving the probability up or down.


Data Universe — 37 FRED Series Across 8 Categories

CategorySeriesTransform
National ActivityCFNAI, CFNAIMA3, GDPC1, USSLINDLevel / YoY
IndustrialINDPRO, BSCICP02USM460S (OECD Mfg Confidence), TCU, DGORDER, IPMANYoY / Level
ConsumerUMCSENT, PCECC96, DSPIC96, RSAFSLevel / YoY
Labor MarketUNRATE, ICSA, PAYEMS, JTSJOLLevel / YoY
InflationCPIAUCSL, PCEPILFE, PCEPI, CPILFESL, PPIACOYoY
HousingHOUST, PERMIT, HSN1F, CSUSHPISAYoY
Banking/CreditBAA10YM, BUSLOANS, DRALACBS, DRTSCILMLevel / YoY
YieldsT10Y3M, T10Y2Y, GS10, TB3MS, FEDFUNDSLevel

Non-monthly series are resampled: weekly (ICSA) to monthly mean, daily (T10Y3M, T10Y2Y) to month-end, quarterly (GDPC1, DRALACBS, DRTSCILM) forward-filled to monthly. Features with less than 80% coverage of the target period are excluded to prevent short-history series from shrinking the sample.


Weekly Email Report

The automated email includes:

SectionContent
IC SummarySnapshot table (probability, direction, risk driver, offset), model range, portfolio positioning (equities, fixed income, credit, hedging)
Executive SummaryEnsemble headline, model consensus, divergence framing
Key IndicatorsFour macro buckets (Growth, Inflation, Policy, Market Signals) — two sentences each
Model DivergenceStructured yield curve analysis: historical track record, three structural factors (QE, foreign CB demand, Basel III), judgment call
WatchlistTrigger levels: exact values each indicator needs to reach for 30%/50% probability, ranked by proximity
Adverse ScenarioTail risk classification, three real-world triggers, hedging framework tied to ensemble level
What Would Change Our ViewFive hardcoded thresholds (spread < -1%, core CPI < 1.5%, housing -15% YoY, claims > 300K, ensemble > 20%)
Data Currency NoticeData-through date and lagged series disclosure

Seven charts embedded inline: probability gauge, ensemble trend, indicator percentile dashboard, model comparison, indicator sparklines, full historical probability, and sensitivity trigger levels.


Configuration

All modeling choices are set in a single configuration block:

ParameterDefaultDescription
TARGET_DEFINITION"point""point" = recession at month t+12; "window" = any recession in months t+1 through t+12
OBS_START"1967-01-01"Observation start date
MIN_WINDOW120Minimum expanding-window training size (months)
MAX_FEATURES_BIC9Maximum features for BIC selection
THRESHOLD_WARNING30Warning probability level (%)
THRESHOLD_ELEVATED50Elevated probability level (%)

Project Structure

Recession_Probability_Model/
├── Recession_Probability_Model.ipynb # Interactive notebook (Google Colab)
├── automation/
│ ├── daily_report.py # Model run, charts, summary JSON
│ ├── generate_email.py # Claude API email composition + Gmail delivery
│ └── output/ # Generated charts, summaries, emails
├── .github/workflows/
│ └── daily_recession_report.yml # GitHub Actions weekly schedule
├── requirements.txt
├── .gitignore
├── LICENSE # MIT
└── README.md

Dependencies

PackageVersionPurpose
fredapi>= 0.5.0FRED API data access
statsmodels>= 0.14Probit regression, marginal effects, summary statistics
scikit-learn>= 1.3AUROC and Brier Score evaluation
matplotlib>= 3.7Charts and visualizations
pandas>= 2.0Data manipulation and time series alignment
numpy>= 1.24Numerical operations
scipy>= 1.10Normal CDF/PDF for probit predictions
anthropic>= 0.40Claude API for email narrative generation

Install all: pip install -r requirements.txt


Evaluation Metrics

MetricWhat It Measures
AUROCDiscrimination ability (1.0 = perfect, 0.5 = random)
Brier ScoreMean squared probability error (lower = better)
Pseudo R-squaredVariance explained vs. intercept-only model
AICFit-complexity tradeoff (lighter penalty)
BICFit-complexity tradeoff (heavier penalty — primary selection criterion)

Known Limitations

  • Trained on ~6 independent recession episodes — limited sample for generalization
  • Assumes future recessions resemble historical patterns — novel mechanisms (pandemics, geopolitical shocks) may not be captured
  • 12-month horizon is long — conditions can change materially within the window
  • FRED data has publication lags (1-3 months) — the latest reading may reflect conditions from 1-2 months ago
  • The model assigns a negative coefficient to inflation, reflecting demand-collapse recessions — this may understate stagflation risk where inflation and growth weakness occur simultaneously
  • Feature selection (BIC) is in-sample — the optimal feature set may differ in future regimes
  • The model should be one input among many — not a sole basis for allocation decisions

References

  1. Estrella, A. & Mishkin, F.S. (1998). "Predicting U.S. Recessions: Financial Variables as Leading Indicators." Review of Economics and Statistics, 80(1), 45-61.

  2. Wright, J.H. (2006). "The Yield Curve and Predicting Recessions." Federal Reserve Board FEDS Working Paper No. 2006-07.

  3. Kauppi, H. & Saikkonen, P. (2008). "Predicting U.S. Recessions with Dynamic Binary Response Models." Review of Economics and Statistics, 90(4), 777-791.

  4. Berge, T.J. (2014). "Predicting Recessions with Leading Indicators: Model Averaging and Links to the Financial Crisis." Federal Reserve Bank of Kansas City Working Paper.

  5. Berge, T.J. & Jorda, O. (2011). "Evaluating the Classification of Economic Activity into Recessions and Expansions." American Economic Journal: Macroeconomics.

  6. Federal Reserve Board FEDS Notes (2018, 2019). Comparative evaluation of six probit recession models.

  7. Boston Fed (2020). On dispersion in predicted recession probabilities from dependent variable construction choices.

  8. McCracken, M.W. & Ng, S. (2016). "FRED-MD: A Monthly Database for Macroeconomic Research." Journal of Business & Economic Statistics, 34(4), 574-589.

  9. Sahm, C. (2019). "Direct Stimulus Payments to Individuals." Brookings Institution. — Introduced the Sahm Rule.

  10. Bellego, C. & Ferrara, L. (2009). "Forecasting Euro Area Recessions Using Time-Varying Binary Response Models for Financial Variables." ECB Working Paper.


Contributing

Contributions are welcome. If you'd like to extend the model:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/your-feature)
  3. Make your changes and test locally with python automation/daily_report.py
  4. Submit a pull request with a clear description of what changed and why

Areas where contributions would be particularly valuable:

  • Additional model specifications (dynamic probit, Bayesian Model Averaging)
  • Alternative data sources beyond FRED
  • International recession models (EU, UK, Japan)
  • Dashboard/web UI for the weekly report

Disclaimer

This project is for educational and research purposes only. It is not financial advice, investment advice, or a recommendation to buy, sell, or hold any security or financial instrument. The model output should not be used as the sole basis for any investment decision. Past recession-prediction accuracy does not guarantee future performance. Economic models are inherently uncertain and can fail without warning, particularly during novel economic conditions. The authors assume no liability for any financial losses incurred from the use of this model. Consult a qualified financial advisor before making investment decisions.


License

MIT License. See LICENSE for details.


Suggested Repository Topics

recessionmacroeconomicsprobityield-curvefred-apieconomic-forecastingrecession-probabilitynbertime-seriespythonstatsmodelsclaude-apigithub-actions

About

Estimates 12-month-ahead U.S. recession probability using a five-model ensemble across 37 Federal Reserve indicators. Generates automated weekly investment committee briefings with embedded charts via GitHub Actions and Claude API.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

U.S. Recession Probability Model — 12-Month Ahead

License: MITPython 3.8+Open In ColabGitHub starsWeekly Report

A five-model ensemble that estimates the probability of a U.S. recession occurring within the next 12 months, using 37 FRED indicators across eight macroeconomic categories. Generates an automated weekly investment committee briefing with embedded charts via Claude API.

Built on the academic framework established by Estrella and Mishkin (1996, 1998) and currently used by the New York Fed and Cleveland Fed.


What This Does

Every Monday morning, a GitHub Actions pipeline:

  1. Pulls the latest data from the Federal Reserve's FRED database (37 indicators)
  2. Runs a probit regression with BIC-based feature selection and economic sign constraints
  3. Computes a five-model ensemble probability with bootstrap confidence intervals
  4. Generates 7 charts covering probability trends, indicator dashboards, model comparison, sensitivity triggers, and historical context
  5. Sends Claude API the model output + charts, which writes a structured investment committee memo
  6. Delivers the memo via email with all charts embedded inline

The ensemble averages across five methodologically distinct models: NY Fed spread-only, Wright two-factor, BIC-selected multivariate, Estrella-Mishkin closed-form, and Chauvet-Piger Markov-switching.


Quick Start

Option A: Google Colab (interactive exploration)

  1. Open Recession_Probability_Model.ipynb in Google Colab
  2. Get a free FRED API key at https://fred.stlouisfed.org/docs/api/fred/
  3. Run all cells — handles installation, data fetching, modeling, and visualization

Option B: Automated weekly reports (fork and deploy)

  1. Fork this repository

  2. Add GitHub Secrets (Settings > Secrets and variables > Actions):

    SecretRequiredDescription
    FRED_API_KEYYesFree key from https://fred.stlouisfed.org/docs/api/fred/
    ANTHROPIC_API_KEYYesClaude API key from https://console.anthropic.com/
    MAIL_USERNAMENoGmail address for sending reports
    MAIL_PASSWORDNoGmail app password (from https://myaccount.google.com/apppasswords)
    MAIL_PORTNoSMTP port, typically 587
    EMAIL_TONoRecipient email(s), comma-separated
  3. Enable the workflow: Actions tab > "Weekly Recession Probability Report" > Enable

  4. Test: Click "Run workflow" to trigger immediately

Without Gmail credentials, the email report is saved as an HTML file in the workflow artifacts.

Option C: Run locally

git clone https://github.com/SecondOrderEdge/Recession_Probability_Model.git
cd Recession_Probability_Model
pip install -r requirements.txt
export FRED_API_KEY="your-key"export ANTHROPIC_API_KEY="your-key"
python automation/daily_report.py # Fetch data, run model, generate charts
python automation/generate_email.py # Generate email via Claude API

Output files are written to automation/output/.


How It Works

The Probit Framework

The core statistical model is a probit regression:

P(Recession_{t+12} = 1 | X_t) = Phi(a_0 + a_1 * X_t)

where Phi(.) is the standard normal CDF, X_t is a vector of economic indicators observed at time t, and the forecast horizon is 12 months. The probit maps a linear combination of indicators into a probability bounded between 0 and 1, connecting naturally to latent-variable models where an unobserved "economic health" index crosses a threshold during recessions.

Five-Model Ensemble

Rather than relying on any single specification, the headline probability is an equal-weighted average of five methodologically distinct models:

ModelFeaturesMethodologyReference
NY Fed BaselineYield curve spread onlyRe-estimated probitEstrella & Mishkin (1998)
Wright ExtensionSpread + Federal Funds RateRe-estimated probitWright (2006)
BIC-SelectedData-driven optimal setRe-estimated probit with sign constraintsForward stepwise BIC
Estrella-MishkinYield curve spreadClosed-form with 2006 parametersEstrella & Trubin (2006)
Chauvet-PigerMarkov-switching modelIndependent FRED series (RECPROUSM156N)Chauvet & Piger

This diversifies across model complexity (1 variable to 7+), estimation approach (re-estimated vs. frozen parameters vs. Markov-switching), and the fundamental question of whether the yield curve alone is sufficient or multi-factor models add value.

Feature Selection: BIC with Sign Constraints

Recessions are rare (~15% of months since 1967). With 30+ candidate features and only ~6 recession episodes in the sample, overfitting is the primary risk. The model uses forward stepwise BIC selection with three safeguards:

  1. BIC penalty: Penalizes complexity more aggressively than AIC, enforcing the parsimony that Berge (2014) showed dominates at the 12-month horizon
  2. Separation detection: Rejects any feature combination that produces quasi-complete separation (coefficients > 100, nan standard errors, or pseudo R-squared > 0.99)
  3. Economic sign constraints: Ensures coefficients align with theory before accepting a candidate:
IndicatorRequired SignEconomic Logic
SPREADNegativeLower spread = higher recession risk
UNRATE_CHG3PositiveRising unemployment = higher recession risk
UMCSENTNegativeLower sentiment = higher recession risk
BUSLOANS_YOYNegativeCredit contraction = higher recession risk

If no valid combination passes all three checks, the model falls back to the Wright two-variable specification (spread + fed funds rate).

Dependent Variable Construction

The dependent variable is configurable:

  • Point-in-time ("point"): y_t = 1 if in recession at month t+12. Used by the NY Fed.
  • Any-in-window ("window"): y_t = 1 if recession occurs at any point during months t+1 through t+12. Produces higher, more persistent probabilities.

The Boston Fed (2020) documented "considerable dispersion" between these approaches. The notebook compares both side-by-side.

Variable Transformations

Transforms are metadata-driven via the SERIES_CONFIG dictionary:

  • Year-over-year percent change ("yoy"): For non-stationary level series (INDPRO, CPI, Housing Starts, Payrolls). Removes trend, preserves cyclical signal.
  • Levels ("level"): For stationary/bounded series (spreads, rates, normalized indexes).
  • Derived features: SPREAD (= GS10 - TB3MS) for pre-1982 monthly history; UNRATE_CHG3 for Sahm-style unemployment momentum.

Estimation: Expanding Windows

Uses expanding-window (not rolling) estimation because recessions are too rare for rolling windows to produce stable estimates. Minimum training window: 120 months (10 years). Each month's probability is generated from a model trained only on data available at that point — no lookahead bias.

Robustness Checks

The notebook includes five robustness checks:

  1. Bootstrap 90% CI — 1,000 resamples to quantify uncertainty around the point estimate
  2. Leave-one-recession-out — Trains on all recessions except one, tests detection on the held-out episode
  3. Penalized probit — L2-regularized logistic regression to verify quasi-separation isn't distorting estimates
  4. Model consensus — Measures agreement across all five specifications
  5. Sensitivity triggers — Binary search for the exact indicator value that would push probability to 30% or 50%

Trend Attribution

The weekly report decomposes the 24-month probability change into per-indicator contributions using partial effects (coefficient x change in variable x normal PDF at the current linear index). This identifies which indicators are driving the probability up or down.


Data Universe — 37 FRED Series Across 8 Categories

CategorySeriesTransform
National ActivityCFNAI, CFNAIMA3, GDPC1, USSLINDLevel / YoY
IndustrialINDPRO, BSCICP02USM460S (OECD Mfg Confidence), TCU, DGORDER, IPMANYoY / Level
ConsumerUMCSENT, PCECC96, DSPIC96, RSAFSLevel / YoY
Labor MarketUNRATE, ICSA, PAYEMS, JTSJOLLevel / YoY
InflationCPIAUCSL, PCEPILFE, PCEPI, CPILFESL, PPIACOYoY
HousingHOUST, PERMIT, HSN1F, CSUSHPISAYoY
Banking/CreditBAA10YM, BUSLOANS, DRALACBS, DRTSCILMLevel / YoY
YieldsT10Y3M, T10Y2Y, GS10, TB3MS, FEDFUNDSLevel

Non-monthly series are resampled: weekly (ICSA) to monthly mean, daily (T10Y3M, T10Y2Y) to month-end, quarterly (GDPC1, DRALACBS, DRTSCILM) forward-filled to monthly. Features with less than 80% coverage of the target period are excluded to prevent short-history series from shrinking the sample.


Weekly Email Report

The automated email includes:

SectionContent
IC SummarySnapshot table (probability, direction, risk driver, offset), model range, portfolio positioning (equities, fixed income, credit, hedging)
Executive SummaryEnsemble headline, model consensus, divergence framing
Key IndicatorsFour macro buckets (Growth, Inflation, Policy, Market Signals) — two sentences each
Model DivergenceStructured yield curve analysis: historical track record, three structural factors (QE, foreign CB demand, Basel III), judgment call
WatchlistTrigger levels: exact values each indicator needs to reach for 30%/50% probability, ranked by proximity
Adverse ScenarioTail risk classification, three real-world triggers, hedging framework tied to ensemble level
What Would Change Our ViewFive hardcoded thresholds (spread < -1%, core CPI < 1.5%, housing -15% YoY, claims > 300K, ensemble > 20%)
Data Currency NoticeData-through date and lagged series disclosure

Seven charts embedded inline: probability gauge, ensemble trend, indicator percentile dashboard, model comparison, indicator sparklines, full historical probability, and sensitivity trigger levels.


Configuration

All modeling choices are set in a single configuration block:

ParameterDefaultDescription
TARGET_DEFINITION"point""point" = recession at month t+12; "window" = any recession in months t+1 through t+12
OBS_START"1967-01-01"Observation start date
MIN_WINDOW120Minimum expanding-window training size (months)
MAX_FEATURES_BIC9Maximum features for BIC selection
THRESHOLD_WARNING30Warning probability level (%)
THRESHOLD_ELEVATED50Elevated probability level (%)

Project Structure

Recession_Probability_Model/
├── Recession_Probability_Model.ipynb # Interactive notebook (Google Colab)
├── automation/
│ ├── daily_report.py # Model run, charts, summary JSON
│ ├── generate_email.py # Claude API email composition + Gmail delivery
│ └── output/ # Generated charts, summaries, emails
├── .github/workflows/
│ └── daily_recession_report.yml # GitHub Actions weekly schedule
├── requirements.txt
├── .gitignore
├── LICENSE # MIT
└── README.md

Dependencies

PackageVersionPurpose
fredapi>= 0.5.0FRED API data access
statsmodels>= 0.14Probit regression, marginal effects, summary statistics
scikit-learn>= 1.3AUROC and Brier Score evaluation
matplotlib>= 3.7Charts and visualizations
pandas>= 2.0Data manipulation and time series alignment
numpy>= 1.24Numerical operations
scipy>= 1.10Normal CDF/PDF for probit predictions
anthropic>= 0.40Claude API for email narrative generation

Install all: pip install -r requirements.txt


Evaluation Metrics

MetricWhat It Measures
AUROCDiscrimination ability (1.0 = perfect, 0.5 = random)
Brier ScoreMean squared probability error (lower = better)
Pseudo R-squaredVariance explained vs. intercept-only model
AICFit-complexity tradeoff (lighter penalty)
BICFit-complexity tradeoff (heavier penalty — primary selection criterion)

Known Limitations

  • Trained on ~6 independent recession episodes — limited sample for generalization
  • Assumes future recessions resemble historical patterns — novel mechanisms (pandemics, geopolitical shocks) may not be captured
  • 12-month horizon is long — conditions can change materially within the window
  • FRED data has publication lags (1-3 months) — the latest reading may reflect conditions from 1-2 months ago
  • The model assigns a negative coefficient to inflation, reflecting demand-collapse recessions — this may understate stagflation risk where inflation and growth weakness occur simultaneously
  • Feature selection (BIC) is in-sample — the optimal feature set may differ in future regimes
  • The model should be one input among many — not a sole basis for allocation decisions

References

  1. Estrella, A. & Mishkin, F.S. (1998). "Predicting U.S. Recessions: Financial Variables as Leading Indicators." Review of Economics and Statistics, 80(1), 45-61.

  2. Wright, J.H. (2006). "The Yield Curve and Predicting Recessions." Federal Reserve Board FEDS Working Paper No. 2006-07.

  3. Kauppi, H. & Saikkonen, P. (2008). "Predicting U.S. Recessions with Dynamic Binary Response Models." Review of Economics and Statistics, 90(4), 777-791.

  4. Berge, T.J. (2014). "Predicting Recessions with Leading Indicators: Model Averaging and Links to the Financial Crisis." Federal Reserve Bank of Kansas City Working Paper.

  5. Berge, T.J. & Jorda, O. (2011). "Evaluating the Classification of Economic Activity into Recessions and Expansions." American Economic Journal: Macroeconomics.

  6. Federal Reserve Board FEDS Notes (2018, 2019). Comparative evaluation of six probit recession models.

  7. Boston Fed (2020). On dispersion in predicted recession probabilities from dependent variable construction choices.

  8. McCracken, M.W. & Ng, S. (2016). "FRED-MD: A Monthly Database for Macroeconomic Research." Journal of Business & Economic Statistics, 34(4), 574-589.

  9. Sahm, C. (2019). "Direct Stimulus Payments to Individuals." Brookings Institution. — Introduced the Sahm Rule.

  10. Bellego, C. & Ferrara, L. (2009). "Forecasting Euro Area Recessions Using Time-Varying Binary Response Models for Financial Variables." ECB Working Paper.


Contributing

Contributions are welcome. If you'd like to extend the model:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/your-feature)
  3. Make your changes and test locally with python automation/daily_report.py
  4. Submit a pull request with a clear description of what changed and why

Areas where contributions would be particularly valuable:

  • Additional model specifications (dynamic probit, Bayesian Model Averaging)
  • Alternative data sources beyond FRED
  • International recession models (EU, UK, Japan)
  • Dashboard/web UI for the weekly report

Disclaimer

This project is for educational and research purposes only. It is not financial advice, investment advice, or a recommendation to buy, sell, or hold any security or financial instrument. The model output should not be used as the sole basis for any investment decision. Past recession-prediction accuracy does not guarantee future performance. Economic models are inherently uncertain and can fail without warning, particularly during novel economic conditions. The authors assume no liability for any financial losses incurred from the use of this model. Consult a qualified financial advisor before making investment decisions.


License

MIT License. See LICENSE for details.


Suggested Repository Topics

recessionmacroeconomicsprobityield-curvefred-apieconomic-forecastingrecession-probabilitynbertime-seriespythonstatsmodelsclaude-apigithub-actions

About

Estimates 12-month-ahead U.S. recession probability using a five-model ensemble across 37 Federal Reserve indicators. Generates automated weekly investment committee briefings with embedded charts via GitHub Actions and Claude API.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

U.S. Recession Probability Model — 12-Month Ahead

License: MITPython 3.8+Open In ColabGitHub starsWeekly Report

A five-model ensemble that estimates the probability of a U.S. recession occurring within the next 12 months, using 37 FRED indicators across eight macroeconomic categories. Generates an automated weekly investment committee briefing with embedded charts via Claude API.

Built on the academic framework established by Estrella and Mishkin (1996, 1998) and currently used by the New York Fed and Cleveland Fed.


What This Does

Every Monday morning, a GitHub Actions pipeline:

  1. Pulls the latest data from the Federal Reserve's FRED database (37 indicators)
  2. Runs a probit regression with BIC-based feature selection and economic sign constraints
  3. Computes a five-model ensemble probability with bootstrap confidence intervals
  4. Generates 7 charts covering probability trends, indicator dashboards, model comparison, sensitivity triggers, and historical context
  5. Sends Claude API the model output + charts, which writes a structured investment committee memo
  6. Delivers the memo via email with all charts embedded inline

The ensemble averages across five methodologically distinct models: NY Fed spread-only, Wright two-factor, BIC-selected multivariate, Estrella-Mishkin closed-form, and Chauvet-Piger Markov-switching.


Quick Start

Option A: Google Colab (interactive exploration)

  1. Open Recession_Probability_Model.ipynb in Google Colab
  2. Get a free FRED API key at https://fred.stlouisfed.org/docs/api/fred/
  3. Run all cells — handles installation, data fetching, modeling, and visualization

Option B: Automated weekly reports (fork and deploy)

  1. Fork this repository

  2. Add GitHub Secrets (Settings > Secrets and variables > Actions):

    SecretRequiredDescription
    FRED_API_KEYYesFree key from https://fred.stlouisfed.org/docs/api/fred/
    ANTHROPIC_API_KEYYesClaude API key from https://console.anthropic.com/
    MAIL_USERNAMENoGmail address for sending reports
    MAIL_PASSWORDNoGmail app password (from https://myaccount.google.com/apppasswords)
    MAIL_PORTNoSMTP port, typically 587
    EMAIL_TONoRecipient email(s), comma-separated
  3. Enable the workflow: Actions tab > "Weekly Recession Probability Report" > Enable

  4. Test: Click "Run workflow" to trigger immediately

Without Gmail credentials, the email report is saved as an HTML file in the workflow artifacts.

Option C: Run locally

git clone https://github.com/SecondOrderEdge/Recession_Probability_Model.git
cd Recession_Probability_Model
pip install -r requirements.txt
export FRED_API_KEY="your-key"export ANTHROPIC_API_KEY="your-key"
python automation/daily_report.py # Fetch data, run model, generate charts
python automation/generate_email.py # Generate email via Claude API

Output files are written to automation/output/.


How It Works

The Probit Framework

The core statistical model is a probit regression:

P(Recession_{t+12} = 1 | X_t) = Phi(a_0 + a_1 * X_t)

where Phi(.) is the standard normal CDF, X_t is a vector of economic indicators observed at time t, and the forecast horizon is 12 months. The probit maps a linear combination of indicators into a probability bounded between 0 and 1, connecting naturally to latent-variable models where an unobserved "economic health" index crosses a threshold during recessions.

Five-Model Ensemble

Rather than relying on any single specification, the headline probability is an equal-weighted average of five methodologically distinct models:

ModelFeaturesMethodologyReference
NY Fed BaselineYield curve spread onlyRe-estimated probitEstrella & Mishkin (1998)
Wright ExtensionSpread + Federal Funds RateRe-estimated probitWright (2006)
BIC-SelectedData-driven optimal setRe-estimated probit with sign constraintsForward stepwise BIC
Estrella-MishkinYield curve spreadClosed-form with 2006 parametersEstrella & Trubin (2006)
Chauvet-PigerMarkov-switching modelIndependent FRED series (RECPROUSM156N)Chauvet & Piger

This diversifies across model complexity (1 variable to 7+), estimation approach (re-estimated vs. frozen parameters vs. Markov-switching), and the fundamental question of whether the yield curve alone is sufficient or multi-factor models add value.

Feature Selection: BIC with Sign Constraints

Recessions are rare (~15% of months since 1967). With 30+ candidate features and only ~6 recession episodes in the sample, overfitting is the primary risk. The model uses forward stepwise BIC selection with three safeguards:

  1. BIC penalty: Penalizes complexity more aggressively than AIC, enforcing the parsimony that Berge (2014) showed dominates at the 12-month horizon
  2. Separation detection: Rejects any feature combination that produces quasi-complete separation (coefficients > 100, nan standard errors, or pseudo R-squared > 0.99)
  3. Economic sign constraints: Ensures coefficients align with theory before accepting a candidate:
IndicatorRequired SignEconomic Logic
SPREADNegativeLower spread = higher recession risk
UNRATE_CHG3PositiveRising unemployment = higher recession risk
UMCSENTNegativeLower sentiment = higher recession risk
BUSLOANS_YOYNegativeCredit contraction = higher recession risk

If no valid combination passes all three checks, the model falls back to the Wright two-variable specification (spread + fed funds rate).

Dependent Variable Construction

The dependent variable is configurable:

  • Point-in-time ("point"): y_t = 1 if in recession at month t+12. Used by the NY Fed.
  • Any-in-window ("window"): y_t = 1 if recession occurs at any point during months t+1 through t+12. Produces higher, more persistent probabilities.

The Boston Fed (2020) documented "considerable dispersion" between these approaches. The notebook compares both side-by-side.

Variable Transformations

Transforms are metadata-driven via the SERIES_CONFIG dictionary:

  • Year-over-year percent change ("yoy"): For non-stationary level series (INDPRO, CPI, Housing Starts, Payrolls). Removes trend, preserves cyclical signal.
  • Levels ("level"): For stationary/bounded series (spreads, rates, normalized indexes).
  • Derived features: SPREAD (= GS10 - TB3MS) for pre-1982 monthly history; UNRATE_CHG3 for Sahm-style unemployment momentum.

Estimation: Expanding Windows

Uses expanding-window (not rolling) estimation because recessions are too rare for rolling windows to produce stable estimates. Minimum training window: 120 months (10 years). Each month's probability is generated from a model trained only on data available at that point — no lookahead bias.

Robustness Checks

The notebook includes five robustness checks:

  1. Bootstrap 90% CI — 1,000 resamples to quantify uncertainty around the point estimate
  2. Leave-one-recession-out — Trains on all recessions except one, tests detection on the held-out episode
  3. Penalized probit — L2-regularized logistic regression to verify quasi-separation isn't distorting estimates
  4. Model consensus — Measures agreement across all five specifications
  5. Sensitivity triggers — Binary search for the exact indicator value that would push probability to 30% or 50%

Trend Attribution

The weekly report decomposes the 24-month probability change into per-indicator contributions using partial effects (coefficient x change in variable x normal PDF at the current linear index). This identifies which indicators are driving the probability up or down.


Data Universe — 37 FRED Series Across 8 Categories

CategorySeriesTransform
National ActivityCFNAI, CFNAIMA3, GDPC1, USSLINDLevel / YoY
IndustrialINDPRO, BSCICP02USM460S (OECD Mfg Confidence), TCU, DGORDER, IPMANYoY / Level
ConsumerUMCSENT, PCECC96, DSPIC96, RSAFSLevel / YoY
Labor MarketUNRATE, ICSA, PAYEMS, JTSJOLLevel / YoY
InflationCPIAUCSL, PCEPILFE, PCEPI, CPILFESL, PPIACOYoY
HousingHOUST, PERMIT, HSN1F, CSUSHPISAYoY
Banking/CreditBAA10YM, BUSLOANS, DRALACBS, DRTSCILMLevel / YoY
YieldsT10Y3M, T10Y2Y, GS10, TB3MS, FEDFUNDSLevel

Non-monthly series are resampled: weekly (ICSA) to monthly mean, daily (T10Y3M, T10Y2Y) to month-end, quarterly (GDPC1, DRALACBS, DRTSCILM) forward-filled to monthly. Features with less than 80% coverage of the target period are excluded to prevent short-history series from shrinking the sample.


Weekly Email Report

The automated email includes:

SectionContent
IC SummarySnapshot table (probability, direction, risk driver, offset), model range, portfolio positioning (equities, fixed income, credit, hedging)
Executive SummaryEnsemble headline, model consensus, divergence framing
Key IndicatorsFour macro buckets (Growth, Inflation, Policy, Market Signals) — two sentences each
Model DivergenceStructured yield curve analysis: historical track record, three structural factors (QE, foreign CB demand, Basel III), judgment call
WatchlistTrigger levels: exact values each indicator needs to reach for 30%/50% probability, ranked by proximity
Adverse ScenarioTail risk classification, three real-world triggers, hedging framework tied to ensemble level
What Would Change Our ViewFive hardcoded thresholds (spread < -1%, core CPI < 1.5%, housing -15% YoY, claims > 300K, ensemble > 20%)
Data Currency NoticeData-through date and lagged series disclosure

Seven charts embedded inline: probability gauge, ensemble trend, indicator percentile dashboard, model comparison, indicator sparklines, full historical probability, and sensitivity trigger levels.


Configuration

All modeling choices are set in a single configuration block:

ParameterDefaultDescription
TARGET_DEFINITION"point""point" = recession at month t+12; "window" = any recession in months t+1 through t+12
OBS_START"1967-01-01"Observation start date
MIN_WINDOW120Minimum expanding-window training size (months)
MAX_FEATURES_BIC9Maximum features for BIC selection
THRESHOLD_WARNING30Warning probability level (%)
THRESHOLD_ELEVATED50Elevated probability level (%)

Project Structure

Recession_Probability_Model/
├── Recession_Probability_Model.ipynb # Interactive notebook (Google Colab)
├── automation/
│ ├── daily_report.py # Model run, charts, summary JSON
│ ├── generate_email.py # Claude API email composition + Gmail delivery
│ └── output/ # Generated charts, summaries, emails
├── .github/workflows/
│ └── daily_recession_report.yml # GitHub Actions weekly schedule
├── requirements.txt
├── .gitignore
├── LICENSE # MIT
└── README.md

Dependencies

PackageVersionPurpose
fredapi>= 0.5.0FRED API data access
statsmodels>= 0.14Probit regression, marginal effects, summary statistics
scikit-learn>= 1.3AUROC and Brier Score evaluation
matplotlib>= 3.7Charts and visualizations
pandas>= 2.0Data manipulation and time series alignment
numpy>= 1.24Numerical operations
scipy>= 1.10Normal CDF/PDF for probit predictions
anthropic>= 0.40Claude API for email narrative generation

Install all: pip install -r requirements.txt


Evaluation Metrics

MetricWhat It Measures
AUROCDiscrimination ability (1.0 = perfect, 0.5 = random)
Brier ScoreMean squared probability error (lower = better)
Pseudo R-squaredVariance explained vs. intercept-only model
AICFit-complexity tradeoff (lighter penalty)
BICFit-complexity tradeoff (heavier penalty — primary selection criterion)

Known Limitations

  • Trained on ~6 independent recession episodes — limited sample for generalization
  • Assumes future recessions resemble historical patterns — novel mechanisms (pandemics, geopolitical shocks) may not be captured
  • 12-month horizon is long — conditions can change materially within the window
  • FRED data has publication lags (1-3 months) — the latest reading may reflect conditions from 1-2 months ago
  • The model assigns a negative coefficient to inflation, reflecting demand-collapse recessions — this may understate stagflation risk where inflation and growth weakness occur simultaneously
  • Feature selection (BIC) is in-sample — the optimal feature set may differ in future regimes
  • The model should be one input among many — not a sole basis for allocation decisions

References

  1. Estrella, A. & Mishkin, F.S. (1998). "Predicting U.S. Recessions: Financial Variables as Leading Indicators." Review of Economics and Statistics, 80(1), 45-61.

  2. Wright, J.H. (2006). "The Yield Curve and Predicting Recessions." Federal Reserve Board FEDS Working Paper No. 2006-07.

  3. Kauppi, H. & Saikkonen, P. (2008). "Predicting U.S. Recessions with Dynamic Binary Response Models." Review of Economics and Statistics, 90(4), 777-791.

  4. Berge, T.J. (2014). "Predicting Recessions with Leading Indicators: Model Averaging and Links to the Financial Crisis." Federal Reserve Bank of Kansas City Working Paper.

  5. Berge, T.J. & Jorda, O. (2011). "Evaluating the Classification of Economic Activity into Recessions and Expansions." American Economic Journal: Macroeconomics.

  6. Federal Reserve Board FEDS Notes (2018, 2019). Comparative evaluation of six probit recession models.

  7. Boston Fed (2020). On dispersion in predicted recession probabilities from dependent variable construction choices.

  8. McCracken, M.W. & Ng, S. (2016). "FRED-MD: A Monthly Database for Macroeconomic Research." Journal of Business & Economic Statistics, 34(4), 574-589.

  9. Sahm, C. (2019). "Direct Stimulus Payments to Individuals." Brookings Institution. — Introduced the Sahm Rule.

  10. Bellego, C. & Ferrara, L. (2009). "Forecasting Euro Area Recessions Using Time-Varying Binary Response Models for Financial Variables." ECB Working Paper.


Contributing

Contributions are welcome. If you'd like to extend the model:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/your-feature)
  3. Make your changes and test locally with python automation/daily_report.py
  4. Submit a pull request with a clear description of what changed and why

Areas where contributions would be particularly valuable:

  • Additional model specifications (dynamic probit, Bayesian Model Averaging)
  • Alternative data sources beyond FRED
  • International recession models (EU, UK, Japan)
  • Dashboard/web UI for the weekly report

Disclaimer

This project is for educational and research purposes only. It is not financial advice, investment advice, or a recommendation to buy, sell, or hold any security or financial instrument. The model output should not be used as the sole basis for any investment decision. Past recession-prediction accuracy does not guarantee future performance. Economic models are inherently uncertain and can fail without warning, particularly during novel economic conditions. The authors assume no liability for any financial losses incurred from the use of this model. Consult a qualified financial advisor before making investment decisions.


License

MIT License. See LICENSE for details.


Suggested Repository Topics

recessionmacroeconomicsprobityield-curvefred-apieconomic-forecastingrecession-probabilitynbertime-seriespythonstatsmodelsclaude-apigithub-actions

About

Estimates 12-month-ahead U.S. recession probability using a five-model ensemble across 37 Federal Reserve indicators. Generates automated weekly investment committee briefings with embedded charts via GitHub Actions and Claude API.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

U.S. Recession Probability Model — 12-Month Ahead

License: MITPython 3.8+Open In ColabGitHub starsWeekly Report

A five-model ensemble that estimates the probability of a U.S. recession occurring within the next 12 months, using 37 FRED indicators across eight macroeconomic categories. Generates an automated weekly investment committee briefing with embedded charts via Claude API.

Built on the academic framework established by Estrella and Mishkin (1996, 1998) and currently used by the New York Fed and Cleveland Fed.


What This Does

Every Monday morning, a GitHub Actions pipeline:

  1. Pulls the latest data from the Federal Reserve's FRED database (37 indicators)
  2. Runs a probit regression with BIC-based feature selection and economic sign constraints
  3. Computes a five-model ensemble probability with bootstrap confidence intervals
  4. Generates 7 charts covering probability trends, indicator dashboards, model comparison, sensitivity triggers, and historical context
  5. Sends Claude API the model output + charts, which writes a structured investment committee memo
  6. Delivers the memo via email with all charts embedded inline

The ensemble averages across five methodologically distinct models: NY Fed spread-only, Wright two-factor, BIC-selected multivariate, Estrella-Mishkin closed-form, and Chauvet-Piger Markov-switching.


Quick Start

Option A: Google Colab (interactive exploration)

  1. Open Recession_Probability_Model.ipynb in Google Colab
  2. Get a free FRED API key at https://fred.stlouisfed.org/docs/api/fred/
  3. Run all cells — handles installation, data fetching, modeling, and visualization

Option B: Automated weekly reports (fork and deploy)

  1. Fork this repository

  2. Add GitHub Secrets (Settings > Secrets and variables > Actions):

    SecretRequiredDescription
    FRED_API_KEYYesFree key from https://fred.stlouisfed.org/docs/api/fred/
    ANTHROPIC_API_KEYYesClaude API key from https://console.anthropic.com/
    MAIL_USERNAMENoGmail address for sending reports
    MAIL_PASSWORDNoGmail app password (from https://myaccount.google.com/apppasswords)
    MAIL_PORTNoSMTP port, typically 587
    EMAIL_TONoRecipient email(s), comma-separated
  3. Enable the workflow: Actions tab > "Weekly Recession Probability Report" > Enable

  4. Test: Click "Run workflow" to trigger immediately

Without Gmail credentials, the email report is saved as an HTML file in the workflow artifacts.

Option C: Run locally

git clone https://github.com/SecondOrderEdge/Recession_Probability_Model.git
cd Recession_Probability_Model
pip install -r requirements.txt
export FRED_API_KEY="your-key"export ANTHROPIC_API_KEY="your-key"
python automation/daily_report.py # Fetch data, run model, generate charts
python automation/generate_email.py # Generate email via Claude API

Output files are written to automation/output/.


How It Works

The Probit Framework

The core statistical model is a probit regression:

P(Recession_{t+12} = 1 | X_t) = Phi(a_0 + a_1 * X_t)

where Phi(.) is the standard normal CDF, X_t is a vector of economic indicators observed at time t, and the forecast horizon is 12 months. The probit maps a linear combination of indicators into a probability bounded between 0 and 1, connecting naturally to latent-variable models where an unobserved "economic health" index crosses a threshold during recessions.

Five-Model Ensemble

Rather than relying on any single specification, the headline probability is an equal-weighted average of five methodologically distinct models:

ModelFeaturesMethodologyReference
NY Fed BaselineYield curve spread onlyRe-estimated probitEstrella & Mishkin (1998)
Wright ExtensionSpread + Federal Funds RateRe-estimated probitWright (2006)
BIC-SelectedData-driven optimal setRe-estimated probit with sign constraintsForward stepwise BIC
Estrella-MishkinYield curve spreadClosed-form with 2006 parametersEstrella & Trubin (2006)
Chauvet-PigerMarkov-switching modelIndependent FRED series (RECPROUSM156N)Chauvet & Piger

This diversifies across model complexity (1 variable to 7+), estimation approach (re-estimated vs. frozen parameters vs. Markov-switching), and the fundamental question of whether the yield curve alone is sufficient or multi-factor models add value.

Feature Selection: BIC with Sign Constraints

Recessions are rare (~15% of months since 1967). With 30+ candidate features and only ~6 recession episodes in the sample, overfitting is the primary risk. The model uses forward stepwise BIC selection with three safeguards:

  1. BIC penalty: Penalizes complexity more aggressively than AIC, enforcing the parsimony that Berge (2014) showed dominates at the 12-month horizon
  2. Separation detection: Rejects any feature combination that produces quasi-complete separation (coefficients > 100, nan standard errors, or pseudo R-squared > 0.99)
  3. Economic sign constraints: Ensures coefficients align with theory before accepting a candidate:
IndicatorRequired SignEconomic Logic
SPREADNegativeLower spread = higher recession risk
UNRATE_CHG3PositiveRising unemployment = higher recession risk
UMCSENTNegativeLower sentiment = higher recession risk
BUSLOANS_YOYNegativeCredit contraction = higher recession risk

If no valid combination passes all three checks, the model falls back to the Wright two-variable specification (spread + fed funds rate).

Dependent Variable Construction

The dependent variable is configurable:

  • Point-in-time ("point"): y_t = 1 if in recession at month t+12. Used by the NY Fed.
  • Any-in-window ("window"): y_t = 1 if recession occurs at any point during months t+1 through t+12. Produces higher, more persistent probabilities.

The Boston Fed (2020) documented "considerable dispersion" between these approaches. The notebook compares both side-by-side.

Variable Transformations

Transforms are metadata-driven via the SERIES_CONFIG dictionary:

  • Year-over-year percent change ("yoy"): For non-stationary level series (INDPRO, CPI, Housing Starts, Payrolls). Removes trend, preserves cyclical signal.
  • Levels ("level"): For stationary/bounded series (spreads, rates, normalized indexes).
  • Derived features: SPREAD (= GS10 - TB3MS) for pre-1982 monthly history; UNRATE_CHG3 for Sahm-style unemployment momentum.

Estimation: Expanding Windows

Uses expanding-window (not rolling) estimation because recessions are too rare for rolling windows to produce stable estimates. Minimum training window: 120 months (10 years). Each month's probability is generated from a model trained only on data available at that point — no lookahead bias.

Robustness Checks

The notebook includes five robustness checks:

  1. Bootstrap 90% CI — 1,000 resamples to quantify uncertainty around the point estimate
  2. Leave-one-recession-out — Trains on all recessions except one, tests detection on the held-out episode
  3. Penalized probit — L2-regularized logistic regression to verify quasi-separation isn't distorting estimates
  4. Model consensus — Measures agreement across all five specifications
  5. Sensitivity triggers — Binary search for the exact indicator value that would push probability to 30% or 50%

Trend Attribution

The weekly report decomposes the 24-month probability change into per-indicator contributions using partial effects (coefficient x change in variable x normal PDF at the current linear index). This identifies which indicators are driving the probability up or down.


Data Universe — 37 FRED Series Across 8 Categories

CategorySeriesTransform
National ActivityCFNAI, CFNAIMA3, GDPC1, USSLINDLevel / YoY
IndustrialINDPRO, BSCICP02USM460S (OECD Mfg Confidence), TCU, DGORDER, IPMANYoY / Level
ConsumerUMCSENT, PCECC96, DSPIC96, RSAFSLevel / YoY
Labor MarketUNRATE, ICSA, PAYEMS, JTSJOLLevel / YoY
InflationCPIAUCSL, PCEPILFE, PCEPI, CPILFESL, PPIACOYoY
HousingHOUST, PERMIT, HSN1F, CSUSHPISAYoY
Banking/CreditBAA10YM, BUSLOANS, DRALACBS, DRTSCILMLevel / YoY
YieldsT10Y3M, T10Y2Y, GS10, TB3MS, FEDFUNDSLevel

Non-monthly series are resampled: weekly (ICSA) to monthly mean, daily (T10Y3M, T10Y2Y) to month-end, quarterly (GDPC1, DRALACBS, DRTSCILM) forward-filled to monthly. Features with less than 80% coverage of the target period are excluded to prevent short-history series from shrinking the sample.


Weekly Email Report

The automated email includes:

SectionContent
IC SummarySnapshot table (probability, direction, risk driver, offset), model range, portfolio positioning (equities, fixed income, credit, hedging)
Executive SummaryEnsemble headline, model consensus, divergence framing
Key IndicatorsFour macro buckets (Growth, Inflation, Policy, Market Signals) — two sentences each
Model DivergenceStructured yield curve analysis: historical track record, three structural factors (QE, foreign CB demand, Basel III), judgment call
WatchlistTrigger levels: exact values each indicator needs to reach for 30%/50% probability, ranked by proximity
Adverse ScenarioTail risk classification, three real-world triggers, hedging framework tied to ensemble level
What Would Change Our ViewFive hardcoded thresholds (spread < -1%, core CPI < 1.5%, housing -15% YoY, claims > 300K, ensemble > 20%)
Data Currency NoticeData-through date and lagged series disclosure

Seven charts embedded inline: probability gauge, ensemble trend, indicator percentile dashboard, model comparison, indicator sparklines, full historical probability, and sensitivity trigger levels.


Configuration

All modeling choices are set in a single configuration block:

ParameterDefaultDescription
TARGET_DEFINITION"point""point" = recession at month t+12; "window" = any recession in months t+1 through t+12
OBS_START"1967-01-01"Observation start date
MIN_WINDOW120Minimum expanding-window training size (months)
MAX_FEATURES_BIC9Maximum features for BIC selection
THRESHOLD_WARNING30Warning probability level (%)
THRESHOLD_ELEVATED50Elevated probability level (%)

Project Structure

Recession_Probability_Model/
├── Recession_Probability_Model.ipynb # Interactive notebook (Google Colab)
├── automation/
│ ├── daily_report.py # Model run, charts, summary JSON
│ ├── generate_email.py # Claude API email composition + Gmail delivery
│ └── output/ # Generated charts, summaries, emails
├── .github/workflows/
│ └── daily_recession_report.yml # GitHub Actions weekly schedule
├── requirements.txt
├── .gitignore
├── LICENSE # MIT
└── README.md

Dependencies

PackageVersionPurpose
fredapi>= 0.5.0FRED API data access
statsmodels>= 0.14Probit regression, marginal effects, summary statistics
scikit-learn>= 1.3AUROC and Brier Score evaluation
matplotlib>= 3.7Charts and visualizations
pandas>= 2.0Data manipulation and time series alignment
numpy>= 1.24Numerical operations
scipy>= 1.10Normal CDF/PDF for probit predictions
anthropic>= 0.40Claude API for email narrative generation

Install all: pip install -r requirements.txt


Evaluation Metrics

MetricWhat It Measures
AUROCDiscrimination ability (1.0 = perfect, 0.5 = random)
Brier ScoreMean squared probability error (lower = better)
Pseudo R-squaredVariance explained vs. intercept-only model
AICFit-complexity tradeoff (lighter penalty)
BICFit-complexity tradeoff (heavier penalty — primary selection criterion)

Known Limitations

  • Trained on ~6 independent recession episodes — limited sample for generalization
  • Assumes future recessions resemble historical patterns — novel mechanisms (pandemics, geopolitical shocks) may not be captured
  • 12-month horizon is long — conditions can change materially within the window
  • FRED data has publication lags (1-3 months) — the latest reading may reflect conditions from 1-2 months ago
  • The model assigns a negative coefficient to inflation, reflecting demand-collapse recessions — this may understate stagflation risk where inflation and growth weakness occur simultaneously
  • Feature selection (BIC) is in-sample — the optimal feature set may differ in future regimes
  • The model should be one input among many — not a sole basis for allocation decisions

References

  1. Estrella, A. & Mishkin, F.S. (1998). "Predicting U.S. Recessions: Financial Variables as Leading Indicators." Review of Economics and Statistics, 80(1), 45-61.

  2. Wright, J.H. (2006). "The Yield Curve and Predicting Recessions." Federal Reserve Board FEDS Working Paper No. 2006-07.

  3. Kauppi, H. & Saikkonen, P. (2008). "Predicting U.S. Recessions with Dynamic Binary Response Models." Review of Economics and Statistics, 90(4), 777-791.

  4. Berge, T.J. (2014). "Predicting Recessions with Leading Indicators: Model Averaging and Links to the Financial Crisis." Federal Reserve Bank of Kansas City Working Paper.

  5. Berge, T.J. & Jorda, O. (2011). "Evaluating the Classification of Economic Activity into Recessions and Expansions." American Economic Journal: Macroeconomics.

  6. Federal Reserve Board FEDS Notes (2018, 2019). Comparative evaluation of six probit recession models.

  7. Boston Fed (2020). On dispersion in predicted recession probabilities from dependent variable construction choices.

  8. McCracken, M.W. & Ng, S. (2016). "FRED-MD: A Monthly Database for Macroeconomic Research." Journal of Business & Economic Statistics, 34(4), 574-589.

  9. Sahm, C. (2019). "Direct Stimulus Payments to Individuals." Brookings Institution. — Introduced the Sahm Rule.

  10. Bellego, C. & Ferrara, L. (2009). "Forecasting Euro Area Recessions Using Time-Varying Binary Response Models for Financial Variables." ECB Working Paper.


Contributing

Contributions are welcome. If you'd like to extend the model:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/your-feature)
  3. Make your changes and test locally with python automation/daily_report.py
  4. Submit a pull request with a clear description of what changed and why

Areas where contributions would be particularly valuable:

  • Additional model specifications (dynamic probit, Bayesian Model Averaging)
  • Alternative data sources beyond FRED
  • International recession models (EU, UK, Japan)
  • Dashboard/web UI for the weekly report

Disclaimer

This project is for educational and research purposes only. It is not financial advice, investment advice, or a recommendation to buy, sell, or hold any security or financial instrument. The model output should not be used as the sole basis for any investment decision. Past recession-prediction accuracy does not guarantee future performance. Economic models are inherently uncertain and can fail without warning, particularly during novel economic conditions. The authors assume no liability for any financial losses incurred from the use of this model. Consult a qualified financial advisor before making investment decisions.


License

MIT License. See LICENSE for details.


Suggested Repository Topics

recessionmacroeconomicsprobityield-curvefred-apieconomic-forecastingrecession-probabilitynbertime-seriespythonstatsmodelsclaude-apigithub-actions

About

Estimates 12-month-ahead U.S. recession probability using a five-model ensemble across 37 Federal Reserve indicators. Generates automated weekly investment committee briefings with embedded charts via GitHub Actions and Claude API.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

U.S. Recession Probability Model — 12-Month Ahead

License: MITPython 3.8+Open In ColabGitHub starsWeekly Report

A five-model ensemble that estimates the probability of a U.S. recession occurring within the next 12 months, using 37 FRED indicators across eight macroeconomic categories. Generates an automated weekly investment committee briefing with embedded charts via Claude API.

Built on the academic framework established by Estrella and Mishkin (1996, 1998) and currently used by the New York Fed and Cleveland Fed.


What This Does

Every Monday morning, a GitHub Actions pipeline:

  1. Pulls the latest data from the Federal Reserve's FRED database (37 indicators)
  2. Runs a probit regression with BIC-based feature selection and economic sign constraints
  3. Computes a five-model ensemble probability with bootstrap confidence intervals
  4. Generates 7 charts covering probability trends, indicator dashboards, model comparison, sensitivity triggers, and historical context
  5. Sends Claude API the model output + charts, which writes a structured investment committee memo
  6. Delivers the memo via email with all charts embedded inline

The ensemble averages across five methodologically distinct models: NY Fed spread-only, Wright two-factor, BIC-selected multivariate, Estrella-Mishkin closed-form, and Chauvet-Piger Markov-switching.


Quick Start

Option A: Google Colab (interactive exploration)

  1. Open Recession_Probability_Model.ipynb in Google Colab
  2. Get a free FRED API key at https://fred.stlouisfed.org/docs/api/fred/
  3. Run all cells — handles installation, data fetching, modeling, and visualization

Option B: Automated weekly reports (fork and deploy)

  1. Fork this repository

  2. Add GitHub Secrets (Settings > Secrets and variables > Actions):

    SecretRequiredDescription
    FRED_API_KEYYesFree key from https://fred.stlouisfed.org/docs/api/fred/
    ANTHROPIC_API_KEYYesClaude API key from https://console.anthropic.com/
    MAIL_USERNAMENoGmail address for sending reports
    MAIL_PASSWORDNoGmail app password (from https://myaccount.google.com/apppasswords)
    MAIL_PORTNoSMTP port, typically 587
    EMAIL_TONoRecipient email(s), comma-separated
  3. Enable the workflow: Actions tab > "Weekly Recession Probability Report" > Enable

  4. Test: Click "Run workflow" to trigger immediately

Without Gmail credentials, the email report is saved as an HTML file in the workflow artifacts.

Option C: Run locally

git clone https://github.com/SecondOrderEdge/Recession_Probability_Model.git
cd Recession_Probability_Model
pip install -r requirements.txt
export FRED_API_KEY="your-key"export ANTHROPIC_API_KEY="your-key"
python automation/daily_report.py # Fetch data, run model, generate charts
python automation/generate_email.py # Generate email via Claude API

Output files are written to automation/output/.


How It Works

The Probit Framework

The core statistical model is a probit regression:

P(Recession_{t+12} = 1 | X_t) = Phi(a_0 + a_1 * X_t)

where Phi(.) is the standard normal CDF, X_t is a vector of economic indicators observed at time t, and the forecast horizon is 12 months. The probit maps a linear combination of indicators into a probability bounded between 0 and 1, connecting naturally to latent-variable models where an unobserved "economic health" index crosses a threshold during recessions.

Five-Model Ensemble

Rather than relying on any single specification, the headline probability is an equal-weighted average of five methodologically distinct models:

ModelFeaturesMethodologyReference
NY Fed BaselineYield curve spread onlyRe-estimated probitEstrella & Mishkin (1998)
Wright ExtensionSpread + Federal Funds RateRe-estimated probitWright (2006)
BIC-SelectedData-driven optimal setRe-estimated probit with sign constraintsForward stepwise BIC
Estrella-MishkinYield curve spreadClosed-form with 2006 parametersEstrella & Trubin (2006)
Chauvet-PigerMarkov-switching modelIndependent FRED series (RECPROUSM156N)Chauvet & Piger

This diversifies across model complexity (1 variable to 7+), estimation approach (re-estimated vs. frozen parameters vs. Markov-switching), and the fundamental question of whether the yield curve alone is sufficient or multi-factor models add value.

Feature Selection: BIC with Sign Constraints

Recessions are rare (~15% of months since 1967). With 30+ candidate features and only ~6 recession episodes in the sample, overfitting is the primary risk. The model uses forward stepwise BIC selection with three safeguards:

  1. BIC penalty: Penalizes complexity more aggressively than AIC, enforcing the parsimony that Berge (2014) showed dominates at the 12-month horizon
  2. Separation detection: Rejects any feature combination that produces quasi-complete separation (coefficients > 100, nan standard errors, or pseudo R-squared > 0.99)
  3. Economic sign constraints: Ensures coefficients align with theory before accepting a candidate:
IndicatorRequired SignEconomic Logic
SPREADNegativeLower spread = higher recession risk
UNRATE_CHG3PositiveRising unemployment = higher recession risk
UMCSENTNegativeLower sentiment = higher recession risk
BUSLOANS_YOYNegativeCredit contraction = higher recession risk

If no valid combination passes all three checks, the model falls back to the Wright two-variable specification (spread + fed funds rate).

Dependent Variable Construction

The dependent variable is configurable:

  • Point-in-time ("point"): y_t = 1 if in recession at month t+12. Used by the NY Fed.
  • Any-in-window ("window"): y_t = 1 if recession occurs at any point during months t+1 through t+12. Produces higher, more persistent probabilities.

The Boston Fed (2020) documented "considerable dispersion" between these approaches. The notebook compares both side-by-side.

Variable Transformations

Transforms are metadata-driven via the SERIES_CONFIG dictionary:

  • Year-over-year percent change ("yoy"): For non-stationary level series (INDPRO, CPI, Housing Starts, Payrolls). Removes trend, preserves cyclical signal.
  • Levels ("level"): For stationary/bounded series (spreads, rates, normalized indexes).
  • Derived features: SPREAD (= GS10 - TB3MS) for pre-1982 monthly history; UNRATE_CHG3 for Sahm-style unemployment momentum.

Estimation: Expanding Windows

Uses expanding-window (not rolling) estimation because recessions are too rare for rolling windows to produce stable estimates. Minimum training window: 120 months (10 years). Each month's probability is generated from a model trained only on data available at that point — no lookahead bias.

Robustness Checks

The notebook includes five robustness checks:

  1. Bootstrap 90% CI — 1,000 resamples to quantify uncertainty around the point estimate
  2. Leave-one-recession-out — Trains on all recessions except one, tests detection on the held-out episode
  3. Penalized probit — L2-regularized logistic regression to verify quasi-separation isn't distorting estimates
  4. Model consensus — Measures agreement across all five specifications
  5. Sensitivity triggers — Binary search for the exact indicator value that would push probability to 30% or 50%

Trend Attribution

The weekly report decomposes the 24-month probability change into per-indicator contributions using partial effects (coefficient x change in variable x normal PDF at the current linear index). This identifies which indicators are driving the probability up or down.


Data Universe — 37 FRED Series Across 8 Categories

CategorySeriesTransform
National ActivityCFNAI, CFNAIMA3, GDPC1, USSLINDLevel / YoY
IndustrialINDPRO, BSCICP02USM460S (OECD Mfg Confidence), TCU, DGORDER, IPMANYoY / Level
ConsumerUMCSENT, PCECC96, DSPIC96, RSAFSLevel / YoY
Labor MarketUNRATE, ICSA, PAYEMS, JTSJOLLevel / YoY
InflationCPIAUCSL, PCEPILFE, PCEPI, CPILFESL, PPIACOYoY
HousingHOUST, PERMIT, HSN1F, CSUSHPISAYoY
Banking/CreditBAA10YM, BUSLOANS, DRALACBS, DRTSCILMLevel / YoY
YieldsT10Y3M, T10Y2Y, GS10, TB3MS, FEDFUNDSLevel

Non-monthly series are resampled: weekly (ICSA) to monthly mean, daily (T10Y3M, T10Y2Y) to month-end, quarterly (GDPC1, DRALACBS, DRTSCILM) forward-filled to monthly. Features with less than 80% coverage of the target period are excluded to prevent short-history series from shrinking the sample.


Weekly Email Report

The automated email includes:

SectionContent
IC SummarySnapshot table (probability, direction, risk driver, offset), model range, portfolio positioning (equities, fixed income, credit, hedging)
Executive SummaryEnsemble headline, model consensus, divergence framing
Key IndicatorsFour macro buckets (Growth, Inflation, Policy, Market Signals) — two sentences each
Model DivergenceStructured yield curve analysis: historical track record, three structural factors (QE, foreign CB demand, Basel III), judgment call
WatchlistTrigger levels: exact values each indicator needs to reach for 30%/50% probability, ranked by proximity
Adverse ScenarioTail risk classification, three real-world triggers, hedging framework tied to ensemble level
What Would Change Our ViewFive hardcoded thresholds (spread < -1%, core CPI < 1.5%, housing -15% YoY, claims > 300K, ensemble > 20%)
Data Currency NoticeData-through date and lagged series disclosure

Seven charts embedded inline: probability gauge, ensemble trend, indicator percentile dashboard, model comparison, indicator sparklines, full historical probability, and sensitivity trigger levels.


Configuration

All modeling choices are set in a single configuration block:

ParameterDefaultDescription
TARGET_DEFINITION"point""point" = recession at month t+12; "window" = any recession in months t+1 through t+12
OBS_START"1967-01-01"Observation start date
MIN_WINDOW120Minimum expanding-window training size (months)
MAX_FEATURES_BIC9Maximum features for BIC selection
THRESHOLD_WARNING30Warning probability level (%)
THRESHOLD_ELEVATED50Elevated probability level (%)

Project Structure

Recession_Probability_Model/
├── Recession_Probability_Model.ipynb # Interactive notebook (Google Colab)
├── automation/
│ ├── daily_report.py # Model run, charts, summary JSON
│ ├── generate_email.py # Claude API email composition + Gmail delivery
│ └── output/ # Generated charts, summaries, emails
├── .github/workflows/
│ └── daily_recession_report.yml # GitHub Actions weekly schedule
├── requirements.txt
├── .gitignore
├── LICENSE # MIT
└── README.md

Dependencies

PackageVersionPurpose
fredapi>= 0.5.0FRED API data access
statsmodels>= 0.14Probit regression, marginal effects, summary statistics
scikit-learn>= 1.3AUROC and Brier Score evaluation
matplotlib>= 3.7Charts and visualizations
pandas>= 2.0Data manipulation and time series alignment
numpy>= 1.24Numerical operations
scipy>= 1.10Normal CDF/PDF for probit predictions
anthropic>= 0.40Claude API for email narrative generation

Install all: pip install -r requirements.txt


Evaluation Metrics

MetricWhat It Measures
AUROCDiscrimination ability (1.0 = perfect, 0.5 = random)
Brier ScoreMean squared probability error (lower = better)
Pseudo R-squaredVariance explained vs. intercept-only model
AICFit-complexity tradeoff (lighter penalty)
BICFit-complexity tradeoff (heavier penalty — primary selection criterion)

Known Limitations

  • Trained on ~6 independent recession episodes — limited sample for generalization
  • Assumes future recessions resemble historical patterns — novel mechanisms (pandemics, geopolitical shocks) may not be captured
  • 12-month horizon is long — conditions can change materially within the window
  • FRED data has publication lags (1-3 months) — the latest reading may reflect conditions from 1-2 months ago
  • The model assigns a negative coefficient to inflation, reflecting demand-collapse recessions — this may understate stagflation risk where inflation and growth weakness occur simultaneously
  • Feature selection (BIC) is in-sample — the optimal feature set may differ in future regimes
  • The model should be one input among many — not a sole basis for allocation decisions

References

  1. Estrella, A. & Mishkin, F.S. (1998). "Predicting U.S. Recessions: Financial Variables as Leading Indicators." Review of Economics and Statistics, 80(1), 45-61.

  2. Wright, J.H. (2006). "The Yield Curve and Predicting Recessions." Federal Reserve Board FEDS Working Paper No. 2006-07.

  3. Kauppi, H. & Saikkonen, P. (2008). "Predicting U.S. Recessions with Dynamic Binary Response Models." Review of Economics and Statistics, 90(4), 777-791.

  4. Berge, T.J. (2014). "Predicting Recessions with Leading Indicators: Model Averaging and Links to the Financial Crisis." Federal Reserve Bank of Kansas City Working Paper.

  5. Berge, T.J. & Jorda, O. (2011). "Evaluating the Classification of Economic Activity into Recessions and Expansions." American Economic Journal: Macroeconomics.

  6. Federal Reserve Board FEDS Notes (2018, 2019). Comparative evaluation of six probit recession models.

  7. Boston Fed (2020). On dispersion in predicted recession probabilities from dependent variable construction choices.

  8. McCracken, M.W. & Ng, S. (2016). "FRED-MD: A Monthly Database for Macroeconomic Research." Journal of Business & Economic Statistics, 34(4), 574-589.

  9. Sahm, C. (2019). "Direct Stimulus Payments to Individuals." Brookings Institution. — Introduced the Sahm Rule.

  10. Bellego, C. & Ferrara, L. (2009). "Forecasting Euro Area Recessions Using Time-Varying Binary Response Models for Financial Variables." ECB Working Paper.


Contributing

Contributions are welcome. If you'd like to extend the model:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/your-feature)
  3. Make your changes and test locally with python automation/daily_report.py
  4. Submit a pull request with a clear description of what changed and why

Areas where contributions would be particularly valuable:

  • Additional model specifications (dynamic probit, Bayesian Model Averaging)
  • Alternative data sources beyond FRED
  • International recession models (EU, UK, Japan)
  • Dashboard/web UI for the weekly report

Disclaimer

This project is for educational and research purposes only. It is not financial advice, investment advice, or a recommendation to buy, sell, or hold any security or financial instrument. The model output should not be used as the sole basis for any investment decision. Past recession-prediction accuracy does not guarantee future performance. Economic models are inherently uncertain and can fail without warning, particularly during novel economic conditions. The authors assume no liability for any financial losses incurred from the use of this model. Consult a qualified financial advisor before making investment decisions.


License

MIT License. See LICENSE for details.


Suggested Repository Topics

recessionmacroeconomicsprobityield-curvefred-apieconomic-forecastingrecession-probabilitynbertime-seriespythonstatsmodelsclaude-apigithub-actions

About

Estimates 12-month-ahead U.S. recession probability using a five-model ensemble across 37 Federal Reserve indicators. Generates automated weekly investment committee briefings with embedded charts via GitHub Actions and Claude API.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

U.S. Recession Probability Model — 12-Month Ahead

License: MITPython 3.8+Open In ColabGitHub starsWeekly Report

A five-model ensemble that estimates the probability of a U.S. recession occurring within the next 12 months, using 37 FRED indicators across eight macroeconomic categories. Generates an automated weekly investment committee briefing with embedded charts via Claude API.

Built on the academic framework established by Estrella and Mishkin (1996, 1998) and currently used by the New York Fed and Cleveland Fed.


What This Does

Every Monday morning, a GitHub Actions pipeline:

  1. Pulls the latest data from the Federal Reserve's FRED database (37 indicators)
  2. Runs a probit regression with BIC-based feature selection and economic sign constraints
  3. Computes a five-model ensemble probability with bootstrap confidence intervals
  4. Generates 7 charts covering probability trends, indicator dashboards, model comparison, sensitivity triggers, and historical context
  5. Sends Claude API the model output + charts, which writes a structured investment committee memo
  6. Delivers the memo via email with all charts embedded inline

The ensemble averages across five methodologically distinct models: NY Fed spread-only, Wright two-factor, BIC-selected multivariate, Estrella-Mishkin closed-form, and Chauvet-Piger Markov-switching.


Quick Start

Option A: Google Colab (interactive exploration)

  1. Open Recession_Probability_Model.ipynb in Google Colab
  2. Get a free FRED API key at https://fred.stlouisfed.org/docs/api/fred/
  3. Run all cells — handles installation, data fetching, modeling, and visualization

Option B: Automated weekly reports (fork and deploy)

  1. Fork this repository

  2. Add GitHub Secrets (Settings > Secrets and variables > Actions):

    SecretRequiredDescription
    FRED_API_KEYYesFree key from https://fred.stlouisfed.org/docs/api/fred/
    ANTHROPIC_API_KEYYesClaude API key from https://console.anthropic.com/
    MAIL_USERNAMENoGmail address for sending reports
    MAIL_PASSWORDNoGmail app password (from https://myaccount.google.com/apppasswords)
    MAIL_PORTNoSMTP port, typically 587
    EMAIL_TONoRecipient email(s), comma-separated
  3. Enable the workflow: Actions tab > "Weekly Recession Probability Report" > Enable

  4. Test: Click "Run workflow" to trigger immediately

Without Gmail credentials, the email report is saved as an HTML file in the workflow artifacts.

Option C: Run locally

git clone https://github.com/SecondOrderEdge/Recession_Probability_Model.git
cd Recession_Probability_Model
pip install -r requirements.txt
export FRED_API_KEY="your-key"export ANTHROPIC_API_KEY="your-key"
python automation/daily_report.py # Fetch data, run model, generate charts
python automation/generate_email.py # Generate email via Claude API

Output files are written to automation/output/.


How It Works

The Probit Framework

The core statistical model is a probit regression:

P(Recession_{t+12} = 1 | X_t) = Phi(a_0 + a_1 * X_t)

where Phi(.) is the standard normal CDF, X_t is a vector of economic indicators observed at time t, and the forecast horizon is 12 months. The probit maps a linear combination of indicators into a probability bounded between 0 and 1, connecting naturally to latent-variable models where an unobserved "economic health" index crosses a threshold during recessions.

Five-Model Ensemble

Rather than relying on any single specification, the headline probability is an equal-weighted average of five methodologically distinct models:

ModelFeaturesMethodologyReference
NY Fed BaselineYield curve spread onlyRe-estimated probitEstrella & Mishkin (1998)
Wright ExtensionSpread + Federal Funds RateRe-estimated probitWright (2006)
BIC-SelectedData-driven optimal setRe-estimated probit with sign constraintsForward stepwise BIC
Estrella-MishkinYield curve spreadClosed-form with 2006 parametersEstrella & Trubin (2006)
Chauvet-PigerMarkov-switching modelIndependent FRED series (RECPROUSM156N)Chauvet & Piger

This diversifies across model complexity (1 variable to 7+), estimation approach (re-estimated vs. frozen parameters vs. Markov-switching), and the fundamental question of whether the yield curve alone is sufficient or multi-factor models add value.

Feature Selection: BIC with Sign Constraints

Recessions are rare (~15% of months since 1967). With 30+ candidate features and only ~6 recession episodes in the sample, overfitting is the primary risk. The model uses forward stepwise BIC selection with three safeguards:

  1. BIC penalty: Penalizes complexity more aggressively than AIC, enforcing the parsimony that Berge (2014) showed dominates at the 12-month horizon
  2. Separation detection: Rejects any feature combination that produces quasi-complete separation (coefficients > 100, nan standard errors, or pseudo R-squared > 0.99)
  3. Economic sign constraints: Ensures coefficients align with theory before accepting a candidate:
IndicatorRequired SignEconomic Logic
SPREADNegativeLower spread = higher recession risk
UNRATE_CHG3PositiveRising unemployment = higher recession risk
UMCSENTNegativeLower sentiment = higher recession risk
BUSLOANS_YOYNegativeCredit contraction = higher recession risk

If no valid combination passes all three checks, the model falls back to the Wright two-variable specification (spread + fed funds rate).

Dependent Variable Construction

The dependent variable is configurable:

  • Point-in-time ("point"): y_t = 1 if in recession at month t+12. Used by the NY Fed.
  • Any-in-window ("window"): y_t = 1 if recession occurs at any point during months t+1 through t+12. Produces higher, more persistent probabilities.

The Boston Fed (2020) documented "considerable dispersion" between these approaches. The notebook compares both side-by-side.

Variable Transformations

Transforms are metadata-driven via the SERIES_CONFIG dictionary:

  • Year-over-year percent change ("yoy"): For non-stationary level series (INDPRO, CPI, Housing Starts, Payrolls). Removes trend, preserves cyclical signal.
  • Levels ("level"): For stationary/bounded series (spreads, rates, normalized indexes).
  • Derived features: SPREAD (= GS10 - TB3MS) for pre-1982 monthly history; UNRATE_CHG3 for Sahm-style unemployment momentum.

Estimation: Expanding Windows

Uses expanding-window (not rolling) estimation because recessions are too rare for rolling windows to produce stable estimates. Minimum training window: 120 months (10 years). Each month's probability is generated from a model trained only on data available at that point — no lookahead bias.

Robustness Checks

The notebook includes five robustness checks:

  1. Bootstrap 90% CI — 1,000 resamples to quantify uncertainty around the point estimate
  2. Leave-one-recession-out — Trains on all recessions except one, tests detection on the held-out episode
  3. Penalized probit — L2-regularized logistic regression to verify quasi-separation isn't distorting estimates
  4. Model consensus — Measures agreement across all five specifications
  5. Sensitivity triggers — Binary search for the exact indicator value that would push probability to 30% or 50%

Trend Attribution

The weekly report decomposes the 24-month probability change into per-indicator contributions using partial effects (coefficient x change in variable x normal PDF at the current linear index). This identifies which indicators are driving the probability up or down.


Data Universe — 37 FRED Series Across 8 Categories

CategorySeriesTransform
National ActivityCFNAI, CFNAIMA3, GDPC1, USSLINDLevel / YoY
IndustrialINDPRO, BSCICP02USM460S (OECD Mfg Confidence), TCU, DGORDER, IPMANYoY / Level
ConsumerUMCSENT, PCECC96, DSPIC96, RSAFSLevel / YoY
Labor MarketUNRATE, ICSA, PAYEMS, JTSJOLLevel / YoY
InflationCPIAUCSL, PCEPILFE, PCEPI, CPILFESL, PPIACOYoY
HousingHOUST, PERMIT, HSN1F, CSUSHPISAYoY
Banking/CreditBAA10YM, BUSLOANS, DRALACBS, DRTSCILMLevel / YoY
YieldsT10Y3M, T10Y2Y, GS10, TB3MS, FEDFUNDSLevel

Non-monthly series are resampled: weekly (ICSA) to monthly mean, daily (T10Y3M, T10Y2Y) to month-end, quarterly (GDPC1, DRALACBS, DRTSCILM) forward-filled to monthly. Features with less than 80% coverage of the target period are excluded to prevent short-history series from shrinking the sample.


Weekly Email Report

The automated email includes:

SectionContent
IC SummarySnapshot table (probability, direction, risk driver, offset), model range, portfolio positioning (equities, fixed income, credit, hedging)
Executive SummaryEnsemble headline, model consensus, divergence framing
Key IndicatorsFour macro buckets (Growth, Inflation, Policy, Market Signals) — two sentences each
Model DivergenceStructured yield curve analysis: historical track record, three structural factors (QE, foreign CB demand, Basel III), judgment call
WatchlistTrigger levels: exact values each indicator needs to reach for 30%/50% probability, ranked by proximity
Adverse ScenarioTail risk classification, three real-world triggers, hedging framework tied to ensemble level
What Would Change Our ViewFive hardcoded thresholds (spread < -1%, core CPI < 1.5%, housing -15% YoY, claims > 300K, ensemble > 20%)
Data Currency NoticeData-through date and lagged series disclosure

Seven charts embedded inline: probability gauge, ensemble trend, indicator percentile dashboard, model comparison, indicator sparklines, full historical probability, and sensitivity trigger levels.


Configuration

All modeling choices are set in a single configuration block:

ParameterDefaultDescription
TARGET_DEFINITION"point""point" = recession at month t+12; "window" = any recession in months t+1 through t+12
OBS_START"1967-01-01"Observation start date
MIN_WINDOW120Minimum expanding-window training size (months)
MAX_FEATURES_BIC9Maximum features for BIC selection
THRESHOLD_WARNING30Warning probability level (%)
THRESHOLD_ELEVATED50Elevated probability level (%)

Project Structure

Recession_Probability_Model/
├── Recession_Probability_Model.ipynb # Interactive notebook (Google Colab)
├── automation/
│ ├── daily_report.py # Model run, charts, summary JSON
│ ├── generate_email.py # Claude API email composition + Gmail delivery
│ └── output/ # Generated charts, summaries, emails
├── .github/workflows/
│ └── daily_recession_report.yml # GitHub Actions weekly schedule
├── requirements.txt
├── .gitignore
├── LICENSE # MIT
└── README.md

Dependencies

PackageVersionPurpose
fredapi>= 0.5.0FRED API data access
statsmodels>= 0.14Probit regression, marginal effects, summary statistics
scikit-learn>= 1.3AUROC and Brier Score evaluation
matplotlib>= 3.7Charts and visualizations
pandas>= 2.0Data manipulation and time series alignment
numpy>= 1.24Numerical operations
scipy>= 1.10Normal CDF/PDF for probit predictions
anthropic>= 0.40Claude API for email narrative generation

Install all: pip install -r requirements.txt


Evaluation Metrics

MetricWhat It Measures
AUROCDiscrimination ability (1.0 = perfect, 0.5 = random)
Brier ScoreMean squared probability error (lower = better)
Pseudo R-squaredVariance explained vs. intercept-only model
AICFit-complexity tradeoff (lighter penalty)
BICFit-complexity tradeoff (heavier penalty — primary selection criterion)

Known Limitations

  • Trained on ~6 independent recession episodes — limited sample for generalization
  • Assumes future recessions resemble historical patterns — novel mechanisms (pandemics, geopolitical shocks) may not be captured
  • 12-month horizon is long — conditions can change materially within the window
  • FRED data has publication lags (1-3 months) — the latest reading may reflect conditions from 1-2 months ago
  • The model assigns a negative coefficient to inflation, reflecting demand-collapse recessions — this may understate stagflation risk where inflation and growth weakness occur simultaneously
  • Feature selection (BIC) is in-sample — the optimal feature set may differ in future regimes
  • The model should be one input among many — not a sole basis for allocation decisions

References

  1. Estrella, A. & Mishkin, F.S. (1998). "Predicting U.S. Recessions: Financial Variables as Leading Indicators." Review of Economics and Statistics, 80(1), 45-61.

  2. Wright, J.H. (2006). "The Yield Curve and Predicting Recessions." Federal Reserve Board FEDS Working Paper No. 2006-07.

  3. Kauppi, H. & Saikkonen, P. (2008). "Predicting U.S. Recessions with Dynamic Binary Response Models." Review of Economics and Statistics, 90(4), 777-791.

  4. Berge, T.J. (2014). "Predicting Recessions with Leading Indicators: Model Averaging and Links to the Financial Crisis." Federal Reserve Bank of Kansas City Working Paper.

  5. Berge, T.J. & Jorda, O. (2011). "Evaluating the Classification of Economic Activity into Recessions and Expansions." American Economic Journal: Macroeconomics.

  6. Federal Reserve Board FEDS Notes (2018, 2019). Comparative evaluation of six probit recession models.

  7. Boston Fed (2020). On dispersion in predicted recession probabilities from dependent variable construction choices.

  8. McCracken, M.W. & Ng, S. (2016). "FRED-MD: A Monthly Database for Macroeconomic Research." Journal of Business & Economic Statistics, 34(4), 574-589.

  9. Sahm, C. (2019). "Direct Stimulus Payments to Individuals." Brookings Institution. — Introduced the Sahm Rule.

  10. Bellego, C. & Ferrara, L. (2009). "Forecasting Euro Area Recessions Using Time-Varying Binary Response Models for Financial Variables." ECB Working Paper.


Contributing

Contributions are welcome. If you'd like to extend the model:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/your-feature)
  3. Make your changes and test locally with python automation/daily_report.py
  4. Submit a pull request with a clear description of what changed and why

Areas where contributions would be particularly valuable:

  • Additional model specifications (dynamic probit, Bayesian Model Averaging)
  • Alternative data sources beyond FRED
  • International recession models (EU, UK, Japan)
  • Dashboard/web UI for the weekly report

Disclaimer

This project is for educational and research purposes only. It is not financial advice, investment advice, or a recommendation to buy, sell, or hold any security or financial instrument. The model output should not be used as the sole basis for any investment decision. Past recession-prediction accuracy does not guarantee future performance. Economic models are inherently uncertain and can fail without warning, particularly during novel economic conditions. The authors assume no liability for any financial losses incurred from the use of this model. Consult a qualified financial advisor before making investment decisions.


License

MIT License. See LICENSE for details.


Suggested Repository Topics

recessionmacroeconomicsprobityield-curvefred-apieconomic-forecastingrecession-probabilitynbertime-seriespythonstatsmodelsclaude-apigithub-actions

About

Estimates 12-month-ahead U.S. recession probability using a five-model ensemble across 37 Federal Reserve indicators. Generates automated weekly investment committee briefings with embedded charts via GitHub Actions and Claude API.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages