Skip to content

Add advanced signal tracking and injury/matchup context to backtest engine#39

Merged
GodingWal merged 1 commit intomainfrom
claude/add-backtest-signals-h4QeN
Feb 5, 2026
Merged

Add advanced signal tracking and injury/matchup context to backtest engine#39
GodingWal merged 1 commit intomainfrom
claude/add-backtest-signals-h4QeN

Conversation

@GodingWal
Copy link
Copy Markdown
Owner

Summary

This PR enhances the backtest engine with new signal types and improved context building by adding injury tracking, matchup history extraction, defender matchup detection, and CLV tracking capabilities.

Key Changes

Frontend (client/src/pages/backtest.tsx)

  • Added 6 new signal display configurations:
    • clv_tracker: Closing line value tracking (purple)
    • defender_matchup: Primary defender impact (teal)
    • matchup_history: Head-to-head performance (orange)
    • line_movement: Sharp money detection (cyan)
    • fatigue: Schedule & travel load (red)
    • referee: Referee tendency adjustment (pink)

Backend (server/nba-prop-model/src/evaluation/backtest_engine.py)

  • Data Loading: Added two new data loaders:

    • _load_injuries(): Loads injury history from database to track OUT/doubtful players by team and date
    • _load_team_rosters(): Loads player rosters with positions for defender matching
  • Context Building: Enhanced _build_context() with new features:

    • Injury alpha: Identifies injured teammates affecting player opportunity
    • Matchup history: Extracts head-to-head game history vs specific opponents
    • CLV tracking: Computes model direction (OVER/UNDER) by comparing baseline to line
    • Blowout risk: Estimates game spread from team defensive ratings
    • Defender matchup: Identifies primary defender on opponent team
  • Helper Methods:

    • _find_injured_teammates(): Locates injured players on a team for a given date
    • _find_primary_defender(): Matches player position with known elite/weak defenders
    • _estimate_spread(): Calculates estimated spread using defensive rating differential
    • _extract_vs_team_history(): Parses recent_games JSONB to find head-to-head matchups
  • Improved B2B Detection: Enhanced _detect_b2b() with fallback logic:

    • Primary: Database query for games on previous day
    • Fallback: Checks recent_games JSONB data if DB unavailable

Implementation Details

  • Injury and roster data are cached in memory during initialization for performance
  • Context building gracefully handles missing data and falls back to heuristics
  • Defender matching uses position categories (G/F/C) for flexible matching
  • Spread estimation incorporates home court advantage (~3 points)
  • All new methods include error handling and logging for debugging

https://claude.ai/code/session_01RXgC7zzvzoDMkf7nJjecaR

Six signals were showing N/A in the backtest accuracy report because
the backtest context builder wasn't providing the data they needed:

- Injury Alpha: now loads injury_history to find OUT teammates per game
- Back-to-Back: added recent_games JSONB fallback for B2B detection
- Blowout Risk: estimates spread from team defensive rating differentials
- Matchup History: extracts vs-opponent games from recent_games JSONB
- CLV Tracker: computes model_direction from season baseline vs line
- Defender Matchup: heuristic matching known elite/weak defenders by position

Also adds all v2 signals (clv_tracker, defender_matchup, matchup_history,
line_movement, fatigue, referee) to the frontend SIGNAL_DISPLAY config
so they render with proper labels, descriptions, and chart colors.

https://claude.ai/code/session_01RXgC7zzvzoDMkf7nJjecaR
@GodingWal GodingWal merged commit 595b3be into main Feb 5, 2026
3 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants