Все необходимое для установки, настройки и использования NBA Shot Strategy приложения.
Интерактивное веб-приложение, применяющее вероятностные методы финансовой математики к баскетбольной аналитике. Позволяет выбирать матчи NBA, настраивать стратегии бросков и запускать симуляции Монте-Карло для поиска оптимального соотношения 2-очковых/3-очковых бросков.
cd /opt/predicrionai
docker compose up --build
# Откройте http://localhost:8000
# Настройте .env
cp .env.example .env
nano .env # Добавьте CF_API_EMAIL, CF_API_KEY, DOMAIN
# Запустите
docker compose up -d --build
# Доступ:
# https://monte.kz-saas.com → Web App
# https://jupyter.monte.kz-saas.com → Jupyter
# https://research.monte.kz-saas.com → Статья
# https://traefik.monte.kz-saas.com → Dashboard
# Клонируйте репозиторий
git clone <repo-url>
cd predicrionai
# Запустите
docker compose up -d --build
Что делает автоматически:
# Backend
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
uvicorn webapp.main:app --reload --port 8000
# Frontend (отдельный терминал)
cd frontend
npm install
npm run dev
# Откройте http://localhost:5173
Добавьте 4 A-записи:
| Name | Content | Proxy |
|---|---|---|
| monte | YOUR_SERVER_IP | ✅ Proxied |
| jupyter.monte | YOUR_SERVER_IP | ✅ Proxied |
| research.monte | YOUR_SERVER_IP | ✅ Proxied |
| traefik.monte | YOUR_SERVER_IP | ❌ DNS only |
cp .env.example .env
nano .env
Заполните:
# Cloudflare API Token
CF_API_EMAIL=your-email@cloudflare.com
CF_API_KEY=your_cloudflare_api_token
# Domain
DOMAIN=monte.yourdomain.com
# Application
NBA_API_RATE_LIMIT=0.6
LOG_LEVEL=INFO
# Кеш матчей (Redis, TTL в секундах, по умолчанию 12 часов)
MATCH_CACHE_TTL_SECONDS=43200
# Запустите все сервисы
docker compose up -d --build
# Проверьте статус
docker ps
# Следите за логами (выпуск сертификатов)
docker logs traefik -f
# Ищите: "Server responded with a certificate"
curl -I https://monte.yourdomain.com # 200
curl -I https://research.monte.yourdomain.com # 200
curl -I https://jupyter.monte.yourdomain.com # 302
ESPN, nba.com или Synthetic (fallback)Список матчей запрашивается в следующем порядке (первый успешный источник выигрывает):
| Приоритет | Источник | Что даёт | source |
|---|---|---|---|
| 1 | ESPN Scoreboard API | Реальные матчи за последние 7 дней и ближайшие 7 дней | espn |
| 2 | stats.nba.com (nba_api) | Исторические матчи сезона 2023-24 | nba_api |
| 3 | SyntheticProvider | Детерминированные синтетические пары (seed 42) — всегда работает | synthetic |
Ответы кешируются в Redis (ключ matches:{mode}:{count}, TTL по умолчанию 12 часов). При недоступности Redis используется in-memory кеш — поведение не меняется.
# Запустите Jupyter
docker compose up jupyter
# Откройте https://jupyter.monte.kz-saas.com
# Пароль в файле CREDENTIALS.txt
Пример кода:
from src.simulation import MonteCarloSimulation
sim = MonteCarloSimulation(
two_point_fg_pct=0.52,
three_point_fg_pct=0.36,
num_iterations=10000
)
best, all = sim.optimize_shot_distribution()
import matplotlib.pyplot as plt
plt.plot([r.three_pt_ratio for r in all],
[r.mean_score for r in all])
plt.show()
predicrionai/
├── webapp/ # FastAPI backend
│ ├── main.py # Точка входа (+ прогрев кеша при старте)
│ ├── api.py # REST routes
│ ├── providers.py # Источники данных: ESPN → nba_api → synthetic
│ ├── cache.py # Redis-кеш матчей (in-memory fallback)
│ ├── services.py # Бизнес-логика
│ └── static/ # Собранный фронтенд
├── frontend/ # React + Vite
│ ├── src/
│ │ ├── pages/ # MatchSelect, Analysis
│ │ └── components/ # TeamCard, Charts
│ └── vite.config.js
├── src/ # Движок симуляции
│ ├── simulation/ # MonteСarlo
│ ├── analysis/ # FourFactors, HotHand
│ └── data/ # NBAClient
├── research-site/ # Статический сайт
└── docker-compose.yml # Оркестрация (traefik, web, redis, jupyter, research)
| Компонент | Технология | Версия |
|---|---|---|
| Backend | FastAPI + Uvicorn | 0.115+ |
| Frontend | React + Vite | 18 / 5 |
| Графики | Chart.js | 4.4 |
| Симуляция | NumPy + SciPy | 1.24+ |
| Кеш | Redis | 7.x |
| Контейнеры | Docker + Compose | v2 |
| Proxy | Traefik + Let's Encrypt | 3.7.10 |
Получить список всех команд NBA.
curl http://localhost:8000/api/teams
Получить профиль команды (статистика бросков, Four Factors).
curl http://localhost:8000/api/teams/1610612747
Запустить симуляцию Монте-Карло.
{
"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
}
Health check эндпоинт.
curl http://localhost:8000/api/health
Список матчей. Для upcoming/history данные запрашиваются из ESPN (fallback: stats.nba.com, затем синтетика) и кешируются в Redis.
curl "http://localhost:8000/api/matches?mode=history&count=5"
Каждый матч содержит поле source — espn, nba_api или synthetic:
[{
"match_id": "ESP-401585000",
"date": "2026-08-04",
"home_team_id": 1610612747,
"away_team_id": 1610612738,
"home_score": 112,
"away_score": 98,
"status": "final",
"source": "espn",
"label": "Los Angeles Lakers vs Boston Celtics"
}]
Полная документация API: https://monte.kz-saas.com/docs
# Найти процесс
lsof -i :8000
# Остановить
kill -9 <PID>
# Или измените порт в docker-compose.yml
ports:
- "8001:8000"
# Пересоберите
cd frontend
npm run build
# Проверьте файлы
ls -la ../webapp/static/
Проверьте хеш пароля в docker-compose.yml — все $ должны быть удвоены:
--NotebookApp.password='argon2:$$argon2id$$v=19$$...'
CREDENTIALS.txttraefik.monte.yourdomain.com в DNS-only режиме (не proxied)# Проверьте логи
docker logs traefik | grep -i error
# Частые причины:
# - Неверный CF_API_KEY
# - Token не имеет прав "Zone DNS Edit"
# - DNS записи отсутствуют
Не проблема! Данные матчей запрашиваются по цепочке ESPN → stats.nba.com → Synthetic. Если все реальные источники недоступны (или сейчас межсезонье и матчей нет), автоматически работает синтетический fallback — вы увидите бейдж "Synthetic". Если stats.nba.com временно блокирует запросы, ESPN продолжает работать и наоборот.
Приложение работает и без Redis: кеш автоматически переключается в in-memory режим (один процесс). Для восстановления Redis: docker compose up -d redis.
Research Concentration under Professor Hesam Oveys
New York University | August 2026