Skip to content

Mover v3 data files: XNYS session calendar and sourced SEC Section 31 / FINRA TAF fees (freeze precondition 2) - #186

Merged
seathatflowsinourveins merged 2 commits into
mainfrom
claude/mover-v3-calendar-fees-20260924
Sep 24, 2026
Merged

seathatflowsinourveins merged 2 commits into
mainfrom
claude/mover-v3-calendar-fees-20260924

Conversation

@seathatflowsinourveins

Copy link
Copy Markdown
Collaborator

Satisfies the data part of protocol-core-draft.json freeze_preconditions[2]: the XNYS session calendar from exchange_calendars 4.13.2, fees-v3.json with sourced SEC Section 31 and FINRA TAF rows from 2017-01-01 through retrieval (2026-09-24), and both amendment files (empty). It adds new files only. The protocol, README and other mover-v3 files are unchanged; the resolution/freeze PR copies the pins below into the protocol.

Pins (sha256, bytes)

  • blueprints/us-equities/mover-v3/data/session-calendar.json fba93303b31f68ba9fceddcaa43e09c33649852313bc948a8748abf648abe965 502703 bytes
  • blueprints/us-equities/mover-v3/data/fees-v3.json f45bed8b5b826a927716d3122ef9f0d07ce7adcb00028a9a343577f5a2677e3a 59794 bytes
  • blueprints/us-equities/mover-v3/data/session-calendar-amendments.jsonl e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 bytes
  • blueprints/us-equities/mover-v3/data/fees-v3-amendments.jsonl e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 bytes

The same values are in blueprints/us-equities/mover-v3/data-pins.json, with the generator inputs' hashes.

Session calendar

  • XNYS, exchange_calendars 4.13.2, tzdata 2026.4 (IANA 2026d); requested 2016-01-01 to 2030-12-31; sessions 2016-01-04 to 2030-12-31: 3769 sessions, 32 early closes (13:00 ET), 0 late opens. Each row: session, open/close in America/New_York (with offset) and UTC, early-close flag.
  • 2016-2020 early closes: 2016-11-25, 2017-07-03, 2017-11-24, 2018-07-03, 2018-11-23, 2018-12-24, 2019-07-03, 2019-11-29, 2019-12-24, 2020-11-27, 2020-12-24 (includes the five the protocol names). 2021-2026 early closes equal the list mover-early-entry/rules.py took from the same version. The 2018-12-05 and 2025-01-09 days of mourning are absent; yearly counts 2016-2025 are 252, 251, 251, 252, 253, 252, 251, 250, 252, 250.
  • Generator data-tools/generate_session_calendar.py with a hash-locked requirements.lock (uv pip compile --universal --generate-hashes, Python >= 3.12). Its pins equal the versions and hashes of blueprints/us-equities/data/requirements.lock, so the CI venv built from that lock (PROMOTION_GATE_PYTHON) runs the regeneration test. It uses only the pinned tzdata package and refuses any other package versions. Output was byte-identical under CPython 3.13 and 3.14 with this lock and under 3.13 with the data lock.
  • Holdout reach: the calendar must extend 432 sessions past the freeze session (N0 = +40, 252 sessions, two 63-session blocks, read due within 15 more). The end of 2030-12-31 covers any freeze session through 2029-04-12.

Fees (fees-v3.json, retrieved 2026-09-24, no unverified periods)

SEC Section 31, $ per million of covered sales, keyed by charge date. Each row cites the SEC order that set it and the next order's statement of the rate it replaced and the last date at that rate (Federal Register full text):

From To Rate Order
2016-02-16 2017-07-03 21.80 81 FR 1458 (SEC Release No. 34-76848)
2017-07-04 2018-05-21 23.10 82 FR 25895 (SEC Release No. 34-80816)
2018-05-22 2019-04-15 13.00 83 FR 17577 (SEC Release No. 34-83057)
2019-04-16 2020-02-17 20.70 84 FR 9576 (SEC Release No. 34-85287)
2020-02-18 2021-02-24 22.10 85 FR 2218 (SEC Release No. 34-87918)
2021-02-25 2022-05-13 5.10 86 FR 6694 (SEC Release No. 34-90932)
2022-05-14 2023-02-26 22.90 87 FR 21931 (SEC Release No. 34-94644)
2023-02-27 2024-05-21 8.00 88 FR 5051 (SEC Release No. 34-96724)
2024-05-22 2025-05-13 27.80 89 FR 29402 (SEC Release No. 34-99973)
2025-05-14 2026-04-03 0.00 90 FR 15492 (SEC Release No. 34-102779)
2026-04-04 open 20.60 91 FR 10643 (SEC Release No. 34-104909)

FINRA TAF, covered equity sales, $ per share with a per-trade cap, keyed by transaction date. Each row cites FINRA's versioned rule text (By-Laws Schedule A, Section 1, ?version= links) and the SEC notices of the FINRA filings:

From To Per share Cap Rule-text versions Filings
2012-07-01 2021-12-31 0.000119 5.95 524541, 524546, 524551, 1207221 77 FR 38690, 85 FR 66592
2022-01-01 2022-12-31 0.000130 6.49 1207251 85 FR 66592
2023-01-01 2023-12-31 0.000145 7.27 1803996, 1803986 85 FR 66592
2024-01-01 2025-12-31 0.000166 8.30 1880951 85 FR 66592, 89 FR 93709
2026-01-01 2026-09-30 0.000195 9.79 2009531 89 FR 93709, 91 FR 60427
2026-10-01 2026-12-31 0.000000 0.00 2009541 91 FR 60435
2027-01-01 2028-12-31 0.000195 9.79 2009881 91 FR 60427, 91 FR 60435
2029-01-01 2029-12-31 0.000232 11.61 2010041 91 FR 60427
2030-01-01 2030-12-31 0.000240 12.05 2010031 91 FR 60427
2031-01-01 open 0.000249 12.50 2010021 91 FR 60427

Every quote was checked as a verbatim substring of the retrieved text. data-tools/verify_fee_sources.py re-fetches the Federal Register, eCFR and FINRA sources and checks them again. The exception is one sec.gov sentence (the $20.60 rate stays until 60 days after the FY2027 appropriation): sec.gov answers scripted requests with HTTP 403, so it was read through a web-fetch tool and is labelled that way.

Findings the freeze PR has to decide

  1. FINRA paused the TAF for transactions from 2026-10-01 through 2026-12-31 (SR-FINRA-2026-021, filed 2026-09-15, published 91 FR 60435 on 2026-09-23). It also postponed its scheduled increases by two years (SR-FINRA-2026-020): $0.000195/$9.79 holds through 2028, then $0.000232 (2029), $0.000240 (2030) and $0.000249 (2031). Both are in the base file as scheduled rows. FINRA's fee-adjustment-schedule page still shows the old schedule.
  2. SEC Section 31 rates apply by charge date, which is the settlement date for cleared sales (17 CFR 240.31(a)(3)(i), quoted in the file), not the trade date. The protocol does not say which key the fee lookup uses. A trade-date lookup is off by the settlement cycle near each rate change.
  3. No FY2027 Section 31 rate existed at retrieval. $20.60 stays until 60 days after the FY2027 appropriation. If the SEC announces the new rate before the freeze, it is added to the base file (and the pins change); after the freeze it goes to fees-v3-amendments.jsonl. Scheduled base rows that change later also need a precedence rule for amendment lines.
  4. The amendment line format is not defined here. The amendment files are deliberately not hash-listed in manifests/evidence.json, so appending a line needs no manifest edit. Their integrity rule is the protocol's byte-prefix check, and the test enforces it against the pinned empty content. Because .gitignore ignores *.jsonl, both files were force-added, as the repo's other tracked .jsonl files were. Appends to them are ordinary modifications, but any new .jsonl log (run or access log) will also need git add -f.

Checks

Check Result
python3 scripts/validate.py exit 0, hashed_files: 5243, passed
python3 scripts/evidence_manifest.py --check exit 0, 5243 files, sorted
python3 -m unittest tests.test_mover_v3_data -v exit 0, 18 tests OK. Regeneration ran byte-for-byte from data-tools/.venv, and again with PROMOTION_GATE_PYTHON set to a venv from blueprints/us-equities/data/requirements.lock (the CI path). A wrong MOVER_V3_CALENDAR_PYTHON fails; a wrong fallback interpreter skips.
generate_session_calendar.py --check exit 0, match under CPython 3.13 and 3.14 (this lock) and 3.13 (the data lock)
verify_fee_sources.py (live re-fetch) exit 0: 95 quotes, 33 documents, 0 failures; the one sec.gov quote is reported as not checked by design. Inside the agent sandbox Python's HTTP client received truncated responses (fetch errors only; 0 mismatches among the 93 quotes it checked), so the passing run was made outside the sandbox.
python3 -m unittest (full suite, sandboxed macOS host) exit 1: 3957 tests, failures=1, errors=34, skipped=510. None are in this change's test module. The 35 are in test_offhost_app_state, test_adoption_bootstrap_macos, test_order_throughput, test_adaptive_paper_metrics, test_research_workflow and test_native_maintenance (portability tests). They are sandbox permission errors (loopback bind, /tmp, ps). Those six modules give the identical 35 failures with this change's files removed (266 tests both ways). CI is the authority.

Limits

  • These are repository integration checks and synthetic assertions. They are not exchange_calendars upstream tests, which were not run. The calendar is exchange_calendars' scheduled calendar; unscheduled future closures are handled only by amendments.
  • No market-data or broker calls and no credentials. Network use: PyPI (lock), federalregister.gov, ecfr.gov, finra.org and one sec.gov page read through a web-fetch tool.
  • Mover studies: preregistered v1 and v2 (no pass in any family), data corrections D1-D6 #162's mover-early-entry/fees.json was not used as a source.

🤖 Generated with Claude Code

Satisfies the data files of protocol-core-draft.json freeze_preconditions[2]
without editing the protocol:

- data/session-calendar.json: every scheduled XNYS session 2016-01-04 to
  2030-12-31 from exchange_calendars 4.13.2 (3769 sessions, 32 early closes),
  with open and close in America/New_York and UTC and an early-close flag.
  Generated by data-tools/generate_session_calendar.py under a hash-locked
  requirements.lock; regeneration is byte-identical and is tested.
- data/fees-v3.json: SEC Section 31 rows (Federal Register orders FY2016 to
  FY2026) and FINRA TAF covered-equity rows (FINRA versioned rule text and
  the SEC notices of the FINRA filings), 2017-01-01 through retrieval on
  2026-09-24 plus adopted later rates, each with verbatim quotes. This
  includes the TAF pause for October to December 2026 (SR-FINRA-2026-021)
  and the two-year postponement (SR-FINRA-2026-020).
- data/session-calendar-amendments.jsonl and data/fees-v3-amendments.jsonl:
  empty, append-only (force-added because .gitignore ignores *.jsonl).
- data-pins.json records sha256 and bytes; tests/test_mover_v3_data.py
  checks pins, structure, sources and regeneration; verify_fee_sources.py
  re-fetches the sources and checks the quotes.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
@seathatflowsinourveins seathatflowsinourveins added the lane:trading Trading lane: sim, paper and live north star label Sep 24, 2026
@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.

test_osv_lockfile_coverage requires every tracked lockfile to be listed in
.github/osv-scanner-lockfiles.json; add data-tools/requirements.lock (with its
requirements.in covered by the lock) and refresh the list's evidence hash.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
@seathatflowsinourveins
seathatflowsinourveins merged commit b165579 into main Sep 24, 2026
22 checks passed
@seathatflowsinourveins
seathatflowsinourveins deleted the claude/mover-v3-calendar-fees-20260924 branch September 24, 2026 15:18
seathatflowsinourveins added a commit that referenced this pull request Sep 24, 2026
…ptance item 2)

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
seathatflowsinourveins pushed a commit that referenced this pull request Sep 25, 2026
Main moved 150+ commits, including #186 and #194 (the v3 data files and
calendar extension) and #197 (leverage-ladder gate wording in the v3
README, which merged cleanly). manifests/evidence.json is main's registry
with the stale digests refreshed. The study tree is bound by its own tree
hash and pinned copies, and was never registered there.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
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.

1 participant