-- GRADE CORRELATION PROOF (2026-07-31). Re-runnable evidence for
-- specs/grade-fix-part1-investigation.md. LOOKAHEAD GUARD: fair_prob_lock is the
-- LOCK-TIME market probability; closing_prob (the close) is deliberately unused.

-- 1) Candidate edge formulations vs outcome, per sport.
with r as (
  select sport, (outcome='hit')::int as won, p_win::numeric as p, fair_prob_lock::numeric as f,
         case grade when 'A+' then 10 when 'A' then 9 when 'A-' then 8 when 'B+' then 7 when 'B' then 6
                    when 'B-' then 5 when 'C+' then 4 when 'C' then 3 when 'C-' then 2 when 'D' then 1 else 0 end as champ_idx
  from ledger_entries
  where user_id is null and outcome in ('hit','miss')
    and p_win is not null and fair_prob_lock is not null and grade is not null
)
select sport, count(*) n,
  corr(champ_idx, won) champ_letter_r,
  corr(p, won)         p_win_alone_r,
  corr(p - f, won)     additive_edge_r,
  corr(p / nullif(f,0), won) ratio_edge_r,
  corr(ln(p/(1-p)) - ln(f/(1-f)), won) logodds_edge_r
from r group by sport;

-- 2) Time-forward split (overfitting guard), MLB.
with r as (
  select game_date, (outcome='hit')::int as won, p_win::numeric as p, fair_prob_lock::numeric as f
  from ledger_entries
  where user_id is null and outcome in ('hit','miss') and sport='mlb'
    and p_win is not null and fair_prob_lock is not null
), s as (select *, ntile(2) over (order by game_date) half from r)
select half, count(*) n, min(game_date) from_date, max(game_date) to_date,
       corr(p, won) p_win_alone_r, corr(p - f, won) additive_edge_r
from s group by half order by half;
