Skip to content

Incentive monitor v2: status/LULD, corporate-action events, screeners, 20 s sweeps, option IV, FINRA short volume (board v2) - #220

Merged
seathatflowsinourveins merged 11 commits into
mainfrom
claude/monitor-v2-20260924
Sep 25, 2026
Merged

seathatflowsinourveins merged 11 commits into
mainfrom
claude/monitor-v2-20260924

Conversation

@seathatflowsinourveins

Copy link
Copy Markdown
Owner

What (stacked on #187)

Monitor v2 uses more of the entitled and free data feeds for incentive finding. Each source records receive timestamps, and each call budget is written to monitor.jsonl.

New sources:

  • Trading status and LULD: a recorder on the IEX stock-stream endpoint (the engine owns the SIP one), merged with Nasdaq RSS halts into one halt state.
  • Corporate-actions event stream (SSE): archived, with splits, mergers, spinoffs and symbol changes surfaced as board context.
  • Screeners: most actives and top movers, once per sweep.
  • Sweep cadence: configurable, default 20 s. The data-call budget is computed and refused above 5% of the 10,000/min limit.
  • Option chain snapshots: implied volatility, greeks and open interest for the top-N board candidates, plus a per-root IV-change feature (a pre-event IV run-up signal).
  • FINRA daily short-sale volume: free and official, fetched once a day.

Board v2:

  • New components with fixed, documented weights, labelled unvalidated.
  • v1 components and weights are unchanged, and a board_version field is added.
  • v2 runs beside v1 as a follower. board_scan refuses a board whose version differs from its protocol's, so the running forward study (v1) stays on v1.

Review trail

Two independent reviews found 5 majors, all fixed in 1f136ba. The recheck approved, with 6 minors left.

Checks

  • tests.test_incentive_monitor tests.test_incentive_forward: 121 OK. Synthetic fixtures only; no live run.
  • Full python3 -m unittest: 4,065 OK (419 skipped).
  • scripts/validate.py: passed.
  • Guarded gitleaks: clean.

Next

Forward protocol v2 pairs board v2 with the engine P0 release. It gets its own pre-outcome review before any v2 order.

🤖 Generated with Claude Code

…and a preregistered paper forward study

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…t order

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…, exclusive ledger, operating companies, exact analysis)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…isions within 90 minutes of an early close

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…cans, full Trust disclosure, retry rule

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…separate from paper performance

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…reener, option chains, FINRA short volume, budgeted sweeps, board v2

Sources added to monitor.py, each recorded with receive times in owner-only files and held to an explicit per-source
call budget written to monitor.jsonl:
- IEX stock stream (v2/iex; v2/sip stays with the engine): statuses, LULD bands and imbalances for every symbol,
  merged with the Nasdaq RSS into one halt state (latest event by its own time wins); message counts per type and
  tape measure tape coverage (CTA statuses on IEX are unobserved so far). A host lease per stream endpoint refuses a
  second holder before it connects; a 406 on the IEX endpoint waits instead of contending.
- Corporate-action events (SSE on the documented stream host): every event archived, deduplicated by ULID event id,
  resumed with Last-Event-Id; splits, mergers, spin-offs and name/symbol changes surfaced as board context from a
  bounded 30-day replay plus the live stream.
- Screener: most actives by volume and by trades, top movers (3 calls per sweep).
- Option chain snapshots for the top 25 candidates by the v1 score (one page each), near-the-money implied volatility
  and a per-root IV change against the previous session (same expiry) or the first value today; open interest from
  the contracts endpoint once per root per day.
- FINRA daily consolidated short sale volume: at most one request per sweep, after 18:05 ET, stored once with a
  manifest; header and trailer count checked.
- Sweep cadence 20 s by default; the plan is refused (exit 2) above 5% of the 10,000/min data limit, above 5% of the
  200/min trading limit, or with the Nasdaq RSS polled more than once a minute; a call over its source cap is refused
  before any request.

Board v2 (board-v2.json, board_version 2) keeps every v1 component and weight (score_v1) and adds fixed, unvalidated
components: stream_news_halt 2.0, stream_volatility_halt 1.0, corporate_action 0.5, iv_runup 1.0,
short_volume_high 0.5. board.json stays board version 1. board_scan.py refuses any board whose board_version differs
from the protocol's (forward protocol v1 pins 1; the frozen protocol file is unchanged).

Evidence: synthetic fixtures and one local-integration once-sweep against a synthetic response router (no network);
docs.alpaca.markets and FINRA pages re-read 2026-09-24; the monitor was not run against live endpoints.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…review fixes

Resolve the two independent reviews of 736c555.

- Coexistence: every run declares --standalone or --follow-v1 V1_OUT. A follower
  holds no news/OPRA stream, polls neither EDGAR nor the Nasdaq RSS (zero budgets),
  reads version 1's appended lines and writes board-v2.json only. --standalone
  refuses while a version 1 monitor runs on this host (/proc). Leases live in one
  fixed per-user directory. The stream backoff resets only after data or 60 s
  connected, and 402/405/409/410 stop a stream.
- Options: chains and IV sampled 09:45-16:00 ET only. The previous-session
  baseline is the last in-session row, the first-today baseline is per expiry,
  and IV older than two sweeps no longer counts. The expiry window is 35 days
  (it always holds a monthly), an empty in-band chain is retried once without
  the band, and a chain poll has a deadline. Open interest is opt-in and paused
  near the trading limit.
- Boards: one scoring pass feeds both boards, and board.json is written before
  any v2 work, which is guarded (board_v2_error). Halts keep v1 precedence
  across sources, and any RSS halt today blocks stream_volatility_halt.
- Corporate actions: US region only, first-insert time kept, and malformed
  symbols ignored. The archive resumes from its last id whatever its age and
  records ca_resume_gap only when that id is not redelivered. An empty archive
  seeds from the retained history; the context replay is bounded and runs on
  the stream thread.
- FINRA: every failure waits an hour. Each stored file is checked once more
  after the next publication, and superseded versions are kept.
- Budgets: the daily-bar load resumes at the failed request under a
  per-minute cap, and --rss-seconds 0 is refused.
- Halts: a multi-day halt enters the merged state, and a moved resumption
  replaces the earlier one.
- Frozen v1: the monitor refuses to run beside protocol v1's frozen bridge,
  and board_scan refuses protocol v1 decisions under non-frozen code
  (code_not_frozen).

Evidence (synthetic fixtures / local integration, no network): 121 tests OK,
0 skipped, under python3 and the pinned engine venv; scripts/validate.py passed.
Every new test fails against 736c555, and 54 fix-revert mutants plus the
builder's 10 are all killed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@seathatflowsinourveins

Copy link
Copy Markdown
Owner Author

CI note (2026-09-25). validate-macos became a required check on main today (#226 and ruleset 23739774). This PR's latest CI run predates that change, so it has no validate-macos status, and GitHub shows the check as expected and waiting.

Nothing in the PR needs to change. The next push, or a close and reopen, runs the current adoption-bootstrap.yml, which reports validate-macos on every pull request.

🤖 Generated with Claude Code

@seathatflowsinourveins

Copy link
Copy Markdown
Owner Author

Trading lane, 2026-09-25: carrying this PR to merge, after #187.

The failing verdict-review-gate is expected. It fails closed because this PR's base is claude/incentive-monitor-20260924, not main; see .github/workflows/validate.yml, "Require sealed cross-family review for changed verdict rows".

Plan, following the dormant-owner merge etiquette:

  1. Merge Incentive monitor (market + non-market signals) and a preregistered paper forward study #187 once its required checks pass.
  2. Retarget this PR to main.
  3. Merge main into it, with no force-push.
  4. Re-run tests.test_incentive_monitor tests.test_incentive_forward and the repo validators.
  5. Merge on green required checks, including validate-macos and the gate, which is re-run by the retarget.

The original owner can take this back by replying here.

🤖 Generated with Claude Code

Base automatically changed from claude/incentive-monitor-20260924 to main September 25, 2026 20:01
Scout and others added 2 commits September 25, 2026 16:01
… merge

#187 was squash-merged as 3e4054d, so its files were added on both sides.
The five files this PR changes conflicted and resolve to this PR's head
(1f136ba) byte for byte. The merged tree differs from main by exactly this
PR's own delta over #187 (05c2849..1f136ba; 5 files, +3529/-122). Main's
monitor.py and board_scan.py still match FROZEN_V1.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…1 as a v2 input

board_scan.ENGINE_FILES hashes 8 engine files. The transitive import closure
of mover_runner.py within adaptive-paper/ adds 14 more modules that the list
omits, measured on main after #187:
- 4 existed when v1 froze (05c2849) and have changed since;
- 6 are unchanged since the freeze;
- 4 were added after it, including corporate_actions and financing from the
  engine P0 release.

The v1 bridge is frozen, so the gap stays in v1 as a recorded limitation.
Protocol v2 should bind the whole engine (every *.py, or a clean-checkout
tree hash) plus the runtime lock before its pre-outcome review. No v1 order
has been placed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Comment thread tests/test_incentive_monitor.py Fixed
Comment thread tests/test_incentive_monitor.py Fixed
Comment thread tests/test_incentive_monitor.py Fixed
Comment thread tests/test_incentive_monitor.py Fixed
…tname (CodeQL)

CodeQL flagged py/incomplete-url-substring-sanitization at four places in
tests/test_incentive_monitor.py: "nasdaqtrader.com" in url and "sec.gov" in u.
A substring test also matches a lookalike host or a query string. A host_is()
helper now compares urlsplit(url).hostname with the domain and its
subdomains. The router, both URL-count assertions and the unflagged sec.gov
assertion use it. host_is rejects ?u=nasdaqtrader.com,
nasdaqtrader.com.evil.example and notsec.gov. 121 tests pass on system
Python and on the pinned runtime.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@seathatflowsinourveins
seathatflowsinourveins merged commit f625b07 into main Sep 25, 2026
23 checks passed
@seathatflowsinourveins
seathatflowsinourveins deleted the claude/monitor-v2-20260924 branch September 25, 2026 20:56
@seathatflowsinourveins

Copy link
Copy Markdown
Owner Author

Merged as f625b07 (trading lane, 2026-09-25).

How it was carried after #187's squash merge (3e4054d):

Added commits:

  • 632ab76 records protocol v1's engine binding gap in the README. ENGINE_FILES hashes 8 engine files, but the import closure of mover_runner.py has 14 more; v2 should bind the whole engine.
  • d5ef208 fixes four CodeQL py/incomplete-url-substring-sanitization alerts in the tests. The router and the URL-count assertions now compare parsed hostnames instead of substrings.

Checks:

  • tests.test_incentive_monitor tests.test_incentive_forward: 121 OK on system Python and on the pinned adaptive-paper runtime.
  • All CI checks pass, including validate-macos, verdict-review-gate and CodeQL.

No v1 or v2 order has been placed. The paper keys currently return HTTP 401.

🤖 Generated with Claude Code

seathatflowsinourveins added a commit that referenced this pull request Sep 25, 2026
… incentive board and data lake, and the recounted WSL host (#288)

- simulation: 866 to 884 fills per min at 70 ms exact release, 30 of 30
  minutes, and 672 at 1 s (#254, sim-capacity/receipts/20260925-elite-tier.json).
- paper: adds the margin financing model (#243); still blocked on the
  paper keys (HTTP 401).
- mover-early-entry-studies: v1 to v3, with the v3 core merged (#190) and not
  frozen.
- New gates:
  - incentive-board-forward (#187, #220): 0 orders;
  - data-lake-source (#208): minute-bar pilot not run.
- wsl-workstation-host: the foundation lane's wording. Counts were recounted
  on main 0074a0c by the last independent_session verdict per receipt,
  superseded excluded: 69 receipts, 56 agree, 1 needs changes, 0 awaiting
  review, 12 superseded (#285).

The foundation lane acked the strings and the recount rule.

Co-authored-by: Scout <scout@local>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lane:trading Trading lane: sim, paper and live north star

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants