Skip to content

Releases

v0.13.38

Choose a tag to compare

@github-actions github-actions released this 24 Oct 15:32
9b98f18

Fixed

  • The watchlist page no longer throws a React hydration error (#418). The server formats card times in its own zone (UTC in Docker) and the browser in the reader's, so the text differed and React threw the tree away and re-rendered it on the client. The suppressHydrationWarning flag sat one element too high to cover the text. TickerCard now renders the UTC string during hydration and switches to local time right after (useSyncExternalStore).
  • The API opens one connection pool, not one per racing first request. get_pool() was a bare lru_cache, which runs the factory once for each thread that misses at the same time; each extra pool opened connections and threads, was dropped, and its __del__ later failed with "cannot join current thread". A lock now serializes the first call.
  • The spot feed stays on xenon when IB Gateway is logged out but Futu is up. xenon v0.15.0 serves US stocks from Futu during RTH (?quotes=futu-first), and its status frame reports providers.futu. The handshake used to fail over to massive on ib_connected: false alone, so an IB logout also dropped Futu. It now fails over only when both are down. Indexes still need IB.

v0.13.37

Choose a tag to compare

@github-actions github-actions released this 23 Oct 17:10
22e93d2

Changed

  • Watchlist and stock-page spots are pushed to the browser instead of polled. The page used to poll /api/watchlist/spots every 2.5 s on top of a 1 s WS flush, so a price change reached the screen up to ~3.6 s late. Now the WS writer sends a Postgres NOTIFY inside each flush transaction; one LISTEN connection per API process re-reads the spots and pushes only the changed tickers over Server-Sent Events at GET /api/watchlist/spots/stream (api/live_spots.py); LiveSpotsProvider opens one EventSource per page. The flush interval default drops from 1 s to 0.25 s (MASSIVE_WS_FLUSH_INTERVAL_SECONDS). Measured on a local stack through the Next proxy: an event every ~0.25 s, and 3.4 ms median (6.3 ms max) from the DB commit to the browser. The stream sends Cache-Control: no-transform, because Next's rewrite proxy otherwise gzips it for any browser that accepts gzip and holds every event in the gzip buffer. The API pings every 2 s and the page reopens a stream that is silent for 5 s or closed for good: when the API restarts, the Next proxy can leave the browser's half of the stream open and silent. uvicorn gets --timeout-graceful-shutdown in dev.sh (1 s) and docker-compose.yml (3 s), because an open stream otherwise blocks a reload forever. The mini runs its own copy of the compose file, so there the stop stays bounded by Docker's 10 s SIGKILL until that copy is synced. GET /api/watchlist/spots stays for other readers.

v0.13.36

Choose a tag to compare

@github-actions github-actions released this 22 Oct 01:49
4310bac

Fixed

  • The SPX GEX scan runs again; it had been stuck on 2026-10-03. Since 2026-10-05 UW answers /stock/SPX/stock-state with HTTP 422 ("not available for index ticker SPX") and returns close: null in the SPX iv-rank row, so scanners/gex.run had no spot and aborted every 2 minutes. The other 11 tickers succeeded, so the job never failed and the Regime GEX tab kept showing the last SPX snapshot. The scan now takes the spot from the live WS quote in intraday_quote (xenon primary; SPX is always subscribed via REGIME_WS_SYMBOLS) when UW has none, tags spot_source with the feed, and sets tape_time to the quote time. A quote older than 24 h means the feed is down, and the scan still aborts. Intraday SPX snapshots from 2026-10-05 until this deploy are lost; the first good scan refills greek_exposure_daily for SPX, because UW's aggregate endpoint returns the full daily series.

v0.13.35

Choose a tag to compare

@github-actions github-actions released this 19 Oct 14:05
463b0c2

Fixed

  • The spot WS consumer now authenticates to xenon's realtime relay. xenon v0.9.0 rejects a WebSocket upgrade from a service client unless it carries X-API-Key and no Origin header. XenonWsClient (the live session and the fallback probe) now sends X-API-Key: $XENON_QUERY_API_KEY on the upgrade when the key is set, and never an Origin. Older relays ignore the header. websockets logs every upgrade header and frame at DEBUG, so the client hands it a logger that renders each record (message, args, exception, stack) to text and prints the key as ***; the consumer's own failover and probe logs name only the exception type and, for a rejected upgrade, its HTTP status, because a rejection response can echo the key. Without the key, xenon v0.9.0 answers 401 and the consumer fails over to massive, so the mini's argon .env must carry XENON_QUERY_API_KEY (the same key the REST greeks API needs) and the WS consumer must restart to pick up a rotated key.

v0.13.34

Choose a tag to compare

@github-actions github-actions released this 15 Oct 09:31
77002d8

Changed

  • The nightly gold factor reads its prices from the livewire lake, not xenon. gold_factor_compute now reads XAUUSD (bronze/asset_class=cmdty) and the six dollar-index pairs (bronze/asset_class=fx_ib) as IB 1-day MIDPOINT closes from the lake that livewire writes at ~17:20 New York, and moves from 17:40 to 17:50 ET. It no longer stores raw prices: the source='IB' rows in macro_series_daily stay but stop growing, and fetch_ib_legs / xenon_query.fetch_ib_daily_midpoints are deleted. Only completed bars are used (a bar dated D closes 17:00 New York on D); xenon returned the bar still forming, so prod stored partial days (dxy_synthetic_daily 2026-10-14 = 102.116 from a mid-session bar, 102.528 from the final one). When a leg's last lake bar is older than the last completed NYSE session the job still computes, then fails naming the legs, so a missed livewire run reaches job_failures. The lake also carries sessions the old chunked xenon seed dropped at its window seams (around Feb 1), adding 11 factor rows; recomputed on prod data the fitted slopes move by at most 0.35 (b_s) over the whole history and 0.022 since 2025, and the latest rows are identical. gold_factor_daily and dxy_synthetic_daily join the data-freshness monitor.

v0.13.33

Choose a tag to compare

@github-actions github-actions released this 14 Oct 07:53
a964910

Added

  • Treasuries tab (02): gold real-yield sensitivity, honest model attribution, per-series data dates. The rates macro tab gains a "Gold · real-yield sensitivity" panel beside the decompositions — the gold factor's real-yield slope with its 95% interval, live only (/api/gold/factor takes no as_of, so it hides under replay) and carrying "Describes the past, not a forecast · the direction test (Phase 3) failed". RatesDecompositionAttribution gains model_vintage_changed: when both window ends read the same monthly Cleveland vintage the five model columns print — ("no new monthly model value in this window") instead of a misleading +0.0, and the 1M read names the vintage rather than "accounts for 0.0bps". RatesSourceFreshness gains first_seen_at, and a compact "Data dates" table inside the curve panel lists each yield series' observation date and argon first-storage time in New York; the caption states that FRED's own publish time is not stored.

Fixed

  • Macro desk charts rendered their text at 9–23px instead of the designed px. .board .chart svg { width: 100%; height: auto } stretches a fixed viewBox's coordinate system — text included — so the gold-factor charts, the DXY panels, usd-gold-month, the gold-flow minis, the Fed paths chart, the dealer-path and SEP dot-plot charts and the yield curve drew on 300/620/760/1200-unit frames that a ~1590px single-column panel magnified and a narrow column shrank. The new lib/useChartWidth hook measures each chart's rendered width (ResizeObserver + initial getBoundingClientRect, disconnect on unmount; the fallback width stands under jsdom/SSR) and those charts now draw viewBox equal to the measured width, so one user unit is one CSS pixel and 10px labels render at 10px at any viewport.

v0.13.32

Choose a tag to compare

@github-actions github-actions released this 14 Oct 04:25
64ed82c

Fixed

  • The nightly gold factor job failed on its first xenon leg. xenon answers 503 when its idle IB data socket was reset, and reconnects on that same request; XAUUSD is fetched first, so it took the 503 and the other six legs passed (job_failures on prod: 2 consecutive failures, the last at 17:46 ET on 2026-10-13, no success yet). fetch_ib_legs now retries a leg once, 5 s after a SourceUnavailable. The factor compute still ran on those nights on stored prices; only the XAUUSD refresh was missed.

v0.13.31

Choose a tag to compare

@github-actions github-actions released this 14 Oct 03:27
fa9a4f0

Added

  • Macro desk redesign, design v3: the gold factor model on the overview, gold and USD tabs. The overview's first zone now shows state changes, market moves for the week and gold's sensitivity from the factor model. The new "What moved gold" section follows it, and the chain rail's gold node prints "3 factors explain N%". The 60-day gold–real-yield correlation panel and its gauge fetch are gone. The market-moves panel gains a "Dollar index (DXY)" row (after the three yields) and drops the weekly Fed broad index. The gold tab (live) opens with the research result (sensitivities with 95% intervals, explained share against its two thresholds), then the breakdown (window waterfall 1W/1M/YTD, year to date, each year as "3 factors vs rest" by default or all five parts, slope history), flows and holdings, and an attribution review (drift vs gold this year, the regrouping, the yearly table). The live gold tab no longer shows the GLD 60-day Compass panels; replay and /gold/replay/<date> keep them. The USD tab (live) opens with the synthetic DXY (level, 1W/1M/YTD moves), its move split by currency, gold's dollar sensitivity with its interval, and this month's gold move against its dollar part; the Fed broad index stays below as reference. Every research panel carries "Describes the past, not a forecast · the direction test (Phase 3) failed". Flow panels draw only series argon stores history for: China's reported reserves (quarterly), CFTC managed-money net as % of open interest (weekly) and the LBMA vault (monthly); SGE withdrawals and the Shanghai premium have no ingest and no panel.
  • Synthetic ICE dollar index, stored as a result. gold_factor_compute now also writes dxy_synthetic_daily (migration 163): the index from the six IB FX closes it already fetches (50.14348112 × EURUSD^-0.576 × USDJPY^0.136 × GBPUSD^-0.119 × USDCAD^0.091 × USDSEK^0.042 × USDCHF^0.036), its daily log change, and each currency's part, which add up to that change exactly. GET /api/macro/dxy?from= serves it (default last 5 years; 404 until the job has run). GET /api/gold/flows serves the three stored flow histories. The table is enrolled in the gap-healer registry as freshness-only (61 entries). Engine macro/gold_factor.py::dxy_daily.
  • Treasuries page plan (docs/superpowers/plans/2026-10-13-macro-treasuries-page-plan.md): gold's real-yield sensitivity beside the 10-year split, the "model accounts for 0.0bp" row (the monthly model has no new vintage inside the window), and data and release dates on each yield. Plan only.

v0.13.30

Choose a tag to compare

@github-actions github-actions released this 11 Oct 12:39
9c49004

Added

  • Gold factor model, computed by argon. A port of the signal-lab gold study: a rolling 252-day fit of gold's daily move (XAUUSD) on the 10-year real yield (DFII10), a synthetic ICE dollar index and a safe-haven spread, with coefficients lagged two rows. It produces the 95% intervals, the 63-day explained share and its label, and each day's move split into real-yield, dollar, safe-haven, last-year's-pace and unexplained parts. It is a historical description, not a forecast: the study's direction test failed. Engine macro/gold_factor.py. Results go to gold_factor_daily (migration 162). The new gold_factor_compute job (17:40 ET Mon–Fri, massive-0) fetches the last month of IB 1-day MIDPOINT closes through xenon POST /historical/bars, stores them in macro_series_daily (source IB), then recomputes and upserts the whole history. The IB fetch runs only when XENON_QUERY_API_KEY is set, and needs xenon PR #174 deployed. GET /api/gold/factor serves daily points and yearly sums. The Gold tab opens with a "What moved gold" band of six charts. scripts/backfill/gold_factor_seed.py seeds the history: IB closes through xenon in overlapping 6-year windows (one call of 17 years or more outruns IB's 60 s timeout), plus FRED DFII10/DGS10 from 2010 run through the real FRED job. scripts/research/gold_factor_parity.py checks the port: from the study's own IB closes, argon matches the study exactly on inputs, coefficients, intervals, parts and labels; with --xenon, the same run on closes pulled through xenon matches it exactly too, on all 4079 rows (docs/research/2026-10-10-gold-factor-parity.json). statsmodels (already installed via arch) is now declared.

v0.13.29

Choose a tag to compare

@github-actions github-actions released this 05 Oct 09:33
1d26ae7

Added

  • Budgeted backfill of dark-pool and lit print history. Before v0.13.28 the nightly capture kept at most 500 prints per ticker, day and source, so busy names lost most of each session. The new dark_lit_backfill job (daily 22:30 ET, uw-0, UW_SCAN_DARK_LIT_BACKFILL_ENABLED, default off) re-pages every active-watchlist ticker-day that was cut (500 or more prints in either source) or is missing, oldest first, from UW's earliest available date through 2026-10-05. It writes through the same capture_dark_lit_for as the nightly capture. Each run spends at most one UW budget day's cap (UTC day; UW_SCAN_DARK_LIT_BACKFILL_WEEKDAY_MAX_CALLS 15,000, _SATURDAY_ 60,000, _SUNDAY_ 60,000), counted from its own rows in external_api_requests, and also stops when the research-pool governor says no. Progress is stored per ticker-day in dark_lit_backfill_progress, so a restart resumes where it stopped; dates UW refuses as outside its 730-trading-day window are recorded as unavailable and skipped. Each run writes its calls, finished ticker-days, remaining count and stop reason to dark_lit_backfill_runs (migration 161).