Skip to content

What (One-liner)

US output gap: FRED GDPC1 → HP filter λ=1600 → gap_pct = (actual - trend) / trend * 100. The source of the output_gap_pct field Canvas exposes via macro_snapshot_v1. Positive → overheating; negative → slack.

How to use

Consumed indirectly on Canvas (macro_snapshot_v1output_gap_pct). Also callable directly in Python:

python
from services.mfle.output_gap import get_output_gap
result = get_output_gap(limit_quarters=80)
# {available, output_gap_pct, trend_latest, actual_latest, as_of_date, logic_lineage}

Core formulas

if not fred_available():
  return {available: False, reason: 'FRED_API_KEY not set', ...}

gdp = fetch_series('GDPC1', limit=80)
trend = hp_filter(gdp, λ=1600)          # see hp_filter card
cycle = gdp.reindex(trend.index).ffill().bfill() - trend
gap_pct = (cycle / trend) * 100

return {
  output_gap_pct:  round(gap_pct[-1], 2),
  trend_latest:    round(trend[-1], 2),
  actual_latest:   round(gdp[-1], 2),
  as_of_date:      YYYY-MM-DD,
  logic_lineage:   ['hp_filter', 'GDPC1']
}

Rounding contract: all numeric fields round(2).

Assumptions & applicability

Assumptions: US FRED GDPC1 + the quarterly HP λ=1600 standard + ≥5 obs + percent-of-trend (not dollars).

Fits: the Canvas macro overlay's output_gap field, the macro_snapshot component, overheating-vs-slack judgment.

Does not fit: monthly / intraday, non-US, exact CBO replication, real-time-stable endpoint estimates.

Input / Output contract

get_output_gap(limit_quarters?=80){available, output_gap_pct, trend_latest, actual_latest, as_of_date, logic_lineage} (primary) or {available: False, reason} (failure).

Known limitations

  1. End-point bias (inherited from HP): the latest quarter's gap is unstable; revises over 2-3 quarters
  2. GDPC1 only / no non-US support
  3. Materially different from CBO: CBO uses a production function; this is HP-simplified
  4. Gap is percent of trend (not dollars)
  5. HP lookahead in default full-sample mode (real-time use must re-run each period; results revise)
  6. limit_quarters=80 default — longer lookbacks raise HP cost
  7. No bootstrap CI / structural breaks (Hamilton 2018 critique)

References

Hodrick-Prescott (1997) original HP paper + CBO (2024) official gap methodology + Orphanides-van Norden (2002) real-time unreliability. Full citations in the frontmatter.

Golden Test

tests/golden/fixtures/tier3/output_gap/captured_snapshot (HP primitive independently cross-validated), 1e-6 tolerance, 11 tests:

  • compute_positive_gap — positive-gap scenario byte-equal
  • compute_negative_gap — negative-gap scenario
  • compute_short_series_insufficient — len<5 → available=False
  • compute_none_input — None → available=False
  • get_output_gap_fred_ok — full path (monkey-patched FRED)
  • get_output_gap_fred_unavail — FRED down → reason='FRED_API_KEY not set'
  • get_output_gap_fetch_none — fetch=None → reason='fetch GDPC1 failed'
  • determinism — 5 reruns identical
  • rounding_contract — round(2) on all numerics
  • logic_lineage — fixed ['hp_filter', 'GDPC1']
  • formula_contract — gap == (actual - trend) / trend * 100

Changelog

  • 1.0.0 (2026-04-21) — First Active (Tier 3 batch 3.2, HP composition)

Verifiable intelligence for the decisions that demand scrutiny.