# Adjusted-opens audit — 2026-08-01

**Panel item A-salvage** (quant panel 2026-08-01) — ops hygiene, report-only,
no registration. Salvaged from the killed overnight/intraday co-signal item:
the signal died 3/3, the data hygiene shipped standalone.

## Why opens deserve their own audit

Every price in `data/raw` is *adjusted* — the vendor rescales history so
splits and dividends don't look like price moves. Vendors are careful with
closes (index products depend on them) and sloppy with opens, which ride
along on whatever adjustment factor was handy. The open is therefore the
least-trusted field in any feed. This shop's exposure is direct: the engine
fills at the next open (`costs.execution_timing: next_open`) and splits every
rebalance-day return into an overnight leg (old book, close→open) times an
intraday leg (new book, open→close). By algebra the two legs always multiply
back to close-to-close — a bad open cannot change total return on a day where
the book doesn't move — but on every transition day it silently re-attributes
P&L between the old book and the new one, and live TCA reads the same frame.

## The checks (per name-day)

- **Check 0 — composition identity** `|(open/prev_close) x (close/open) −
  close/prev_close| < 1e-9`. Trivially true by algebra when all three values
  are finite and positive — it is the tautology guard the panel item names;
  a nonzero count would mean non-finite values leaked past the presence
  checks. The real screens are the ones below.
- **Check 1 (HARD) — open missing or non-positive**: null/NaN/infinite, or
  a zero/negative print. An engine fill price that does not exist.
- **Check 2 (HARD) — open outside the day's [low, high] range**: an
  impossible bar — the day's own extremes must bracket its open. Tolerance
  matches the golden ingestion gate (relative 1e-9, floored at $1), so
  adjustment float-dust never fires but a cents-level violation does.
- **Check 3 (census) — |overnight| > 20% days**, classified against the
  panel's corporate-action heuristic: a **volume spike** (>= 3x trailing
  21-session median — the real-news fingerprint) or a **split-like ratio**
  (overnight gross ratio within 2% of a small-integer split ratio — in
  properly adjusted data a split leaves *no* jump, so landing on one is the
  mis-adjustment fingerprint). Two extra lenses: **halt-gap context** (first
  bar after a >7-calendar-day gap) and the **reversal fingerprint**
  (|close-to-close| < 5% while the open jumped >20% — the close
  series is consistent and the open printed on the wrong basis).

Census days are *flagged for reading, never hard failures* — a real 20%
overnight move is information, not corruption. Only checks 0-2 count toward
quarantine recommendation. Classification precedence: artifact fingerprints
(split-like, reversal) require ORDINARY volume — a pure mis-adjustment leaves
the tape untouched, while a real event that happens to land near a split
ratio announces itself with a volume spike and is classified real-news.

## Results

Store: `data/raw` — **904 symbols**, **3,570,574 name-days** audited.

| Check | Name-days flagged | Symbols affected |
|---|---|---|
| 0 composition identity | 0 | 0 |
| 1 open missing (null/NaN) | 0 | 0 |
| 1 open non-positive | 0 | 0 |
| 2 open outside [low, high] | 4 | 4 |
| 2 range not evaluable (broken high/low) | 0 | 0 |
| 3 census abs(overnight) > 20% | 854 | 305 |

**Hard failures (checks 0-2): 4 name-days across 4 symbols.**

### Worst offenders — hard checks

| Symbol | Hard days | Days | Rate | Worst excursion | Examples |
|---|---|---|---|---|---|
| BK | 1 | 4,385 | 0.023% | 75.5 bps | 2021-05-05 open-outside-range open=44.0621 range=[44.3973,44.9153] excursion=75.5bps |
| CTRA | 1 | 4,363 | 0.023% | 93.1 bps | 2023-06-05 open-outside-range open=22.3057 range=[21.6790,22.0999] excursion=93.1bps |
| HUBB | 1 | 4,385 | 0.023% | 11.7 bps | 2021-05-05 open-outside-range open=180.3051 range=[180.5167,182.7523] excursion=11.7bps |
| PSTG | 1 | 2,683 | 0.037% | 42.1 bps | 2021-05-05 open-outside-range open=19.0900 range=[18.2100,19.0100] excursion=42.1bps |

### Census of big overnight moves

| Classification | Days | Share |
|---|---|---|
| split-like ratio (adjustment-artifact fingerprint) | 11 | 1.3% |
| open-only jump, close consistent, no volume (bad-open fingerprint) | 51 | 6.0% |
| volume spike >= 3x trailing median (real-news fingerprint) | 648 | 75.9% |
| unexplained (no corporate-action fingerprint) | 144 | 16.9% |

Most suspicious days (artifact fingerprints, largest first):

| Symbol | Date | Overnight | Close-to-close | Vol ratio | Fingerprint |
|---|---|---|---|---|---|
| GME | 2021-01-29 | +96.1% | +67.9% | 1.5x | split-like ratio |
| CELH | 2011-10-07 | +86.7% | +0.0% | 1.6x | open-only jump, close consistent, no volume |
| CELH | 2011-01-24 | +52.0% | +12.0% | 0.8x | split-like ratio |
| CHRD | 2020-10-12 | -50.0% | -37.5% | 1.3x | split-like ratio |
| CELH | 2009-03-09 | +50.0% | +25.0% | 2.5x | split-like ratio |
| PEGA | 2020-03-16 | -49.3% | -15.9% | 1.6x | split-like ratio |
| CELH | 2012-04-24 | +38.5% | +0.0% | 0.1x | open-only jump, close consistent, no volume |
| OZK | 2020-03-16 | -33.9% | -7.0% | 1.7x | split-like ratio |
| CELH | 2009-02-02 | -33.3% | +0.0% | 1.1x | split-like ratio |
| CELH | 2012-01-18 | +33.3% | +4.8% | 1.2x | open-only jump, close consistent, no volume |
| KTOS | 2009-10-02 | -32.8% | -4.3% | 0.4x | split-like ratio |
| CELH | 2011-05-18 | -32.4% | -11.8% | 1.8x | split-like ratio |
| CELH | 2009-12-24 | -32.2% | -13.0% | 0.3x | split-like ratio |
| BYD | 2020-03-16 | -32.1% | -29.3% | 1.5x | split-like ratio |
| ARWR | 2009-12-24 | +30.2% | +0.0% | 1.7x | open-only jump, close consistent, no volume |

Symbols with the most big-overnight days: CELH (114), GME (18), CHRD (13), ARWR (12), SW (12), CVNA (11), ALGN (9), PCG (9), RH (9), ANF (8).

## Reading the results (analysis of this run — not regenerated by the script)

1. **The store is clean where it matters: 4 hard-failure name-days in 3,570,574
   (~1.1 per million).** No missing, NaN, or non-positive opens anywhere; the
   composition identity held on every row (as it must by algebra — its zero
   count confirms no non-finite values slipped past the presence checks).

2. **Three of the four hard failures are a known, already-recorded vendor
   glitch — the audit independently rediscovered it.** BK, HUBB, and PSTG on
   2021-05-05 are exactly the three "material vendor OHLC glitches" the golden
   store's integrity audit recorded in `data/golden/MANIFEST.json`
   (`integrity_audit.material_ohlc_anomalies`, built 2026-06-07: a vendor
   dividend-adjustment glitch that pushed the adjusted open outside [low,
   high]; kept verbatim there, non-rebalance dates, high/low/close correct).
   Two instruments built independently converging on the same three bars is
   mutual validation of both.

3. **The fourth — CTRA 2023-06-05, at 93 bps the largest excursion — is NEW,
   and it is fresh evidence for the freeze-and-own doctrine.** The golden
   store's frozen CTRA copy has a valid bar for that date (open = high =
   22.3164); today's `data/raw` copy has open 22.3057 above a high of 22.0999,
   and a different volume (6.50M vs 6.93M). Every field of the raw row differs
   from the copy frozen on 2026-06-07 — the row changed in some later vendor
   re-fetch, and the re-based version is an impossible bar. This is the
   "re-fetching re-bases adjusted prices" failure mode
   (memory/backtest-data-reproducibility) surfacing as concrete corruption:
   the frozen golden copy is the trustworthy one.

4. **Read the census table with its dates in mind — the volume-spike
   fingerprint has a known blind spot in manias and crashes.** The trailing
   21-session median volume is itself inflated during a sustained frenzy, so
   follow-on REAL days lose their volume fingerprint: GME 2021-01-29 (+96.1%
   overnight, the squeeze aftermath — trailing baseline already meme-inflated,
   ratio only 1.5x) lands split-like, and several 2020-03-16 COVID-crash-Monday
   gaps (PEGA, OZK, BYD — the whole market gapped down hard that morning) do
   too. These are real moves mislabeled by a conservative classifier, not
   adjustment errors; the census is a reading aid, not a verdict.

5. **CELH accounts for 114 of the 854 census days — 111 of them in 2009-2015,
   its thin-tape penny-stock era.** A thin tape gaps hugely for real, but
   several CELH days are open-only jumps with a flat close (+86.7% overnight
   on 2011-10-07 against a 0.0% close-to-close) — the classic bad-open print.
   CELH's bars are internally consistent (opens inside [low, high]), so it
   fails no hard check and earns no quarantine recommendation; but any
   research that reads pre-2016 CELH opens (overnight/intraday
   decompositions, open-fill simulations of that era) should treat them as
   untrustworthy.

**Bottom line:** the opens in `data/raw` are fit for their production purpose —
the engine's next-open fill and the TCA arrival frame — at a hard-failure rate
of ~1 per million name-days, every failure a sub-1% excursion on a single
isolated bar. The recommended quarantine list is empty under the pinned >0.1%
rule.

## Recommended quarantine list

Names failing hard checks on more than 0.1% of their observed
days. **Recommend-only** — nothing is wired: quarantining is a deliberate
follow-up (it would change the tradable universe, which is a re-baseline
event, not an audit side effect).

**Empty.** No symbol exceeds the threshold.

## Reproduce

```bash
python scripts/audit_adjusted_opens.py --data-dir data/raw \
    --out research/2026-08-01_adjusted_opens_audit.md
```

Re-running writes only the mechanical sections — the "Reading the results"
section above is this run's hand-written analysis. For a fresh audit, use a
new dated `--out` (this file is the 2026-08-01 record; do not overwrite it).

Pinned parameters: overnight threshold 20%, volume-spike multiple 3x over a trailing 21-session median (min 5 obs), split-ratio tolerance 2%, reversal c2c bound 5%, halt gap >7 calendar days, hard-fail quarantine rate >0.1%, identity tolerance 1e-09.
