Data Sources
Last verified
Eighteen external feeds drive the platform. Each is registered as a DataSource subclass in app/sources/ and pulled by engine.py:fetch_all_sources() on the cadence dictated by the active collection profile.
The full inventory
| Source | What it provides | Cadence | Required |
|---|---|---|---|
market (primary brokerage feed + public market-data fallback) |
SPY/QQQ/IWM/DIA closes, VIX, MOVE, chain net-Γ + gamma walls/ZGL/PCR, BTC, RSI, IVR | Per profile | Yes (core) |
fred |
Fed liquidity, HY OAS, 2s10s, breakevens, yields, real yield | Per profile | Yes |
credit |
High-yield credit spread series, NFCI | Per profile | Yes |
liquidity |
Net Fed liquidity (WALCL − TGA − RRP) | Per profile | Yes |
darkpool |
Dealer-gamma analytics vendor DIX + GEX daily CSV | Daily post-close | Yes |
news |
FXStreet RSS + Iran International liveblog + Hormuz tanker monitor | Per profile | Yes |
sentiment |
Third-party news-sentiment feed (retired 2026-06) | Per profile | Optional (25 req/day budget) |
seasonality |
Historical SPY seasonality lookup | Per profile | Optional |
vol_structure |
VIX term structure (VIX9D/VIX/VIX3M/VIX6M ratios) | Per profile | Yes |
eps |
Forward EPS revision deltas | Per profile | Optional |
breadth |
S&P 500 % above 50/200 SMA, sector breadth | Per profile | Yes |
energy |
WTI, Brent, USO, XLE, crack spread | Per profile | Yes |
inflation |
Breakeven inflation series (5Y, 10Y, 5Y5Y) | Per profile | Yes |
macro_indicators |
Composite macro health proxies | Per profile | Optional |
cot |
CFTC Commitments of Traders speculator net positioning | Weekly (Fri ~15:30 ET) | Optional |
aaii |
AAII bull-bear sentiment spread | Weekly (Thu) | Optional |
ebp |
Fed Excess Bond Premium + GZ credit spread + model recession probability | Monthly (FEDS Notes CSV) | Optional |
fred_macro |
Free FRED macro-state + financial-stress / funding series (Kim-Wright 10Y term premium, EFFR, SOFR, jobless claims, STLFSI4, KCFSI, unemployment, Core PCE); all data_only carriers, not yet scored |
Per profile (full / extended) |
Optional |
cboe |
Free CBOE CDN no-key CSVs — options put/call ratios (equity / total / index) + VIX term-structure front/back points (VIX9D, VIX6M); all data_only carriers, not yet scored |
Daily (full / extended) |
Optional |
ofr |
Free OFR (US Treasury) no-key daily CSV — Financial Stress Index composite + 5 subindices (credit / equity-valuation / safe-assets / funding / volatility); all data_only carriers, not yet scored |
Daily (full / extended) |
Optional |
naaim |
Retired 2026-09-01 — NAAIM Exposure Index (active-manager equity exposure), a free weekly page-scrape; NAAIM paywalled the feed on 2026-08-01, so the series is history-only now. data_only carrier, never scored |
Retired (was weekly) | Optional (history only) |
options-analytics-live |
Live options-analytics dealer-risk + levels for SPY — settled/live net dealer gamma + delta (billions), intraday flow-shift, the categorical flow direction, and the gamma-flip / call-wall / put-wall / max-pain levels; all fa_* data_only carriers, not yet scored. Captured forward as a hedge against the subscription lapsing |
Intraday (4×/trading day, full) |
Optional |
edgar_xbrl |
Free, no-key SEC EDGAR audited quarterly financial facts for a fixed 6-name entity set (NVDA inventory + revenue; MSFT/GOOGL/AMZN/META/ORCL capex + operating cash flow). Feeds the AI Capital Cycle T13 auto trigger + T10’s capex/OCF companion read; persisted to its own table, not daily_signals |
Daily (overnight / full) |
Optional |
sovereign_yields |
Free, no-key six-sovereign long-end government-bond-yield panel — Germany 30Y (Bundesbank), euro-area AAA 30Y (ECB Data Portal, the euro / France proxy), UK 20Y long (Bank of England), Canada long (Bank of Canada), Japan 30Y/40Y/20Y (Japan MoF), plus US 30Y for the shared look-back table. Makes the “six governments at multi-year highs at once” observable honest from primary central-bank data. Persists the full history to macro_series and the derived daily carriers (levels, per-country years-since-higher, two synchrony counts, oldest-of-six panel as-of) to daily_signals; each country fetch is independent so one dead endpoint never blanks the others. All data_only, not yet scored |
Daily (extended / overnight) |
Optional |
debt_holders |
Free, no-key who-holds-the-debt / cash-on-the-sidelines panel (long-end-stress Phase 3B — the second-driver watch: who owns the Treasury float and how much cash sits short). Four independent groups: money-market-fund assets (FRED — a narrower retail weekly measure plus the broad quarterly total, the ~$8.36T headline the retail series understates), Fed SOMA Treasuries held outright (NY Fed, weekly — runoff halted Dec 2025), foreign holdings of US Treasuries (US Treasury TIC — Japan / China / UK / all-foreign total, monthly with a ~2-month lag; the frozen legacy TIC path is a silent-staleness trap and is refused), and foreign-official custody of marketable Treasuries (FRED, weekly). Persists full history to macro_series and the derived daily carriers (levels, 13-week / 12-month change look-backs, per-cadence as-of stamps) to daily_signals; each group fetch is independent so one dead endpoint never blanks the others. All data_only, not yet scored |
Daily (extended / overnight) |
Optional |
Three auxiliary fetches run alongside the registered sources and stash results under underscore-prefixed keys (_gamma_levels, _fed_watch, _correlations) so format_report can find them without colliding with per-source dicts:
- Gamma profile — Brokerage option-chain pull for the per-strike
gamma_levelsAPI path. Requires brokerage auth; logs and continues on token failure. - Fed Watch — CME rate-cut probability surface for the next FOMC meeting.
- Correlations — rolling SPY/VIX, SPY/DXY, SPY/TNX, SPY/Oil pair correlations computed post-hoc from the persisted
daily_signalshistory. Not an external fetch — it’s a SQL query against our own history.
Provider mix and fallback posture
markettries the brokerage market-data feed first, falls back to the public market-data fallback when the brokerage returns None/empty. The chain-computed quantities (chain net-Γ, gamma walls, ZGL, PCR — not the dealer-gamma analytics GEX aggregate, which arrives viadarkpool) require brokerage option chains and have no fallback. VIX uses volume-weighting since the brokerage reports no OI for index options. TNX and DXY have no option chains.- The brokerage feed is optional. Missing or expired tokens log CRITICAL but the platform continues on the public market-data fallback / FRED / other sources. See source health for how token status surfaces on
/api/v1/status. - The third-party news-sentiment feed was rate-limited at 25 requests/day and retired 2026-06 (DOCTRINE D22);
/api/v1/source-healthsurfaces remaining budget for active rate-limited sources. - News fan-out — the
newssource merges three feeds: FXStreet financial headlines, Iran International liveblog (for geopolitical risk), and the Hormuz Strait tanker monitor (for oil-supply tail risk). ebppulls the Federal Reserve’s monthly FEDS Notes Excess Bond Premium CSV. EBP is the residual of the Gilchrist-Zakrajšek corporate credit spread after stripping out compensation for expected default risk — the credit-market literature’s premier forward leading indicator, with a 50-year multi-regime history back to 1973. The source persists three fields per cycle:ebp(the excess premium, % points, can be negative),gz_spread(the parent GZ spread, % points), andebp_recession_prob(the model’s recession probability, a 0-1 fraction; renamed from the upstreamest_probcolumn). Cadence is monthly — the Fed refreshes the file roughly once a month, last row datedYYYY-MM-01, so only the low-frequency profiles (overnight,extended,full) earn a fresh row. Ingested + persisted only: the three fields land ondaily_signalsfor future scoring / matcher use but are not yet wired into the health score or alignment — that is a later, separately-gated step.cboepulls free, no-key CBOE CDN CSVs (daily cadence,full/extendedprofiles). Fivedata_onlycarriers for the drawdown-risk / state lane: three options put/call ratios —cboe_equity_pc(equity-only),cboe_total_pc(equity + index),cboe_index_pc(index-only) — and two VIX term-structure points,vix9d_close(9-day, front of the curve) andvix6m_close(6-month, back). The intermediate VIX3M and the derived VIX term slope / ratio are already persisted elsewhere (Law 3 — not re-emitted here). Each CSV leg is fetched independently throughsafe_fetch, so a single dead file degrades that one field tonulland leaves the others intact. Ingested + persisted only — not yet wired into the health score or alignment.ofrpulls the OFR (US Treasury Office of Financial Research) Financial Stress Index from a free, no-key daily CSV (financialresearch.gov, daily T-2,full/extendedprofiles). Sixdata_onlycarriers for the drawdown-risk / state lane: the compositeofr_fsi(>0 = above-average stress) plus five subindices —ofr_fsi_credit,ofr_fsi_equity_valuation,ofr_fsi_safe_assets,ofr_fsi_funding,ofr_fsi_volatility. The three geographic split columns (US / other-advanced / emerging) are deliberately dropped. It is a second, model-independent stress read alongside the FRED STLFSI4 / KCFSI legs. The single CSV routes throughsafe_fetch; a dead URL or unparseable file degrades the whole dict to empty without raising. Ingested + persisted only — not yet wired into the health score or alignment.naaim— RETIRED 2026-09-01, history only. The NAAIM Exposure Index measured the average equity exposure NAAIM-member active managers report running (~-200 leveraged short to +200 leveraged long) — adata_onlypositioning / contrarian carrier for the squeeze-setup and drawdown-risk lane, pulled via a free two-step weekly page-scrape ofnaaim.org. NAAIM moved the index behind a paid subscription (index.naaim.org) effective 2026-08-01, so no compliant free path remains and the series can never advance. It is no longer polled; the persisted history is retained and still served on/signals/history,/signals/sparklines, andpositioning.naaim_exposure, badged with its frozen weekly as-of date. The source module + parser are kept dormant for a future paid revival. It was never wired into the health score or alignment.options-analytics-livepulls the live options-analytics dealer-risk + levels archive for SPY from two REST endpoints. It persists afa_*-prefixed family: settled vs live aggregate net dealer gamma + delta (normalized to billions to share the dealer-gamma analytics GEX scale), the intraday flow-shift fractions, a categoricalfa_flow_direction(amplifying / dampening / neutral / no_flow / regime_flip), the live gamma-flip / call-wall / put-wall / max-pain price levels, and anfa_as_ofvintage stamp. This is a SECOND vendor’s positioning read, deliberately kept distinct from the dealer-gamma analytics GEX and the option-chain gamma walls. Each endpoint is fetched independently throughsafe_fetch, so a 5xx / timeout / null on one endpoint degrades only its fields and never poisons the other or the cycle; with no API key the source returns empty and logs a warning. Captured forward as a hedge — alldata_onlycarriers, not yet wired into the health score or alignment (forward-accruing until graded).edgar_xbrlpulls SEC EDGAR’s freecompanyfactsAPI for a fixed six-name entity set — no key, no rate concern (six requests per cycle against SEC’s ~10 req/s ceiling). Unlike every other source in this table it does NOT feeddaily_signals: it persists directly to its own append-only table, because the data is per-company audited history, not a daily macro reading. The interesting engineering is the extraction, not the fetch — EDGAR reports cash-flow and income figures as fiscal-year-to-date cumulative totals, not clean quarterly numbers, so the source derives genuine quarterly deltas (and correctly handles a company’s underlying reporting tag changing over the years) before writing anything. See the AI capital cycle framework page for how the derived reads feed the T13/T10 triggers.
Macro calendar — what’s filled, what isn’t
The platform seeds a forward macro-event calendar (calendar_events) that powers the air-pocket flag’s catalyst leg and the AI brief’s calendar_lookahead. The three high-impact monthly prints — Employment Situation (NFP), CPI, PPI — are seeded from FRED’s free release/dates endpoint, plus FOMC decisions and the weekly FRED release projections.
The long-end-stress Phase 3B rates-event calendar adds two more emitters, both calendar_events rows on the same forward-lookahead substrate: treasury_auctions seeds announced Treasury coupon auctions (10Y / 20Y / 30Y) from the free TreasuryDirect TA_WS securities API (auction date at the 13:00 ET coupon close; 20Y/30Y high-importance, 10Y medium), and rates_calendar seeds hand-entered dated structural events from a committed file — Bank of Japan meeting dates, US quarterly-refunding announcements, the Dutch pension transition wave, the UK DMO remit, the OBR fiscal risks report, the OECD Global Debt Report. Both are idempotent (one row per event, re-emit is a no-op) and gated to once per ET day. The calendar records and reacts to these dates; it never forecasts an embargoed policy outcome.
Each macro-event row carries consensus and actual columns. The two behave differently:
consensusis NULL by constraint. The market’s prior-expectation survey for these releases has no free, terms-of-service-clean source. FRED’s release endpoint serves the schedule only — the published date, never the street’s forecast. Consensus figures live behind paid econ-calendar vendors, which the platform deliberately avoids. So the print-vs-consensus surprise read (the thing the calendar would unlock) stays blocked until a free consensus source appears or a paid one is sanctioned. This is an honest data gap, not a bug — the column exists, waiting for a source that does not yet exist.actualis wired for the unambiguous prints. The realized headline figure is free from FRED (the underlying series themselves), so after a print lands the backfill fillsactualfor the releases whose series → quoted-headline mapping is unambiguous:- NFP →
PAYEMS(Total Nonfarm Payrolls); headline = month-over-month change in the level, in thousands (e.g.+139K). - CPI →
CPIAUCSL(CPI-U, All Items, SA); headline = month-over-month percent change (e.g.+0.2% m/m). - PPI is deliberately left NULL. PPI has two competing “headline” series in common quotation (final-demand vs all-commodities) and the quoted figure isn’t unambiguously one of them — so per the rule that a wrong
actualis worse than an empty one, PPI stays unfilled until a canonical mapping is settled.
- NFP →
Constraint: no free consensus survey for NFP/CPI/PPI; no canonical headline mapping for PPI. Falsifier: a free, ToS-clean consensus feed (or a sanctioned paid one) becomes available, or PPI’s quoted-headline series is settled. Unblock: wire consensus into
_emit_fred_release_calendar(consensus=) and the surprise framing follows; add the PPI entry toRELEASE_ACTUAL_MAPand itsactualwires automatically.
Execution order
Fast HTTP sources run first (FRED, liquidity, darkpool, news, sentiment) so the heavy market-data fallback sources (market, eps, breadth) don’t gate the report on slow network paths. Breadth specifically downloads in batches of 50 tickers with 2-second delays to stay under the market-data fallback feed’s rate limits.
Every fetch routes through DataSource.safe_fetch() in app/sources/base.py — uniform retry with exponential backoff, WARNING on transient failure, logger.exception() on fatal, returns a default on terminal failure. New sources must use it.
See also
- Schedule — when each profile fires, which sources each profile pulls.
- Lifecycle — what happens to fetched data inside a report cycle.
- Source health — how
source_runstracks ok/fail and the 95%/80% escalation rules. - DIX and GEX — the two signals that flow through the
darkpoolsource. - Source code:
app/sources/(one file per source). Inventory + provider table also inapp/sources/README.md.