# stoic-kal/betting-model architecture

> Architecture diagram of the GitHub repository stoic-kal/betting-model, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-08-12). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/stoic-kal/betting-model
- Repository: https://github.com/stoic-kal/betting-model

## Overview

#### Purpose and entry points
This is an MLB betting-model platform: it ingests baseball/odds data, builds features, trains and promotes moneyline/totals models, generates daily picks, tracks outcomes, and exposes results through a Python web application plus iOS and analytics-dashboard clients. Primary runtime entry points are `app.py`, `run_betting_model.py`, `generate_game_card.py`, and `src/production_runner.py`.

#### Application/API layer
The Python application is organized as a route-and-service system. Route modules present game, pick, result, analytics, diagnostics, and system endpoints; services own business workflows such as pick generation, model control, execution, reporting, and notifications.
- `app.py`
- `web/routes/picks_routes.py`
- `web/routes/game_routes.py`
- `services/pick_service.py`
- `services/execution_service.py`
- `services/model_control_service.py`

#### Data ingestion and feature stores
Historical and live workflows consume local baseball statistics, Statcast-derived tables, retrospective splits, and Vegas odds files. Pipeline ingestion/build stages normalize these sources into versioned game-feature datasets; live features are a boundary between scheduled games/current context and inference.
- `pipeline/retrosplits_ingestion.py`
- `pipeline/vegas_ingestion.py`
- `pipeline/statcast_store.py`
- `pipeline/build_features_v2.py`
- `pipeline/live_features_v2.py`
- `data/games_v2_features_final.csv`

#### Modeling, calibration, and promotion
Separate moneyline and totals training pipelines share common training/calibration machinery. Model artifacts are versioned in a filesystem registry, with `latest.json` pointers, metadata, promotion reports, and validation/audit outputs; this is the deployable-model contract rather than an external model service.
- `pipeline/train_moneyline.py`
- `pipeline/train_totals.py`
- `pipeline/train_experimental_candidates.py`
- `pipeline/model_registry.py`
- `pipeline/retrain.py`
- `models/registry/moneyline/latest.json`
- `models/registry/totals/latest.json`

#### Prediction and betting decisions
Production prediction combines trained artifacts with game context, odds/market signals, and prediction math to produce picks. Supporting services cover portfolios, shadow inference, opposite-model comparison, execution recording, and postgame/loss learning. Daily and historical pick files are durable handoff outputs.
- `src/get_game_predictions_v2.py`
- `services/ml_model_v3.py`
- `services/totals_model_v3.py`
- `services/market_signals_service.py`
- `services/portfolio_risk_service.py`
- `results/daily_picks.csv`

#### Operations, results, and external integrations
The service layer integrates odds feeds, Discord notifications, and Pikkit-related tracking, while scripts poll/fetch odds and import results. Deployment artifacts indicate Docker Compose and macOS `launchd` service operation. No cloud database or queue is evidenced in the tree; CSV/JSONL/JSON files are the visible persistence boundary.
- `services/odds_feed_service.py`
- `services/notifications/engine.py`
- `services/pikkit_service.py`
- `scripts/odds/poll_odds.py`
- `docker-compose.yml`
- `deploy/com.jingleez.flask.plist`

#### User-facing clients and analytics
The server-rendered web UI is under `web/templates`. A native SwiftUI iOS app calls an API client and presents Today, Results, Insights, Alerts, and Account views. `projects/athena` is a separate React/TypeScript/Vite diagnostics frontend with API/stream clients, state stores, and feature pages for calibration, CLV, drift/data health, edge, and prediction analysis.
- `ios/JingleezMobile/JingleezMobile/APIClient.swift`
- `ios/JingleezMobile/JingleezMobile/JingleezMobileApp.swift`
- `projects/athena/src/services/api.ts`
- `projects/athena/src/app/router.tsx`
- `projects/athena/src/features/overview/OverviewPage.tsx`

#### Research and governance boundary
Offline research supports leakage-aware historical replay, calibration/root-cause diagnostics, and reporting. These workflows consume data/model outputs and generate experiment artifacts; they should remain separate from live pick execution.
- `research/historical_replay/cli.py`
- `research/historical_replay/engine.py`
- `research/diagnostics/totals/run_all.py`
- `pipeline/execution_audit.py`
- `reports/execution/complete_execution_audit.json`

Main entry points: [`src/get_game_predictions_v2.py`](https://github.com/stoic-kal/betting-model/blob/main/src/get_game_predictions_v2.py) (Prediction Engine), [`pipeline/model_registry.py`](https://github.com/stoic-kal/betting-model/blob/main/pipeline/model_registry.py) (Filesystem Model Registry), [`data/games_v2_features_final.csv`](https://github.com/stoic-kal/betting-model/blob/main/data/games_v2_features_final.csv) (Versioned Game Features), [`app.py`](https://github.com/stoic-kal/betting-model/blob/main/app.py) (Python Web App)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_app["Application &amp; Clients"]
  node_web_app["Python Web App<br/>Flask application<br/>[app.py]"]
  node_web_routes["Route Modules<br/>HTTP routes<br/>[picks_routes.py]"]
  node_ios_client["iOS Client<br/>SwiftUI client"]
  node_athena["Athena Dashboard<br/>React diagnostics UI<br/>[router.tsx]"]
end

subgraph group_data["Data Pipeline"]
  node_ingestion["Baseball &amp; Odds Ingestion<br/>data ingestion"]
  node_feature_builder["Historical Feature Builder<br/>feature pipeline"]
  node_feature_store[("Versioned Game Features<br/>CSV feature store")]
  node_live_features["Live Features<br/>inference context"]
end

subgraph group_models["Model Lifecycle"]
  node_training["Moneyline &amp; Totals Training<br/>training pipelines<br/>[train_moneyline.py]"]
  node_candidates["Experimental Candidates<br/>candidate training"]
  node_registry[("Filesystem Model Registry<br/>versioned artifacts<br/>[model_registry.py]")]
  node_moneyline_pointer["Moneyline Latest Pointer<br/>model pointer<br/>[latest.json]"]
  node_totals_pointer["Totals Latest Pointer<br/>model pointer<br/>[latest.json]"]
end

subgraph group_production["Production Decisions"]
  node_production_runner["Production Runner<br/>scheduled runtime"]
  node_prediction["Prediction Engine<br/>model inference"]
  node_pick_service["Pick &amp; Portfolio Service<br/>decision workflow<br/>[pick_service.py]"]
  node_daily_picks[("Daily Picks<br/>durable CSV handoff<br/>[daily_picks.csv]")]
  node_integrations["Odds, Notifications &amp; Tracking<br/>external integrations"]
end

subgraph group_research["Research &amp; Governance"]
  node_research_replay["Historical Replay<br/>offline research<br/>[engine.py]"]
  node_execution_audit["Execution Audit<br/>governance audit<br/>[execution_audit.py]"]
end

node_web_app -->|"serves"| node_web_routes
node_ios_client -->|"API calls"| node_web_app
node_athena -->|"API and streams"| node_web_app
node_ingestion -->|"normalized inputs"| node_feature_builder
node_feature_builder -->|"writes"| node_feature_store
node_feature_store -->|"trains on"| node_training
node_feature_store -->|"historical context"| node_live_features
node_training -->|"registers candidates"| node_registry
node_candidates -->|"promotion inputs"| node_registry
node_registry -->|"publishes"| node_moneyline_pointer
node_registry -->|"publishes"| node_totals_pointer
node_production_runner -->|"builds daily context"| node_live_features
node_production_runner -->|"runs"| node_prediction
node_moneyline_pointer -->|"loads model"| node_prediction
node_totals_pointer -->|"loads model"| node_prediction
node_integrations -->|"market odds"| node_prediction
node_live_features -->|"game context"| node_prediction
node_prediction -->|"predictions"| node_pick_service
node_pick_service -->|"writes picks"| node_daily_picks
node_daily_picks -->|"picks and results"| node_web_app
node_pick_service -->|"records and notifies"| node_integrations
node_feature_store -.->|"historical inputs"| node_research_replay
node_registry -.->|"model artifacts"| node_research_replay
node_daily_picks -.->|"execution evidence"| node_execution_audit

click node_web_app "https://github.com/stoic-kal/betting-model/blob/main/app.py"
click node_web_routes "https://github.com/stoic-kal/betting-model/blob/main/web/routes/picks_routes.py"
click node_ios_client "https://github.com/stoic-kal/betting-model/blob/main/ios/JingleezMobile/JingleezMobile/JingleezMobileApp.swift"
click node_athena "https://github.com/stoic-kal/betting-model/blob/main/projects/athena/src/app/router.tsx"
click node_ingestion "https://github.com/stoic-kal/betting-model/blob/main/pipeline/retrosplits_ingestion.py"
click node_feature_builder "https://github.com/stoic-kal/betting-model/blob/main/pipeline/build_features_v2.py"
click node_feature_store "https://github.com/stoic-kal/betting-model/blob/main/data/games_v2_features_final.csv"
click node_live_features "https://github.com/stoic-kal/betting-model/blob/main/pipeline/live_features_v2.py"
click node_training "https://github.com/stoic-kal/betting-model/blob/main/pipeline/train_moneyline.py"
click node_candidates "https://github.com/stoic-kal/betting-model/blob/main/pipeline/train_experimental_candidates.py"
click node_registry "https://github.com/stoic-kal/betting-model/blob/main/pipeline/model_registry.py"
click node_moneyline_pointer "https://github.com/stoic-kal/betting-model/blob/main/models/registry/moneyline/latest.json"
click node_totals_pointer "https://github.com/stoic-kal/betting-model/blob/main/models/registry/totals/latest.json"
click node_production_runner "https://github.com/stoic-kal/betting-model/blob/main/src/production_runner.py"
click node_prediction "https://github.com/stoic-kal/betting-model/blob/main/src/get_game_predictions_v2.py"
click node_pick_service "https://github.com/stoic-kal/betting-model/blob/main/services/pick_service.py"
click node_daily_picks "https://github.com/stoic-kal/betting-model/blob/main/results/daily_picks.csv"
click node_integrations "https://github.com/stoic-kal/betting-model/blob/main/services/odds_feed_service.py"
click node_research_replay "https://github.com/stoic-kal/betting-model/blob/main/research/historical_replay/engine.py"
click node_execution_audit "https://github.com/stoic-kal/betting-model/blob/main/pipeline/execution_audit.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_web_app,node_web_routes,node_ios_client,node_athena toneBlue
class node_ingestion,node_feature_builder,node_feature_store,node_live_features toneAmber
class node_training,node_candidates,node_registry,node_moneyline_pointer,node_totals_pointer toneMint
class node_production_runner,node_prediction,node_pick_service,node_daily_picks,node_integrations toneRose
class node_research_replay,node_execution_audit toneIndigo
```

## Components

### Application & Clients

- [Python Web App](https://github.com/stoic-kal/betting-model/blob/main/app.py): Flask application · Routes expose games, picks, results, analytics, and system APIs. · `app.py`
- [Route Modules](https://github.com/stoic-kal/betting-model/blob/main/web/routes/picks_routes.py): HTTP routes · `web/routes/picks_routes.py`
- [iOS Client](https://github.com/stoic-kal/betting-model/blob/main/ios/JingleezMobile/JingleezMobile/JingleezMobileApp.swift): SwiftUI client · `ios/JingleezMobile/JingleezMobile/JingleezMobileApp.swift`
- [Athena Dashboard](https://github.com/stoic-kal/betting-model/blob/main/projects/athena/src/app/router.tsx): React diagnostics UI · `projects/athena/src/app/router.tsx`

### Data Pipeline

- [Baseball & Odds Ingestion](https://github.com/stoic-kal/betting-model/blob/main/pipeline/retrosplits_ingestion.py): data ingestion · Normalizes local baseball, Statcast, retrosplits, and Vegas inputs. · `pipeline/retrosplits_ingestion.py`
- [Historical Feature Builder](https://github.com/stoic-kal/betting-model/blob/main/pipeline/build_features_v2.py): feature pipeline · `pipeline/build_features_v2.py`
- [Versioned Game Features](https://github.com/stoic-kal/betting-model/blob/main/data/games_v2_features_final.csv): CSV feature store · `data/games_v2_features_final.csv`
- [Live Features](https://github.com/stoic-kal/betting-model/blob/main/pipeline/live_features_v2.py): inference context · Combines scheduled-game context for current inference. · `pipeline/live_features_v2.py`

### Model Lifecycle

- [Moneyline & Totals Training](https://github.com/stoic-kal/betting-model/blob/main/pipeline/train_moneyline.py): training pipelines · Separate targets share training and calibration machinery. · `pipeline/train_moneyline.py`
- [Experimental Candidates](https://github.com/stoic-kal/betting-model/blob/main/pipeline/train_experimental_candidates.py): candidate training · `pipeline/train_experimental_candidates.py`
- [Filesystem Model Registry](https://github.com/stoic-kal/betting-model/blob/main/pipeline/model_registry.py): versioned artifacts · Promotion metadata, reports, validation outputs, and latest pointers form the deployable contract. · `pipeline/model_registry.py`
- [Moneyline Latest Pointer](https://github.com/stoic-kal/betting-model/blob/main/models/registry/moneyline/latest.json): model pointer · `models/registry/moneyline/latest.json`
- [Totals Latest Pointer](https://github.com/stoic-kal/betting-model/blob/main/models/registry/totals/latest.json): model pointer · `models/registry/totals/latest.json`

### Production Decisions

- [Production Runner](https://github.com/stoic-kal/betting-model/blob/main/src/production_runner.py): scheduled runtime · Coordinates daily production workflows. · `src/production_runner.py`
- [Prediction Engine](https://github.com/stoic-kal/betting-model/blob/main/src/get_game_predictions_v2.py): model inference · Combines deployed artifacts, game context, odds, and prediction math. · `src/get_game_predictions_v2.py`
- [Pick & Portfolio Service](https://github.com/stoic-kal/betting-model/blob/main/services/pick_service.py): decision workflow · Generates picks and applies portfolio risk controls. · `services/pick_service.py`
- [Daily Picks](https://github.com/stoic-kal/betting-model/blob/main/results/daily_picks.csv): durable CSV handoff · `results/daily_picks.csv`
- [Odds, Notifications & Tracking](https://github.com/stoic-kal/betting-model/blob/main/services/odds_feed_service.py): external integrations · Connects odds feeds, Discord notifications, and Pikkit tracking. · `services/odds_feed_service.py`

### Research & Governance

- [Historical Replay](https://github.com/stoic-kal/betting-model/blob/main/research/historical_replay/engine.py): offline research · Leakage-aware replay remains separate from live execution. · `research/historical_replay/engine.py`
- [Execution Audit](https://github.com/stoic-kal/betting-model/blob/main/pipeline/execution_audit.py): governance audit · `pipeline/execution_audit.py`

## Connections

- Python Web App → Route Modules: serves
- iOS Client → Python Web App: API calls
- Athena Dashboard → Python Web App: API and streams
- Baseball & Odds Ingestion → Historical Feature Builder: normalized inputs
- Historical Feature Builder → Versioned Game Features: writes
- Versioned Game Features → Moneyline & Totals Training: trains on
- Versioned Game Features → Live Features: historical context
- Moneyline & Totals Training → Filesystem Model Registry: registers candidates
- Experimental Candidates → Filesystem Model Registry: promotion inputs
- Filesystem Model Registry → Moneyline Latest Pointer: publishes
- Filesystem Model Registry → Totals Latest Pointer: publishes
- Production Runner → Live Features: builds daily context
- Production Runner → Prediction Engine: runs
- Moneyline Latest Pointer → Prediction Engine: loads model
- Totals Latest Pointer → Prediction Engine: loads model
- Odds, Notifications & Tracking → Prediction Engine: market odds
- Live Features → Prediction Engine: game context
- Prediction Engine → Pick & Portfolio Service: predictions
- Pick & Portfolio Service → Daily Picks: writes picks
- Daily Picks → Python Web App: picks and results
- Pick & Portfolio Service → Odds, Notifications & Tracking: records and notifies
- Versioned Game Features → Historical Replay: historical inputs
- Filesystem Model Registry → Historical Replay: model artifacts
- Daily Picks → Execution Audit: execution evidence
