Web Application for Optimal Shot Distribution Analysis
Research under Professor Hesam Oveys (NYU)
Interactive web application that applies probabilistic methods from financial mathematics to basketball analytics. Users can select NBA matchups, adjust shot strategies interactively, and run Monte Carlo simulations to find optimal 2PT/3PT ratios.
Local Development:
# Clone repository
git clone <repo-url>
cd predicrionai
# Build and run
docker compose up --build
# Open browser
open http://localhost:8000
Production Deployment (with Traefik + Let's Encrypt):
# Setup environment
cp .env.example .env
nano .env # Add CF_API_EMAIL, CF_API_KEY, DOMAIN
# Launch all services
docker compose up -d --build
# Access:
# https://monte.kz-saas.com → Web App
# https://jupyter.monte.kz-saas.com → Jupyter
# https://research.monte.kz-saas.com → Research Paper
# https://traefik.monte.kz-saas.com → Traefik Dashboard
See docs/TRAEFIK_SETUP_RU.md for detailed production setup instructions.
# Backend
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
uvicorn webapp.main:app --reload
# Frontend (in another terminal)
cd frontend
npm install
npm run dev
# Open http://localhost:5173 (dev) or http://localhost:8000 (production)
# Get all teams
GET /api/teams
# Get team profile
GET /api/teams/{team_id}
# List matches (mode: synthetic | history | upcoming)
GET /api/matches?mode=history&count=20
# Run simulation
POST /api/simulate
{
"home_team_id": 1610612747,
"away_team_id": 1610612744,
"home_three_ratio": 0.38,
"away_three_ratio": 0.42,
"home_fg3_pct": 0.36,
"away_fg3_pct": 0.38,
"hot_hand": false,
"iterations": 5000
}
# Analyze optimal strategy
GET /api/analysis/{team_id}?opponent_id={opp_id}&iterations=1500
predicrionai/
├── webapp/ # FastAPI backend
│ ├── main.py # App entry point (+ cache warm-up on startup)
│ ├── api.py # REST routes
│ ├── schemas.py # Pydantic models (API contracts)
│ ├── services.py # Business logic (simulation orchestration)
│ ├── providers.py # Data sources: ESPN (primary) → nba_api → synthetic
│ ├── cache.py # Redis match cache (in-memory fallback)
│ └── static/ # Built frontend (from Vite)
├── frontend/ # React + Vite
│ ├── src/
│ │ ├── App.jsx
│ │ ├── pages/ # MatchSelect, Analysis
│ │ ├── components/ # TeamCard, StrategyPanel, Charts
│ │ ├── api.js # Fetch wrapper
│ │ └── styles.css # Design tokens
│ └── vite.config.js
├── src/ # Core simulation engine
│ ├── simulation/ # Monte Carlo, ShotModel, GameSimulator
│ ├── analysis/ # FourFactors, HotHand, Statistics
│ ├── data/ # NBAClient (with TLS bypass)
│ └── utils/ # Config, Logger
├── tests/ # Pytest (34 tests, 100% pass)
├── notebooks/ # Jupyter analysis notebooks
└── paper/ # Research paper
# Run all tests
pytest tests/ -v
# With coverage
pytest tests/ --cov=src --cov=webapp --cov-report=html
# Test API manually
curl http://localhost:8000/api/health
curl http://localhost:8000/api/teams
(FGM + 0.5 × 3PM) / FGATOV / (FGA + 0.44 × FTA + TOV)ORB / (ORB + Opp DRB)FTA / FGA| Component | Technology | Version |
|---|---|---|
| Backend | FastAPI + Uvicorn | 0.115+ |
| Frontend | React + Vite | 18 / 5 |
| Charts | Chart.js | 4.5 |
| Data | ESPN API (primary) + nba_api (fallback) + synthetic | — |
| Cache | Redis (in-memory fallback) | 7.x |
| Simulation | NumPy + SciPy | 1.24+ |
| Container | Docker + Docker Compose | — |
Environment variables (optional):
NBA_API_RATE_LIMIT=0.6 # Delay between NBA API calls (seconds)
LOG_LEVEL=INFO # Logging level
REDIS_URL=redis://redis:6379/0 # Redis connection (auto-set by docker-compose)
MATCH_CACHE_TTL_SECONDS=43200 # Match cache TTL (default 12 hours)
SIM_ITERATIONS=10000 # Default simulation iterations
HOT_HAND_WINDOW=5 # Consecutive makes to trigger hot hand
paper/research_paper.md — Full academic papernotebooks/01_monte_carlo_simulation.ipynb — Interactive analysisdocs/specs/web-app-spec.md — Technical specification# Format code
black src/ webapp/ tests/
# Lint
flake8 src/ webapp/ tests/
# Type check
mypy webapp/
# Run tests before committing
pytest tests/
MIT License — see LICENSE file
This project was developed as part of a research concentration under Professor Hesam Oveys at NYU, exploring the application of financial mathematics (random walk theory, Monte Carlo methods, portfolio optimization) to sports analytics.
Core Question: How should an NBA team optimally distribute 2-point vs 3-point shots to maximize expected points while managing variance?
Answer: At NBA-average shooting (52% 2PT, 36% 3PT), optimal strategy is approximately 45-50% three-point attempts. However, the optimal ratio depends on: - Team shooting ability (better 3PT shooters should shoot more 3s) - Risk tolerance (trailing teams should increase variance with more 3PT) - Opponent strategy (defensive adjustments not modeled)
The web application makes this research interactive and accessible.