Skip to content

KB / framework

Leading, coincident, and lagging indicators

Last verified

The alignment surface classifies its twelve signal categories into three indicator classes — leading, coincident, and lagging. The class drives how much weight a category gets in the weighted alignment percentage, where its dot lives on the Signal Alignment card, and how loudly the operator should react when it moves.

What the classes mean

The three classes are not equally informative. Leading signals carry more forward-looking content per move, lagging signals carry less. The weighted alignment math encodes that directly (see below).

The twelve categories by class

Order comes from IMPLICATION_FUNCS in app/signals/implications.py — leading first, then coincident, then lagging:

Indicator class — canonical assignment per category

dark_pool Leading DIX (institutional dark-pool buying) + intraday options-flow proxy (zero_dte_pcr + vix_skew_divergence). DIX moves before price; flow corrects intraday.
gamma Leading GEX dealer gamma exposure. Sign flips alter the vol regime before VIX reacts.
credit Leading HY OAS spreads + NFCI financial conditions. Credit widens before equity selloffs.
breadth Leading % of S&P above 50-day SMA. Participation narrows before indices roll over.
energy Leading energy_regime categorical + WTI 1y percentile. Oil shocks act as a leading macro headwind via margin compression.
growth_expectations Leading Copper/Gold 20d RoC + 10y real yield. Reflation breadth shows here before the equity rotation.
news_sentiment Leading (flag-gated) AI brief's news_sentiment_score (0-10). 12th category, off by default behind ENABLE_AI_SENTIMENT_ALIGNMENT until calibration clears.
correlations Coincident 4-pair basket (SPY/VIX, SPY/DXY, SPY/TNX, SPY/Oil). Cross-asset transmission confirms or denies the structural read.
volatility Coincident VIX + term structure (primary) + SKEW + VVIX/VIX. Implied vol responds to current conditions.
inflation Coincident Stagflation score from weighted breakevens. Concurrent macro read.
carry_risk Coincident USD/JPY 5d RoC + MOVE. Cross-asset carry stress as it happens.
liquidity Lagging Fed balance sheet trajectory + cut probability. The slowest macro confirming signal.

Eleven categories ship active by default; news_sentiment is flag-gated behind ENABLE_AI_SENTIMENT_ALIGNMENT=0 per DOCTRINE P8 — additive until the per-horizon calibration substrate at /ai-brief/calibration-by-sentiment shows ≥55% hit rate over 30d. When the flag is unset the category is absent from the alignment response and the active count is 11.

Why classification matters

Weighted alignment

compute_alignment() returns two percentages on every /api/v1/signals/alignment response: alignment_pct (count-based — every category counts once) and weighted_alignment_pct (information-content-adjusted). The weighted variant multiplies four independent factors per category:

Indicator-class multiplier (from app/signals/regime.py:_INDICATOR_CLASS_WEIGHTS)

Leading 1.5× Forward-looking categories carry the most signal per move.
Coincident 1.0× Confirming categories carry baseline information content.
Lagging 0.7× Slow confirming categories down-weighted.

The full weight composition is indicator_class × leg_count × regime_relevance × freshness. A two-leg leading category with a fresh intraday read and energy-shock regime relevance gets the loudest voice; a single-leg lagging category running on a stale weekly print gets the quietest. A 50% unweighted reading with 3 leading aligned and 3 lagging divergent reads around 66% weighted because the leading agreement carries more weight than the lagging dissent.

Transmission order on the Alignment card

The eleven (or twelve) dots on the Signal Alignment card are split into a leading cluster (left) and a lagging cluster (right). The exact ordering within each cluster is regime-conditional — every active regime carries a profile in ui/src/data/signal-transmission-order.json. Examples:

The midpoint divider on the card hovers a tooltip with the rationale for the active profile. Per-regime profiles are the operator’s way of saying “in this regime, this indicator typically moves first” without re-classifying the underlying signal — correlations stays a coincident category structurally; the transmission-order JSON just decides where its dot lives in the visual ordering.

When a leading dot flips

The standing operator rule: when leading indicators deteriorate while lagging indicators still look fine, the leading indicators are usually right. The whole point of separating the classes is to weight the loudest forward-looking voices over the slowest confirming ones. A bearish DIX + bearish credit + bearish gamma with bullish liquidity reading is a signal to reduce risk, not a signal to wait for liquidity to confirm.

The STRONG_DIVERGENCE severity badge (5+ divergent categories) is the loudest version of this — it fires loudest when leading + coincident categories disagree with SPY’s recent direction. Lagging-only divergence is quieter by construction.

See also