spb/anomaly-atlas Public License
Systematic discovery & rigorous validation of statistical anomalies in open HF market data (hfmarketdata.io) — pre-registered, artifact-null-driven, fully reproducible. Live atlas: www.anomaly-atlas.io
Python 61.4%
JavaScript 28.7%
CSS 8.6%
Shell 0.7%
Makefile 0.5%
1---2project: anomaly-atlas3document: Research log4author: Simon-Pierre Boucher5contact: contact@spboucher.ai6data_source: hfmarketdata.io7created: 2026-08-128status: draft9---1011# Research log — anomaly-atlas1213Append-only. Every entry: date/time+timezone, question, experiment, result,14interpretation, decision (CLAUDE.md §12).1516## 2026-08-12 21:00 ET — Project bootstrap1718**Question.** None yet — administrative.1920**Action.** Repository scaffolded per CLAUDE.md §3, mirroring the21localvm-research layout (the `site/` of the charter is implemented as `web/`,22a Node/Express research-showcase platform, like localvm-research). Author23headers with the mandatory `Data src: hfmarketdata.io` field on every source24file; `tools/check_headers.py` enforces them. Web platform deployed on25MacLustr node M3U96b (port 8150) behind ngrok at www.anomaly-atlas.io.2627**Decision.** Next step is Phase 0.5 / Experiment A (data reality check):28establish empirically what hfmarketdata.io actually provides before any29methodology is designed. No statistical work before the detectors pass the30synthetic-series tests (§8.1).3132## 2026-08-12 01:50 ET — Phase 0.5 complete: Experiment A (data reality check)3334**Question.** What does hfmarketdata.io actually provide (granularity,35depth, timestamps, adjustments, completeness, limits)?3637**Experiment.** expA_data_reality — 8 probe families through the newly38implemented single client (`hf_client.py`: cache-first, throttled, back-off,39data-manifest index; 5 offline unit tests pass). 54 network requests,40274 571 rows; re-run served 100 % from cache (0 network requests).4142**Result.** 1min granularity is real; stock/etf from 2000, futures/index 2008,43fx 2010, crypto 2013; options daily chains 2010→2026 (67 quarters). Timestamps44US/Eastern bar-start. Archive lags ~2–5 days. Hard 50k-row cap (client45paginates, verified 218 006 rows, 0 dupes). Split arithmetic exact;46adj_splitdiv re-bases history to build date. No zero-volume bars — missing47minutes are real gaps. Daily bars = RTH + auction close + consolidated volume48NOT present in 1min bars.4950**Interpretation.** Dataset is fit for Q1–Q3. Four built-in artifact51mechanisms identified (non-synchronous sessions, stale prints, auction-close52mismatch, rolling adjustment anchor) — these seed the artifact taxonomy and53the expB nulls.5455**Decision.** Full findings in research/data_source_profile.md (status:56reviewed). Next: expB_artifact_baselines + Phase 1 literature sweep.5758## 2026-08-12 02:15 ET — expB complete: artifact nulls measured (after the §8.1 gate caught a real bug)5960**Question.** Are the bounce/staleness/non-synchronicity artifacts measurable61and material at 1min on this data?6263**Experiment.** Built generators with known ground truth + first real stats64modules (reversion, leadlag, bootstrap, artifacts). The mandatory synthetic65gate (11 tests) CAUGHT A REAL BUG before any real data was touched: the66variance-ratio estimator divided by q twice (VR ≈ 1/q on a pure random walk).67Fixed; all detectors then read 0 on random walks and recover planted effects.68expB then ran the pre-specified protocol (hypothesis.md written first):6912 liquid + 30 seed-42 random tickers, Q1 2024, RTH 1min, 47 requests,70795k rows.7172**Result.** Median by staleness tercile (staleness | AC1 | Roll spread |73VR30 | SPY-leads-+1min): fresh 0.00 | −0.009 | 1.4bp | 0.97 | +0.005;74mid 0.11 | −0.051 | 3.8bp | 0.90 | +0.047; stale 0.69 | −0.232 | 17bp |750.55 | +0.021. Spearman(staleness, SPY-lead) = +0.43. SPX-vs-SPY: SPY leads76by 1min at +0.065. Mega-caps: no measurable bounce (AC1 CI covers 0).7778**Interpretation.** Uncorrected VR/AC1 scans on mid/low-liquidity names are79dominated by plumbing, not economics. Nulls usable; both falsification80criteria failed to trigger. All Level 0 by construction.8182**Decision.** artifact_taxonomy.md now carries 7 entries with measured83magnitudes (T1–T7). Next: expC consumes the bucket-matched bounce null;84Phase 1 literature sweep in parallel.8586## 2026-08-12 02:45 ET — Phase 1 complete: literature sweep (52 verified sources)8788**Question.** What does the literature establish about Q1-Q3 anomalies, the89statistics of not fooling yourself, microstructure artifacts, and costs?9091**Method.** Three parallel verification passes against OpenAlex (every92citation confirmed: title, authors, year, venue, DOI; access date932026-08-12), plus discovery searches for 2005-2025 decay/replication work.94Six theme notes written in research/notes/; consolidated bibliography.9596**Key priors adopted.** (i) McLean-Pontiff: -26% OOS, -58% post-publication97— the base rate. (ii) Sullivan-Timmermann-White: calendar effects vanish98under the Reality Check. (iii) Chordia-Goyal-Saretto/Harvey-Liu-Zhu:99t-hurdle >= 3.0 floor, 3.4-3.8 band reported. (iv) Novy-Marx-Velikov +100Chen-Velikov: high-turnover (short-horizon) anomalies mostly die at costs101(~4bp/month average net). (v) Chordia-Roll-Subrahmanyam: minute-scale102inefficiencies arbitraged within 5-60 min already by 2005. (vi) Marquering103et al.: turn-of-month was the last calendar survivor (2006) — the single104most interesting re-test. (vii) EDGE (Ardia et al. 2024) chosen as primary105OHLC spread estimator for expG.106107**Decision.** Error-rate ladder fixed for Phase 9: FDR for scans -> SPA/StepM108vs artifact nulls for Level 1 -> DSR with logged trial counts. Next: Phase 2109state-of-the-art map, then research_gaps (Phase 3). In parallel (user110request): major web platform upgrade (mobile + comments).111112## 2026-08-12 03:30 ET — Phases 2–4 complete: state of the art, 22 hypotheses, candidates selected113114**Question.** Given the verified literature and the measured artifact nulls,115which hypotheses deserve prototyping?116117**Output.** state_of_the_art.md (10 anomaly families in the §5 template with118epistemic status + methods/arm64 inventory); research_gaps.md (H01–H22, each119with a constructable artifact null; MULTIPLE-TESTING BUDGET DECLARED: 22);120candidate_ranking.md (10-axis scores).121122**Selected.** C01=H15 intraday-momentum post-2018 decay; C02=H13123turn-of-month 2006–2026; C03=H11+H03 index-artifact decomposition (SPX/SPY124staleness + Fisher VR share); C04=H10 crypto-weekend→Monday-gap (novelty125pick). Reserve: H09. Controls H14/H20/H21 run inside the micro-experiment126pipeline. Selection used priors + expA/expB artifact levels only — no127real-data effect peeking.128129**Decision.** Next: expC–expE scans (consuming expB nulls), then expF130correction with the declared 22-hypothesis budget. Candidate 04 requires131crypto volume-semantics verification first (expA follow-up).132133## 2026-08-12 06:40 ET — expC complete: null mis-specification caught, corrected triage = 14 cells134135**Question.** Which reversion cells exceed the bounce null (H01, H02-scan)?136137**Experiment.** expC on TRAIN only (2000-2016; splits frozen in138universe.py BEFORE the scan). 354 requests, 10.5M rows, 127 cells,139BH-FDR per family.140141**Result.** The pre-specified EDGE+Roll bounce null is MIS-SPECIFIED142intraday (predicts AC1 −3..−27, impossible) — the 90 positive-excess143"survivors" are artifacts of the null and were DISCARDED. Post-hoc null144FIX (documented here per §12; this is a null correction, not a hypothesis145expansion; budget stays 22): MA(1)-consistent VR null. Corrected triage:14614 cells with FDR + VR30 excess < −0.05 (JPM 1min 2014-15 −0.243; MSFT1475min 2000-07; XOM/NVDA 1min) + a broad daily 2008-2015 mega-cap/index148reversal family (XOM excess_AC1 −0.133 FDR, SPY −0.055 FDR).149150**Interpretation.** H01 CONFIRMED (liquid intraday lag-1 reversion = 0 net151of bounce). Decay clause PARTIALLY FALSIFIED (flat 5min, mild 1day decay152inside train). Methodological finding adopted: variance-consistency153requirement for spread-based nulls (taxonomy T1 amended).154155**Decision.** 14 triage cells + daily-reversal family -> expF/expH. Next:156expD lead-lag scan with MA(1)-consistency lesson applied.157158## 2026-08-12 07:20 ET — expD complete: lead-lag decay measured on synchronized pairs159160**Question.** Which lead-lag survives synchronization (H07/H08 scan), and do161the H09/H11 previews hold?162163**Experiment.** expD, protocol pre-specified: 49 pair-cells, 2 windows,164raw-LOCF vs both-fresh, day-block bootstrap, BH-FDR over 98 tests.165198 requests, 8.4M rows.166167**Result.** 2006-2007: real minute-scale diffusion (SPY->XLK +0.148168both-fresh). 2014-2015: collapse to [-0.02, +0.05]; a few tiny FDR169survivors — H08's expected-negative clause formally FALSIFIED (recorded).170ES->SPY: -0.032 splice-invariant (basis-reversion-like). SPX->SPY: +0.132171both-fresh, artifact share ~0 — content staleness, not print staleness172(H11 scan-confirmed). T3 amended: LOCF artifact is non-monotone (inflates173mid-stale, dilutes ultra-stale).174175**Decision.** To expF: 2014-15 FDR residuals + ES->SPY + decay curve.176Next: expE calendar scan (pre-counted budget), then expF.177178## 2026-08-12 07:55 ET — expE complete: the calendar is empty; controls held179180**Question.** Do any of the 8 pre-declared calendar classes (H13/H14/H18)181beat the permuted-calendar null on SPY train?182183**Experiment.** expE — budget pre-counted at 8 tests, single declared184instrument, within-year permutation null (n=2000, seed 42) with family-wise185max-stat, plus the H20 intraday profile measurement. 1 new API request186(rest cache-served).187188**Result.** ZERO survivors (family-wise p >= 0.93 everywhere). Monday189negative control held (-1.4bp, p .73). Turn-of-month — the 2006-era last190survivor — fails (p_marg .24) and decays inside train (+7.9bp -> +1.6bp).191Holiday power is low (n=144, bands +/-21bp) — reported as such. H20:192volatility U-shape confirmed (6.6/2.4/2.9 bp); spread declines 2.8 -> 1.2bp193(L-shape, not U) — taxonomy updated with the measured profile.194195**Interpretation.** STW (2001) reproduced on open data with an honest196budget. Candidate 02 (turn-of-month) now carries a dead-on-arrival prior197into its validation protocol — the expected atlas outcome is a first-class198negative finding.199200**Decision.** Nothing from expE enters the expF pool. Next: expF correction201battery over the C/D triage output, with the declared 22-hypothesis budget.202203## 2026-08-12 08:40 ET — expF complete: the survival curve, and its methodological headline204205**Question.** What fraction of the searched universe survives honest206search correction (charter result-type E)?207208**Experiment.** expF — 372 signed rules from EVERYTHING C/D/E searched,2096 blocks, White RC + Hansen SPA (500 stationary bootstraps, gate-tested)210+ BH-FDR + DSR. 0 network requests — fully served by the frozen cache.211212**Result.** Gross funnel: 372 -> 232 naive (62%) -> 226 FDR (61%) -> 68 SPA213step-1 (18%). Best "Sharpes" 10-31 annualized = the §12 red flag. The known214SPX->SPY artifact SURVIVES SPA (canary). expE calendar block: nothing215survives (tripwire did not fire). Intersection with expC's216artifact-adjusted triage: 12/14 cells; plus -L:ES->SPY.217218**Interpretation.** Statistical correction corrects for SEARCH, not219MECHANISM: SPA survivors are dominated by bounce harvesting and220frictionless timing. Honest validation needs artifact nulls AND search221correction AND costs — no substitutions. Added to methodology as an axiom222with this experiment as the demonstration.223224**Decision.** Double-filtered pool (12 reversion cells + ES->SPY + expD2252014-15 FDR set) -> expG cost frontier. SPX->SPY routed to candidate 03.226227## 2026-08-12 09:10 ET — expG complete: the cost frontier kills the pool228229**Question.** Where does each double-filtered survivor's net effect cross230zero (Q5)?231232**Experiment.** expG — pool rebuilt mechanically from committed results233(31 rules), net = gross - kappa*(EDGE/2)*turnover, kappa in {0,.1,.25,.5,2341,2}, block-bootstrap CIs, breakeven kappa* per rule.235236**Result.** Median kappa* = 0.0114 (max 0.28). Survivors: 3 at kappa=0.1,2371 at 0.25 (CKX 1day), 0 at 0.5 and beyond. Zero intraday rules survive238kappa=1 (pre-registered falsification did not trigger). ES->SPY kappa* =2390.0028, splice-invariant.240241**Interpretation.** The gross survivors were harvesting the spread they242would have to pay — Novy-Marx-Velikov/Chen-Velikov reproduced on open243data. Three-layer doctrine complete: artifact nulls (scans) + search244correction (expF) + costs (expG), none substitutable.245246**Decision.** expH validation split: CKX 1day (skeptical prior), the daily2472008-15 reversal family (for the record), and the negative finding itself248("nothing intraday survives costs") — candidate for the atlas's first249entries.250251## 2026-08-12 10:05 ET — expH complete: the ladder closes; first atlas entries252253**Question.** Do the train-split survivors and the negative finding hold on254the untouched validation split (2016-2021)?255256**Experiment.** expH — validation opened for the first time (418 requests,25718.8M rows). Machinery imported from committed expC/expD/expG benchmarks.258259**Result.** Negative finding REPLICATES (0 net survivors at kappa=1; only260CKX at 0.25). CKX fails its pre-registered two-sub-period clause (2019-21261CI covers 0; kappa* decays 0.445->0.263) — not confirmed, holdout NOT262spent. ES->SPY flips sign (+0.003, p=0.68). Daily reversal family:263VR30 excess -0.143 -> +0.023 — crisis-regime confirmed. SPX->SPY artifact264persists (+0.080): artifacts replicate, "alphas" do not.265266**Decision.** Atlas receives its first entries: F001 (Level 2 negative267finding: nothing in the searched universe survives the full ladder) and268F002 (Level 2 artifact demonstration: the SPX->SPY lead is content269staleness). Holdout stays sealed. Publications tab launched with P001270(Part I, train results); Part II will carry these OOS verdicts.271