-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
analyticsAdvanced analytics featuresAdvanced analytics featuresenhancementNew feature or requestNew feature or requestphase-2Phase 2: Market IntelligencePhase 2: Market Intelligence
Description
name: "Phase 2: Bookmaker Performance Analytics"
about: Track and rank bookmakers by value offered, market-making behavior, and reliability
title: "[Phase 2] Bookmaker Performance Analytics"
labels: enhancement, phase-2, analytics
assignees: ''
Overview
Comprehensive analytics on bookmaker performance: which books offer best value, move lines first (sharp), have best limits, and provide most reliable odds.
Business Value
- Bookmaker Selection: Help users choose which books to use
- Sharp Book Identification: Know which books set the market
- Value Optimization: Always get best available odds
- Market Intelligence: Understand bookmaker strategies
Technical Requirements
Database Changes
model BookmakerAnalytics {
id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
bookmaker String @unique @db.VarChar(50)
// Odds quality metrics
averageCLVOffered Decimal @map("average_clv_offered") @db.Decimal(5,2)
bestOddsFrequency Decimal @map("best_odds_frequency") @db.Decimal(5,2)
marginVsConsensus Decimal @map("margin_vs_consensus") @db.Decimal(5,2)
outlierFrequency Decimal @map("outlier_frequency") @db.Decimal(5,2)
// Market making behavior
firstMoverFrequency Decimal @map("first_mover_frequency") @db.Decimal(5,2)
lineMovementLag Int @map("line_movement_lag") // Average seconds behind market
sharpBookRating Int @map("sharp_book_rating") // 1-10
marketEfficiency Decimal @map("market_efficiency") @db.Decimal(5,2)
// Coverage & reliability
sportsCovered String[] @map("sports_covered")
marketsCovered String[] @map("markets_covered")
uptimePercentage Decimal @map("uptime_percentage") @db.Decimal(5,2)
oddsUpdateFrequency Int @map("odds_update_frequency") // Seconds
averageOddsAge Int @map("average_odds_age") // Seconds since last update
// Limits & accessibility
limitProfile String @map("limit_profile") @db.VarChar(20) // high/medium/low
estimatedMaxBet Decimal? @map("estimated_max_bet") @db.Decimal(10,2)
accountLimitReports Int @map("account_limit_reports") // User reports of being limited
// Historical performance
totalGamesOffered Int @map("total_games_offered")
totalMarketsOffered Int @map("total_markets_offered")
averageMargin Decimal @map("average_margin") @db.Decimal(5,2)
// Reputation
userRating Decimal? @map("user_rating") @db.Decimal(3,2)
userReviewCount Int @default(0) @map("user_review_count")
recommendationScore Int @map("recommendation_score") // 1-100
// Metadata
calculatedAt DateTime @default(now()) @map("calculated_at") @db.Timestamptz(6)
updatedAt DateTime @default(now()) @updatedAt @map("updated_at") @db.Timestamptz(6)
@@index([bestOddsFrequency])
@@index([sharpBookRating])
@@map("bookmaker_analytics")
}
// Bookmaker movement events (track who moves first)
model BookmakerMovementEvent {
id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
gameId String @map("game_id") @db.Uuid
marketType String @map("market_type") @db.VarChar(20)
detectedAt DateTime @default(now()) @map("detected_at") @db.Timestamptz(6)
firstMover String @map("first_mover") @db.VarChar(50)
firstMoveTime DateTime @map("first_move_time") @db.Timestamptz(6)
followers Json // [{bookmaker, lagSeconds}]
movementSize Decimal @map("movement_size") @db.Decimal(5,2)
game Game @relation(fields: [gameId], references: [id])
@@index([firstMover])
@@index([detectedAt])
@@map("bookmaker_movement_events")
}Backend Services
File: src/services/bookmaker-analytics.service.ts
class BookmakerAnalyticsService {
async calculateBookmakerMetrics(bookmaker: string): Promise<Analytics>
async rankBookmakers(criteria: string): Promise<Ranking[]>
async identifySharpBooks(): Promise<string[]>
async trackLineMovement(bookmaker: string): Promise<MovementStats>
async generateBookmakerReport(): Promise<Report>
}Metrics Calculations
Best Odds Frequency:
// % of time bookmaker has best odds vs all others
function calculateBestOddsFrequency(bookmaker: string, period: string): number {
const totalGames = getGamesWithOdds(bookmaker, period);
const bestOddsCount = totalGames.filter(game =>
hasBestOdds(game, bookmaker)
).length;
return (bestOddsCount / totalGames.length) * 100;
}Sharp Book Rating:
function calculateSharpBookRating(bookmaker: string): number {
const metrics = {
firstMoverFrequency: getFirstMoverFrequency(bookmaker), // Weight: 35%
marginVsConsensus: getMarginVsConsensus(bookmaker), // Weight: 25%
limits: getLimitProfile(bookmaker), // Weight: 20%
efficiency: getMarketEfficiency(bookmaker), // Weight: 20%
};
const score =
(metrics.firstMoverFrequency * 0.35) +
((100 - metrics.marginVsConsensus) * 0.25) +
(metrics.limits * 0.20) +
(metrics.efficiency * 0.20);
return Math.round(score / 10); // Scale to 1-10
}Average CLV Offered:
// Average CLV users get when betting at this bookmaker
function calculateAverageCLVOffered(bookmaker: string): number {
const bets = getBetsPlacedAt(bookmaker);
const clvValues = bets.map(bet => bet.clv);
return mean(clvValues);
}Scheduled Jobs
Daily Analytics Update: Runs at 2 AM
- Calculate all metrics for each bookmaker
- Update bookmaker_analytics table
- Generate rankings
- Send alerts for significant changes
Real-time Movement Tracking: Runs every 5 minutes
- Identify line movements
- Track who moved first
- Update movement event records
- Increment first-mover counts
API Endpoints
GET /api/bookmakers- List all bookmakers with basic statsGET /api/bookmakers/:bookmaker- Detailed analytics for one bookmakerGET /api/bookmakers/rankings/:criteria- Rankings by specific metricGET /api/bookmakers/sharp- List of sharp booksGET /api/bookmakers/best-value/:sport- Best value bookmakers by sportGET /api/bookmakers/movement/:bookmaker- Line movement statsGET /api/bookmakers/compare- Compare multiple bookmakers side-by-side
Frontend Components
Bookmaker Leaderboard: BookmakerLeaderboard.tsx
┌────────────────────────────────────────────────┐
│ 🏆 Bookmaker Rankings │
├────────────────────────────────────────────────┤
│ 1. Pinnacle Sharp: 9/10 Value: 92% │
│ 2. Circa Sports Sharp: 8/10 Value: 88% │
│ 3. BetCRIS Sharp: 7/10 Value: 85% │
│ 4. DraftKings Sharp: 5/10 Value: 76% │
│ 5. FanDuel Sharp: 5/10 Value: 74% │
└────────────────────────────────────────────────┘
Bookmaker Profile: BookmakerProfile.tsx
- Full analytics dashboard for single bookmaker
- Radar chart: Sharp rating, value, coverage, reliability
- Line chart: Metrics over time
- Best sports/markets for this book
- User reviews and ratings
Comparison Tool: BookmakerComparison.tsx
- Side-by-side comparison of 2-4 bookmakers
- Highlight advantages/disadvantages
- Sport-specific comparisons
- Recommendation engine
Sharp Book Identifier: SharpBookBadge.tsx
- Visual badge on game cards
- Shows which books are sharp for that game/market
- Quick reference for users
- Click to see detailed analysis
Visualizations
Sharp Book Network Graph:
- Nodes = Bookmakers
- Edges = Line movement following
- Size = Influence
- Color = Sharp rating
Value Heatmap:
- Rows = Bookmakers
- Columns = Sports
- Color = Best odds frequency
- Helps identify which book for which sport
Acceptance Criteria
- Database migration completed
- Metrics calculation service implemented
- Daily analytics update job
- Real-time movement tracking
- Bookmaker leaderboard page
- Detailed bookmaker profiles
- Comparison tool
- API endpoints documented
- Unit tests for all calculations
- Historical data validation (manual review)
Dependencies
- Odds sync with multiple bookmakers
- Line movement tracking (Phase 1)
- Market consensus (Phase 2)
- Historical game results
Estimated Effort
- Backend: 7 days
- Frontend: 5 days
- Testing & Validation: 3 days
- Total: 15 days
Success Metrics
- Analytics calculated for 100% of active bookmakers
- Sharp book identification accuracy >85% (expert validation)
- Users consult rankings when choosing books
- Positive correlation between bookmaker rating and user satisfaction
Future Enhancements
- User-submitted limit reports
- Bookmaker account health scoring
- Payout speed tracking
- Customer service ratings
- Promo/bonus value analysis
- Machine learning for sharp book prediction
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
analyticsAdvanced analytics featuresAdvanced analytics featuresenhancementNew feature or requestNew feature or requestphase-2Phase 2: Market IntelligencePhase 2: Market Intelligence