Macro Signal
Federal Reserve Data as Product Surface
Macro context sits beneath every institutional product decision — credit tiers, AML thresholds, margin calls, advisor copy — but it almost never appears in the UI. This concept takes four Federal Reserve series (UNRATE · CPI · 10Y Treasury · VIX) and reshapes them from chart-library demo into the information object a senior PM, risk lead, or portfolio manager actually reads: latest value, YoY delta, 5-year percentile, regime band. One line of product intent per series. No forecasting theater.
A macro series is not a line. It's a product default waiting to be set.
When unemployment moves 0.6 points in a quarter, a consumer credit app should be quietly retiering its default risk thresholds — not waiting for a quarterly model refresh. When CPI prints above 3% YoY, the advisory copy in a wealth platform needs to stop saying "with inflation near target." When VIX closes below 15, margin-call calibration can ease; when it prints above 30, it must tighten. The reason these adjustments happen slowly today is not that the data is unavailable — it's that the data is not designed as a product input. This concept fixes that.
1. Why these four series
FRED publishes over 800,000 time series. The selection problem is itself the first design decision. Four series earn their panel because each maps cleanly to a product default a mid-sized fintech already sets — and gets wrong by default because the context isn't surfaced.
UNRATE — unemployment rate
Drives default risk tier thresholds in consumer credit products. When unemployment rises above regional norms, tier cut-offs should tighten and onboarding copy should acknowledge the macro environment.
CPIAUCSL — consumer price index
Anchors inflation-adjusted thresholds in AML monitoring and the baseline assumption in every piece of advisor copy that says "with inflation near target." The 2% target is an editorial default; CPI YoY is the observed truth.
DGS10 — 10-year treasury yield
The benchmark rail for every fixed-income advisor UI. Portfolio valuation deltas, discount-rate assumptions, and rate-sensitive product card copy all inherit from this single number.
VIXCLS — CBOE volatility index
Position-sizing defaults, margin-call stress calibration, and "market stress" dashboard pills all respond to VIX regime. Volatility is the single most under-represented signal in consumer investing UIs.
Why no GDP, no PMI, no M2
Each of the above is an interesting research series. None of them changes a product default in the next 24 hours. The bar for inclusion is: does this number alter a decision a product team would make this week? These four pass. Others fail.
Why no forecast cone
Forecasting is a different product than sensing. Cones imply probabilistic claims this surface does not make. The Kronos-inspired prediction cone lives in the AI trading demo, not here. Macro Signal reports; it does not predict.
2. The information object
Every panel carries the same four-line information object — and in exactly that rank order, because that's the order a risk or product lead actually reads:
Latest value — anchor the reader
The current print, in its native unit, tabular-numerals. No compression, no abbreviation. 4.3% reads; 4.30% reads; "4.3% unemployment" does not — the label is already carrying that work.
YoY delta — direction + magnitude in one glyph
Percentage-point deltas for rates (UNRATE, DGS10). Percent-change for indices (CPI, VIX). The distinction is not pedantic — a 0.1 point rise in unemployment is a different statement than a 0.1% rise in an index, and the colour coding inverts: for UNRATE and VIX, up is red; for CPI, deviation from 2% is red. Designed so a red glyph always means the same thing to the reader: default may need to tighten.
5-year percentile — the honest historical anchor
"4.3% unemployment" reads differently at the 67th percentile than at the 15th. The percentile is the single field that most consumer dashboards omit, and it's the field that converts an isolated number into a product decision. Tone-mapped: 0–35 good (green), 35–65 neutral, 65–85 elevated (amber), 85+ alert (red).
Regime band — one word of product language
Full employment · Expansion · Slowdown · Recessionary. Calm · Normal · Anxious · Panic. These are not technical bands — they are the language a product copywriter or a compliance officer can use downstream without translation. The current band is highlighted in its tone colour; the others stay dim as reference vocabulary.
3. What is deliberately absent
No intraday animation on the price
The line enters once on mount. It never ticks, pulses, or breathes. Animation on financial data introduces perceived latency — professionals notice, and they stop trusting the surface. Provenance dot is the single live element on the panel.
No crosshair label on hover
The chart is a shape, not a table. If the reader needs a specific value, the KPI row above carries it. A crosshair with a tooltip duplicates the work and doubles the read time.
No comparison mode, no overlay, no second axis
Two series on one axis is a research tool, not a product surface. The panel is the unit. If a PM needs to see CPI and DGS10 together, they open two panels — which is exactly what this grid already gives them.
No model confidence, no AI label
The data is 100% Federal Reserve. There is no model, so there is nothing to label. Adding a "powered by AI" badge to a surface that reports BLS prints would be a form of trust laundering.
4. Data pipeline — why the JSON is static
FRED's fredgraph.csv endpoint returns a valid CSV but does not include a CORS header,
which blocks browser-side fetch. Three options were on the table:
- Public proxy. Routes through a free-tier relay. Latency 300–1200 ms, reliability ~95%. Rejected — the surface is a product demo and unreliable latency undermines the thesis.
- Server-side pre-fetch. A small worker fetches nightly, caches JSON, serves from same origin. Chosen direction for production — sketched as
.github/workflows/fred-refresh.ymlin the repo plan. - Build-time pre-fetch → static JSON. What's shipped here. 74 rows for monthly series, ~1,600 for daily. Committed to
data/fred/macro.json. Zero runtime dependency. The honest trade is freshness: the dashboard shows the data as of build time, not live.
Option 3 is the right call for a concept deliverable because it lets the design conversation be about
the information object, not the infrastructure. The same module (js/modules/macro-signal.js)
works against any same-origin macro.json — swap the build-time file for a nightly-refreshed
one and the UI layer doesn't change.
5. Where it plugs in
Macro Signal is designed as a component, not a page. In the portfolio's own product set, it has three obvious homes:
- ACY Securities trader dashboard → top-rail VIX panel replacing the current "market stress" pill, with the regime word as the primary glyph.
- Xanthos advisor UI → DGS10 + CPI pair as the permanent context header on portfolio valuation screens. The advisor stops having to say "with rates around 4%" because the rail already carries it.
- TradeX institutional terminal → UNRATE + VIX as the left rail's macro stripe, feeding the position-sizing default that the terminal already computes.
6. Craft notes
- Zero inline styles. Every value token-driven (
--accent,--space-*,--text-*). - Chart library: TradingView Lightweight Charts v4.2. Price scale locked, pan/zoom disabled — the panel is a signal, not a workspace.
- Colour-blind-safe: every directional cue pairs colour with a word (Slowdown · Anxious · Elevated). Never colour alone.
prefers-reduced-motionhonoured — no entrance stagger, no crosshair magnet.- WCAG AA on all body text contrast ratios. Tabular numerals throughout the KPI row for alignment.
All series sourced from the Federal Reserve Bank of St. Louis (FRED) public API. Fetched via the fredapi Python client at build time and committed as a single JSON artifact. No intraday polling, no live credentials in the browser, no quota exposure. Ed's Python pipeline handles the fetching, schema normalization, and JSON shaping — the page reads a static artifact.