# Pre-registration: How fast edges die (study #1)

**Registered:** 2026-11-08, before any statistic in this document was computed on this data.
**Status:** frozen. Any change after the first run is a deviation. Deviations get logged in
RESULTS.md with the reason; this file is never edited.

## Question

Once a FanDuel or DraftKings price is flagged +EV against the no-vig market consensus, how
long does the flag last?

## Data

- File: `~/data/plusevbets-archive/ev_snapshots_through_2026-11-07.csv.gz`, exported from
  `ev_snapshots` on 2026-11-07. Expected 1,622,957 rows and 45 columns; the run aborts on any
  mismatch. Only the header, the row count and `ev_snapshots_schema.txt` were read before
  this file was written.
- Books: DraftKings and FanDuel (all that the table holds). Seven sports.
- Rows used: pre-commence only (`snapshot_time < commence_time`).
- Games used: `commence_time` in [2026-10-15 00:00, 2026-11-07 18:15) UTC. The archive starts
  2026-10-08 00:00. The 7-day buffer keeps out games whose pre-game polling began before the
  archive did; the end bound keeps out games whose pre-game window the export cut off.
- No new data is collected.

## Definitions

- **Series:** one (game_id, bookmaker, market_type), ordered by `snapshot_time`. Its polls are
  the rows that exist for it.
- **Alive (side s, poll p):** `best_bet_side == s` and `best_bet_ev_percent > 0`. This is the
  product's own flag. A NULL `best_bet_ev_percent` is unknown, not dead.
  - *Primary definition:* the side stays flagged at any price or point.
  - *Secondary definition:* the side stays flagged at the same `best_bet_price` and
    `best_bet_point`. If either changes, the flag counts as dead.
- **Flag (the unit):** the first poll in a series at which s is alive, where the series has a
  previous poll and s was not alive at it.
  - A flag on a series' first poll is left-truncated. It is excluded, and the number excluded
    is reported.
  - Re-entries after a death are not counted.
- **Lifetime interval:** `[t_last_alive − t_flag, t_death − t_prev]`. Here `t_prev` is the poll
  before the flag, `t_last_alive` is the last consecutive alive poll, and `t_death` is the first
  later poll at which s is not alive.
- **Right-censoring:** each of these cases is censored at `t_last_alive − t_flag`, and every
  censored flag is kept:
  - still alive at the series' last pre-commence poll;
  - the gap from `t_last_alive` to the next poll exceeds 120 minutes;
  - the next poll has a NULL `best_bet_ev_percent`.
- **Filters:** none beyond what the poller already applied. `line_is_outlier` rows and every
  value of `num_books_in_consensus` are included. Both distributions are reported.
- **Side columns:** the poller writes `over` to the `home_*` columns and `under` to `away_*`
  (`ev-adaptive-poller/calculator.py:648-657`). So side s ∈ {home, over} reads `home_price`,
  `home_point` and `consensus_home_prob`, and s ∈ {away, under} reads the `away_*`
  equivalents.
- **Death attribution (`died_by`):** compare the poll at `t_death` with the poll at
  `t_last_alive`, always on s's own columns. `best_bet_*` can describe the other side by
  `t_death`, so it is not used here. Exactly one label applies, from these two tests:
  - *consensus moved:* s's consensus probability changed by ≥ 0.1 percentage points, or
    `consensus_line` changed;
  - *book moved:* s's price or s's point changed.

  The label is `consensus` (only the first test holds), `book` (only the second), `both`, or
  `neither`.
- **EV band:** `best_bet_ev_percent` at the flag poll, 0 < EV < 3 vs EV ≥ 3 (whole-number
  percentages).
- **Time-to-kickoff band:** `commence_time − t_flag` ≤ 2h, 2–24h, or > 24h.

## What was already known (stated so it can be checked)

Part 4 of the 2026-11-03 edge audit (`docs/analysis/2026-11-03-edge-and-ledger-audit.md`) used
games from 10-12 to 11-03, which fall inside this window. It found:

- about 60% of first flags still alive at the next poll;
- a median gap to the next poll of 25.6 minutes (p10 5, p90 60).

Taken together, those imply a median lifetime of roughly one to three polls, about 25–75
minutes. **This study is therefore not out-of-sample on next-poll persistence.** Its new
quantities are the full survival curve, the interval treatment, and H2.

## Hypotheses and decision rules

Inference uses a game-clustered bootstrap: 2,000 resamples of games with replacement, seed
20261108, percentile 95% CI. The Kaplan–Meier estimator handles censoring. Each hypothesis
is computed under the primary definition. The secondary definition is reported descriptively.

**H1 (primary).** "Most +EV flags at FanDuel and DraftKings are gone within an hour."
- Metric: the KM median of the interval's upper bound, pooled across all flags.
- Supported if that median's 95% CI upper limit is < 60 minutes.
- Refuted if the 95% CI lower limit of the KM median of the lower bound is > 60 minutes.
- Inconclusive otherwise.
- 60 minutes was chosen because readers think in hours. It was not tuned. As stated above,
  prior knowledge puts the answer near this line.

**H2.** "Flags raised close to kickoff die faster than flags raised a day or more out."
- Groups: flags with time-to-kickoff ≤ 2h ("near") and > 24h ("far").
- Metric: KM median(far) − KM median(near), with a clustered bootstrap CI. It is computed
  separately on the lower bound and the upper bound.
- Supported only if the CI excludes 0 on the positive side for both bounds.
- Refuted if the CI excludes 0 on the negative side for both bounds.
- Inconclusive otherwise, which includes the two bounds disagreeing.
- Why both bounds are required: polling is denser near kickoff, which narrows the interval
  there. A result on only one bound could be an artefact of polling cadence.

## Descriptive outputs (no thresholds, no claims beyond what they show)

- KM survival at 5, 15, 30, 60, 120, 240 and 720 minutes, pooled and broken out by market
  (h2h, spreads, totals), sport, EV band and time-to-kickoff band, on both bounds.
- The share of flags still alive at their series' last pre-commence poll.
- `died_by` shares, pooled and by market.
- The median poll gap by time-to-kickoff band.
- Counts: flags, games, flags excluded as left-truncated, flags censored by reason.

## Fixed in advance

- One set of definitions, as above. No threshold sweeps, and no alternative windows reported
  as results.
- Poll spacing (5–60 minutes) sets the resolution. No statement will be finer than "by the
  next poll".
- Null and negative results are published as they come out.
- A sanity check against Part 4 is allowed: restrict to its window and rules (games 10-12 →
  11-03, first-poll flags kept, last-poll flags dropped) and compare with its 3,115 flags. Any
  difference is reported, never tuned away.

## Publication rules

- Aggregate tables only. No game ids, team names, prices or links in any published file.
- Copy: no picks, no "real-time", no edge or profitability claims. A "flag" is the model's
  output, not a recommendation to bet.

## Proof of order

This file's SHA-256 and the commit that adds it are recorded in RESULTS.md. The repository is
not pushed at registration time, so until the founder publishes this file the timestamp is
**private** (local git only). RESULTS.md says so in plain words.
