-
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-1Phase 1: Core AnalyticsPhase 1: Core Analytics
Description
name: "Phase 1: Line Movement Tracking"
about: Detect and classify line movements (steam moves, reverse line movement, etc.)
title: "[Phase 1] Line Movement Tracking"
labels: enhancement, phase-1, analytics
assignees: ''
Overview
Track how betting lines move over time and classify movements to identify "steam moves" (sharp money) and "reverse line movement" (line moves against public betting).
Business Value
- Sharp Money Detection: Identify when professional bettors are betting
- Value Timing: Know when to place bets for best value
- Market Sentiment: Understand what the market is saying
- Historical Analysis: Track your success betting with/against line moves
Technical Requirements
Database Changes
// Enhanced OddsSnapshot
model OddsSnapshot {
// ... existing fields
capturedAt DateTime
// NEW: Movement detection
movementType String? @map("movement_type") @db.VarChar(20)
movementSize Decimal? @map("movement_size") @db.Decimal(5,2)
volumeIndicator Int? @map("volume_indicator") // 1-10 scale
@@index([capturedAt])
@@index([movementType])
}
// New table: Line Movement Events
model LineMovement {
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)
// Movement characteristics
movementType String @map("movement_type") @db.VarChar(20)
linesBefore Json @map("lines_before")
linesAfter Json @map("lines_after")
// Analysis
bookmakerCount Int @map("bookmaker_count")
averageMovement Decimal @map("average_movement") @db.Decimal(5,2)
timeToMove Int @map("time_to_move") // seconds
suspectedCause String? @map("suspected_cause") @db.VarChar(100)
game Game @relation(fields: [gameId], references: [id])
@@index([gameId])
@@index([movementType])
@@index([detectedAt])
@@map("line_movements")
}Backend Services
File: src/services/line-movement.service.ts
class LineMovementService {
async detectMovement(gameId: string): Promise<Movement[]>
async classifyMovement(movement: Movement): Promise<MovementType>
async trackSteamMove(gameId: string): Promise<boolean>
async findReverseLineMovement(gameId: string): Promise<boolean>
async getRecentMoves(filters): Promise<LineMovement[]>
}Real-time Detection: Compare odds snapshots every 5 minutes
- Query last 2 snapshots for each game
- Calculate movement for each bookmaker
- Detect patterns across bookmakers
- Classify movement type
Movement Classification
Steam Move (Sharp Money):
- 3+ major books move simultaneously (within 2 minutes)
- Movement of 1.5+ points on spreads/totals
- Movement of 15+ cents on moneylines
- Same direction across all books
- Indicator: Sharp/professional money
Reverse Line Movement:
- Line moves opposite to public betting percentages
- Example: Public betting 70% on favorite, line moves toward underdog
- Indicator: Sharp money on less popular side
Gradual Drift:
- Line moves slowly over hours/days
- Small incremental changes
- Indicator: Balanced public action
Injury/News Move:
- Sudden, large movement
- Triggered by news event
- Books may suspend betting temporarily
- Indicator: Information-based adjustment
Detection Algorithm
function classifyMovement(before: Odds[], after: Odds[]): MovementType {
// Calculate changes
const changes = after.map((odds, i) => odds - before[i]);
const avgChange = mean(changes);
const timeElapsed = after.timestamp - before.timestamp;
const bookCount = changes.filter(c => abs(c) > threshold).length;
// Steam move criteria
if (bookCount >= 3 &&
timeElapsed < 120 &&
abs(avgChange) >= 1.5) {
return 'steam';
}
// Reverse line movement (requires public betting data)
if (publicBettingPct > 65 && avgChange < 0) {
return 'reverse';
}
// Gradual drift
if (timeElapsed > 3600 && abs(avgChange) < 1.0) {
return 'gradual';
}
return 'normal';
}API Endpoints
GET /api/analytics/movements/live- Steam moves in last 2 hoursGET /api/analytics/movements/game/:gameId- All movements for gameGET /api/analytics/movements/history- Historical movement analysisGET /api/analytics/movements/bookmaker/:bookmaker- Which book moves firstGET /api/analytics/movements/performance- Win rate when betting with/against moves
Frontend Components
Dashboard Alert: SteamMoveAlert.tsx
- Real-time banner for steam moves
- Shows game, moved line, direction
- "Bet Now" CTA
- Dismiss to remove from view
Movement Timeline: LineMovementChart.tsx
- Line chart showing line over time
- Annotate with movement events
- Color-code by movement type
- Show bookmaker-specific lines
Historical Performance: MovementPerformance.tsx
- Win rate when betting with steam moves
- Win rate when betting against public
- ROI by movement type
- Sample size and confidence intervals
Notifications
Push Alerts (when user opts in):
- Steam move detected on followed games/teams
- Reverse line movement on followed games
- Significant line swing (>3 points)
Alert Preferences:
- Minimum movement size
- Sports to monitor
- Time before game (e.g., only alert if >2 hours to game)
Acceptance Criteria
- Database migration completed
- Line movement detection running every 5 minutes
- Movement classification algorithm tested
- Dashboard alerts for steam moves
- Historical movement data visualization
- API endpoints documented
- Unit tests for classification logic
- Performance metrics tracked (win rate with moves)
Dependencies
- Odds sync must run frequently (every 5-10 minutes)
- Multiple bookmakers required for reliable detection
- Historical odds data for baseline comparison
Estimated Effort
- Backend: 5 days
- Frontend: 3 days
- Testing & Tuning: 2 days
- Total: 10 days
Success Metrics
- Detect 5-10 steam moves per day
- 95% classification accuracy (manual validation)
- Alerts delivered within 60 seconds of detection
- Users report steam moves are valuable (survey)
- Positive win rate correlation with steam moves
Future Enhancements
- Public betting percentage integration (from external source)
- Machine learning for movement prediction
- Bookmaker "sharpness" ranking (who moves first)
- Player prop line movement tracking
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
analyticsAdvanced analytics featuresAdvanced analytics featuresenhancementNew feature or requestNew feature or requestphase-1Phase 1: Core AnalyticsPhase 1: Core Analytics