Methodology
Signal Architecture
The regime classification is driven by a deterministic three-layer framework. Every number is computed from causal windows — today's observation is scored only against history that was available at close of business t − 1. No lookahead.
Executive Summary
FX Regime Lab classifies each currency pair into one of eight macro regimes using five signal families. Each signal is normalized against its own 252-day history (no lookahead), weighted by pair-specific importance, and fused into a composite score. The final regime label and confidence are validated against future price action using Brier scores and directional accuracy.
5
Signal families
3
Classification layers
8
Regime labels
Signal Families
Pipeline Architecture
HOVER OR CLICK A NODE FOR DETAILS
Layer 1 — Regime Gate
The gate determines the macro environment from rate differentials, carry momentum, breakeven-inflation shocks, and spot stress. First filter; if invalidated (stale or missing data), the system falls back to neutral.
Rate differential z-score. The carry-risk-adjusted spread is converted to a rolling MAD Z-score over a 252-day causal window with a 90-day minimum. The observation at t is scored against median and MAD computed from [t−251, t−1] only — no lookahead:
z_blended (M.3.2). 60% tactical (252d) + 40% structural (2520d real 10Y) MAD Z-score. Tactical captures near-term momentum; structural captures secular valuation.
Momentum check. Carry momentum m = x_t - x_{t-20} flags fading trends. When z >= 1.15 and m <= -0.25 simultaneously, the regime flips to CARRY_COLLAPSE.
Policy-breakout override. If breakeven inflation moves ≥ 12 bps in 5 days while |z| ≥ 2.0, the gate overrides to USD_POLICY_BREAKOUT.
Liquidity-shock override. If 21-day spot-return z-score |d| ≥ 2.5, the gate triggers LIQUIDITY_SHOCK regardless of composite.
Adaptive precision weighting (M.2.1). Precision weights: static weights scaled by |Spearman beta| / 0.10, floored at 10%. Signals with stronger historical predictive power receive higher effective weight.
Redundancy penalty (M.2.2). 0.03 per same-sign pair, capped at 0.15. Prevents overconfidence when correlated signals (rate + carry) align.
Composite hysteresis. When no override fires, the composite score maps to a five-tier snap function with memory of yesterday's tier. Sequential evaluation — each condition tested in order:
Tier changes of two or more steps are immediate. Single-step changes deferred by tighter hold thresholds:
Invalidation by stale or missing data forces neutral fallback. A structural_instability flag triggers CARRY_COLLAPSE before all other checks.
Layer 2 — Directional Bias & Conviction
Layer 2 translates the gate's macro read into a discrete directional bias (LONG / SHORT / NEUTRAL) and a calibrated probability conviction 0.0–1.0.
Positioning percentile. CFTC non-commercial net positions are ranked over a 156-week lookback. The percentile π feeds three metrics:
COT smart spread (M.3.3). 70% traditional non-commercial net-long percentile + 30% (asset-manager minus leveraged-money) spread. Reduces noise from speculator repositioning.
Crowding flag: π ≥ 90 or π ≤ 10. Crowding veto: π ≥ 97 or π ≤ 3.
Marcus B clash veto. If the rate sign and positioning sign point in opposite directions (both materially non-zero, with a ±5 pp deadband around the 50th percentile), the bias is forced to NEUTRAL and conviction is capped at 0.50.
Marcus C composite-rate clash. If the composite score and rate direction strongly disagree (|S| > 0.30), the bias is forced to NEUTRAL and conviction is capped at 0.50. This prevents the rate signal from overriding a divergent composite.
Conviction multiplier. Alignment bonus when rate and positioning agree; penalty when they conflict or when crowding is elevated. If positioning data is missing, an additional 0.88 discount applies:
where a = 1.0 if rate and positioning agree, 0.72 if they conflict. The effective rate sign uses a tactical z-score when informative (|z| > 0.12); otherwise it falls back to the futures-style BULLISH/BEARISH label.
Conviction score. Base conviction is anchored to the composite magnitude, then scaled by m_π. The raw score is an integer 1–5 which is then divided by 5 and stored as a probability 0.0–1.0:
Direction logic: if the composite is materially non-zero (|S| > 0.30), composite drives the bias; otherwise the rate sign drives it. If Layer 1 is invalidated, crowding is veto-level, or Marcus B / Marcus C clashes fire, the bias is forced to NEUTRAL and conviction is hard-capped at 0.50.
Layer 3 — Execution & Timing
Layer 3 produces entry timing (ENTER / WAIT), position sizing (FULL / HALF), and stop levels from realized volatility, risk reversal skew, and intraday microstructure.
Realized-vol rank. The 21-day annualized realized vol is scored against its empirical CDF over a trailing 3-year (756 session) causal window. Let q^σ_t denote the quantile. Entry is blocked when q^σ_t > 0.88. Full size requires q^σ_t ≤ 0.70.
Risk-reversal skew. 25-delta risk reversal (implied-vol difference call−put) is z-scored causally using only [t−252, t−1] for mean and standard deviation. The alignment score A_t = sign(bias) · sign(z_t). A skew-reversal flag R_t fires on a sign change across consecutive sessions where both legs are material (|z| > 0.35).
Marcus enter rule. Entry requires: bias ≠ NEUTRAL, conviction ≥ 0.50, q^σ_t ≤ 0.88, no skew reversal, and no strong directional skew contradiction. A strong contradiction fires when skew alignment A_t = −1, |z_t| > 1.0, and conviction < 0.75 — the disagreement is too large to absorb.
Lena + Chen sizing. Full size only when: timing = ENTER, conviction ≥ 0.75, q^σ_t ≤ 0.70, skew alignment ≥ 0, and no Chen trim. Chen trim fires when the crowding flag is active (π ≥ 90 or π ≤ 10) or when the crowding penalty p_crowd > 0.35. Otherwise HALF.
Stop level. Stop buffer is max(1.5 · ADR_20, MIE_proxy) where ADR is the mean daily range and MIE proxy is the worst adverse intraday move from the open against the directional bias over 20 days:
Signal Decomposition
The composite regime score is a weighted sum of five signal families. Weights vary by pair; shown below for EUR/USD. Click any segment to inspect its computation, source, and contribution.
Illustrative Example (Synthetic Data) — EUR/USD
Per-Pair Methodology
The three pairs share the same three-layer architecture but differ in weighting, data sources, and special-signal handling.
EUR / USD
Primary driver is the US–Germany 2-year yield spread (FRED DGS2 vs ECB data-api). Composite weights: rate differential ~45%, COT positioning ~25%, realized volatility ~20%, open interest ~5%, special signal ~5%. The special signal blends Bund-BTP spread (Italian sovereign stress percentile) with ECB balance sheet YoY growth rate. Computed as dual-horizon MAD Z-score. Risk-reversal skew is monitored but not used as a composite modifier.
USD / JPY
Primary driver is the US–Japan yield spread (FRED DGS2 vs MOF JGBs). Composite weights: rate differential ~40%, COT positioning ~20%, realized volatility ~25%, open interest ~5%, special signal ~10%. The special signal is a VIX funding-stress proxy: high VIX → JPY bid → USD weakness. Carry-trade dynamics are explicitly monitored — when carry risk-adjusted z-score is elevated (≥ 1.15) but 20-day momentum is fading (≤ −0.25), the gate triggers CARRY_COLLAPSE. Confidence receives a +5 pp bonus when the special signal > 0.5.
USD / INR
INR uses a tailored composite with reduced COT weight. Composite weights: rate differential ~30%, COT ~10%, realized volatility ~20%, open interest ~5%, special signal ~20%, FPI flow ~15%. COT is a reduced-weight proxy (managed-float positioning is less informative than G10). The special signal blends crude oil and DXY pressure on EMFX (40% oil + 35% DXY + 25% EM composite). FPI is SEBI daily net flow z-scored over 20 days. When Brent is above its 80th percentile, confidence receives a −5 pp adjustment reflecting external-account vulnerability.
Confidence Derivation
Confidence is not a probability of being correct. It is an internal consistency metric: signal strength modulated by directional agreement, pair-specific adjustments, and an institutional −3 pp haircut.
Base confidence is driven by the absolute composite magnitude. The composite is clipped to [−2, 2] upstream; typical range is [−1, 1]:
Agreement bonus. +5 pp if rate and COT point in the same direction. Additional +5 pp if both have magnitude > 0.3.
Pair adjustments. USDJPY special signal > 0.5 adds +5 pp. USDINR Brent above 80th percentile subtracts −5 pp. Other pairs have their own commodity / special-signal adjustments.
Raw confidence is clipped to [0.30, 0.95], then the institutional haircut is applied:
Platt calibration. Calibrated confidence applies Platt scaling:
Max calibrated confidence ≈ 0.71 even if raw reaches 0.90.
Validation Methodology
Every regime call is validated out-of-sample at two horizons: T+5 (one trading week) and T+20 (one trading month). Validation is append-only; once written, a validation row is never mutated.
Directional outcome. The log-return in basis points between call-date spot and horizon-date spot is:
A 5 bps dead-band filters noise: UP if r > 5, DOWN if r < -5, otherwise NEUTRAL.
Correctness. A BULLISH call is correct only if realized is UP; BEARISH only if DOWN; NEUTRAL only if realized is NEUTRAL.
Brier score. For each directional call (non-neutral), the Brier score is (p − y)² where p is the confidence and y = 1 if correct, 0 otherwise. The random-guess baseline for three outcomes is 0.333. Brier skill is reported as (baseline − mean) / baseline.
Win rate. Computed only over directional calls (excludes neutral) to avoid inflating accuracy with no-trade states.
Regime Validation via Sizing Simulation
The core question is not whether the model generates positive returns, but whether regime conviction improves risk-adjusted returns versus a uniform benchmark. This is a validation exercise, not a trading strategy.
Uniform benchmark. Every directional call receives identical exposure sizing regardless of confidence. This produces a baseline return series that isolates the value of directional accuracy alone.
Regime-aware sizing. Exposure scales with calibrated confidence. Higher-confidence calls receive larger sizing; lower-confidence calls receive smaller sizing. Neutral calls receive zero exposure. The scaling function is sigmoid-clipped to prevent over-concentration in any single call.
Why this validates regime labels. If regime-aware sizing produces a higher Sharpe ratio, higher Sortino, and lower maximum drawdown than uniform sizing — using the exact same directional calls — then the regime labels are adding genuine information beyond random directional bias. If not, the labels are noise and the framework requires revision.
The comparison is reported on the Track Record page under the "Regime Validation" tab: Sharpe, Sortino, max drawdown, return-to-drawdown ratio, hit rate by confidence decile, and regime-conditional performance breakdown.
Data Sources & Fallback Chain
All data is fetched daily via an async ingestion engine with explicit backoff and retry. Missing primary sources trigger a documented fallback chain; if all fail, the signal is marked stale rather than interpolated.
| SIGNAL | PRIMARY | FALLBACK |
|---|---|---|
| US Yields | FRED (DGS2, DGS10) | — |
| DE Yields | ECB data-api | — |
| JP Yields | MOF Japan CSV | — |
| FX Spot | Alpha Vantage | yfinance |
| COT Positioning | CFTC weekly | — |
| Implied Vol | Yahoo Finance (^EVZ, ^JYVIX) | — |
| CME OI | CME volume/OI CSV | — |
| Risk Reversal | yfinance (FXE options) | — |
| Macro Calendar | Investing.com | — |
Signal Families
2Y sovereign yield spreads. Structural anchor of the composite.
CFTC weekly non-commercial net positions as 156-week percentile ranks.
21d annualized realized vs 3-yr empirical CDF. Vol gate at 88th percentile.
CME futures OI delta and price-alignment flag.
Regime Thresholds (EUR/USD, USD/JPY)
Regime Thresholds (USD/INR)
Volatility Overlay
When realized-vol rank exceeds the 88th percentile, the regime label appends __VOL_EXPANDING to the neutral tier. This flags elevated volatility without changing the directional read.