Skip to content

feat: market context: SPY regime, VIX and breadth in the report and on backtest rows - #105

Merged
yanivil merged 1 commit into
mainfrom
feat/market-context
Sep 8, 2026
Merged

yanivil merged 1 commit into
mainfrom
feat/market-context

Conversation

@yanivil

@yanivil yanivil commented Sep 8, 2026

Copy link
Copy Markdown
Owner

Description

Implements #93. Informational only: nothing gates on the context.

  • Scan. MARKET_INDEX (SPY) and MARKET_VOL (^VIX) go through the same download_history as the universe, cut to the scanned bar; breadth comes from the histories already downloaded (share of scanned symbols whose close is above their own 200-bar SMA, among those with 200 bars). meta.market carries the index close, its distance from the SMA200 and the SMA50's distance from the SMA200 in percent, the regime those name (bull: both above, bear: both below, neutral otherwise), the VIX close and the breadth. One header line in the report: Market: SPY 8.5 % above its SMA200, SMA50 > SMA200 (bull); VIX 14.5; 90% of 10 symbols above their SMA200. A failed fetch leaves the fields null and the line names what is missing; it never fails the run.
  • Backtest. Every row carries regime, VIX, breadth and SPY-vs-SMA200 at its scan day through the same scan.market_series, so the scan and the replay define the context identically. Summaries gain a per-regime slice; VIX and breadth join the feature buckets. JSON gains market_symbols.
  • Wiki 01 (ingestion and output contract), wiki 03 (constants table and a short evidence note), README meta sentence, changelog.

Verified locally: ruff clean, 128 tests pass (4 new: series and context arithmetic including a bear-regime index, header line formatting and degradation, end to end with SPY and ^VIX in the fake yfinance, backtest rows and the regime slice). A 10-ticker real scan renders the header line and meta.market; a 30-ticker two-year backtest with --split shows the regime slices and the VIX and breadth buckets per window.

Related Issues

Closes #93
Related: #101 (VIX below 15), #95 (multi-year replay before any rule)

Checklist

  • Code follows existing project style and type annotations
  • Threshold changes include a one-line "why" comment in scan.py (two new constants, commented; no threshold changed)
  • Offline unit tests pass (python -m pytest -q)
  • Random-walk false-positive rate stays under 5% (detection logic untouched)
  • Documentation updated in docs/wiki/
  • CHANGELOG.md updated

🤖 Generated with Claude Code

….market and on backtest rows

The scan fetches SPY and ^VIX through the same download and cleaning as the
universe, cut to the scanned bar, and computes the breadth of the universe
(share of scanned symbols above their own SMA200). meta.market carries the
index close, its distance from the SMA200, the SMA50's distance from the
SMA200, the regime those name (bull, bear, neutral), the VIX and the breadth;
the report header gets one line. A failed fetch leaves the fields null and the
line names what is missing; nothing gates on the context.

The backtest puts the regime, VIX, breadth and SPY-vs-SMA200 at the scan day
on every row through the same market_series, adds a per-regime slice to every
summary, and VIX and breadth to the feature buckets.

Closes #93.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@yanivil
yanivil merged commit 922510a into main Sep 8, 2026
5 of 6 checks passed
@yanivil
yanivil deleted the feat/market-context branch September 8, 2026 04:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Market context: SPY regime, VIX and breadth in the report header and on backtest rows

1 participant