brackt/drizzle/meta/_journal.json
Chris Parsons 79ec477a98 feat: implement Expected Value System with ICM probability calculator
Implements Phase 5.2 of the EV system with Harville-Malmuth Independent Chip Model
for calculating participant placement probabilities from futures odds.

## Key Features

### ICM Probability Calculator
- Implements Harville-Malmuth method for distributing probabilities
- Converts American odds to championship probabilities
- Generates P(1st) through P(8th) for all participants
- Column-normalized: each placement sums to 100% across all teams
- Works with any number of participants (not limited to 8)

### Admin UI - Futures Odds Entry
- Enter American odds (e.g., +550, -200) for championship futures
- Live preview of ICM-calculated probability distributions
- Displays all 8 placement probabilities
- Persists odds for editing on subsequent visits
- Automatic probability normalization (removes bookmaker vig)

### Database Schema Updates
- Renamed participant_expected_values.season_id → sports_season_id
- Updated foreign key to reference sports_seasons instead of seasons
- Added source_odds field to store original futures odds
- Migration 0025: Column rename and FK update
- Migration 0026: Add source_odds field

### Model Layer
- participant-expected-value: CRUD operations for probability distributions
- Supports multiple probability sources (manual, futures_odds, elo_simulation)
- Automatic EV calculation based on league scoring rules
- Probability validation and normalization

### Service Layer
- icm-calculator: Harville-Malmuth probability distribution
- probability-engine: Odds conversion and Elo utilities (for future use)
- bracket-simulator: Monte Carlo simulation (for future hybrid approach)
- ev-calculator: Expected value computation from probabilities

## Technical Details

- Uses exponential decay favoring top positions for strong teams
- Preserves championship probability ordering in final distributions
- Row sums vary (strong teams ~100%, weak teams lower)
- All probabilities between 0-1, mathematically valid
- Comprehensive test suite: 97 tests passing

## Future Enhancements

- Hybrid approach: ICM pre-playoffs, bracket simulation during playoffs
- Integration with league-specific scoring rules
- Historical probability tracking for accuracy analysis

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 22:19:46 -08:00

195 lines
No EOL
3.9 KiB
JSON

{
"version": "7",
"dialect": "postgresql",
"entries": [
{
"idx": 0,
"version": "7",
"when": 1732076135211,
"tag": "0000_short_donald_blake",
"breakpoints": true
},
{
"idx": 1,
"version": "7",
"when": 1760165302772,
"tag": "0001_serious_la_nuit",
"breakpoints": true
},
{
"idx": 2,
"version": "7",
"when": 1760166775427,
"tag": "0002_tired_iron_man",
"breakpoints": true
},
{
"idx": 3,
"version": "7",
"when": 1760167848365,
"tag": "0003_public_shadowcat",
"breakpoints": true
},
{
"idx": 4,
"version": "7",
"when": 1760168383812,
"tag": "0004_spicy_zarda",
"breakpoints": true
},
{
"idx": 5,
"version": "7",
"when": 1760169537260,
"tag": "0005_abnormal_thunderbird",
"breakpoints": true
},
{
"idx": 6,
"version": "7",
"when": 1760241924414,
"tag": "0006_needy_junta",
"breakpoints": true
},
{
"idx": 7,
"version": "7",
"when": 1760327817376,
"tag": "0007_pink_nebula",
"breakpoints": true
},
{
"idx": 8,
"version": "7",
"when": 1760375514773,
"tag": "0008_salty_trauma",
"breakpoints": true
},
{
"idx": 9,
"version": "7",
"when": 1760392647508,
"tag": "0009_fuzzy_korvac",
"breakpoints": true
},
{
"idx": 10,
"version": "7",
"when": 1760469105799,
"tag": "0010_complex_the_stranger",
"breakpoints": true
},
{
"idx": 11,
"version": "7",
"when": 1760501621605,
"tag": "0011_gifted_mystique",
"breakpoints": true
},
{
"idx": 12,
"version": "7",
"when": 1760504208398,
"tag": "0012_yielding_phil_sheldon",
"breakpoints": true
},
{
"idx": 13,
"version": "7",
"when": 1760543654915,
"tag": "0013_pink_the_order",
"breakpoints": true
},
{
"idx": 14,
"version": "7",
"when": 1760588333462,
"tag": "0014_lowly_gateway",
"breakpoints": true
},
{
"idx": 15,
"version": "7",
"when": 1760589195551,
"tag": "0015_exotic_loners",
"breakpoints": true
},
{
"idx": 16,
"version": "7",
"when": 1760590495868,
"tag": "0016_majestic_roulette",
"breakpoints": true
},
{
"idx": 17,
"version": "7",
"when": 1760599350154,
"tag": "0017_calm_zarda",
"breakpoints": true
},
{
"idx": 18,
"version": "7",
"when": 1760996053371,
"tag": "0018_numerous_stardust",
"breakpoints": true
},
{
"idx": 19,
"version": "7",
"when": 1761112236540,
"tag": "0019_acoustic_ben_grimm",
"breakpoints": true
},
{
"idx": 20,
"version": "7",
"when": 1761719248881,
"tag": "0020_slim_spacker_dave",
"breakpoints": true
},
{
"idx": 21,
"version": "7",
"when": 1762190473418,
"tag": "0021_fair_ser_duncan",
"breakpoints": true
},
{
"idx": 22,
"version": "7",
"when": 1762191156317,
"tag": "0022_shiny_mother_askani",
"breakpoints": true
},
{
"idx": 23,
"version": "7",
"when": 1762200550705,
"tag": "0023_cynical_jack_power",
"breakpoints": true
},
{
"idx": 24,
"version": "7",
"when": 1763276901482,
"tag": "0024_faithful_mesmero",
"breakpoints": true
},
{
"idx": 25,
"version": "7",
"when": 1763277000000,
"tag": "0025_rename_participant_ev_season_to_sports_season",
"breakpoints": true
},
{
"idx": 26,
"version": "7",
"when": 1763278000000,
"tag": "0026_add_source_odds_to_participant_ev",
"breakpoints": true
}
]
}