Полная документация проекта

Все необходимое для установки, настройки и использования NBA Shot Strategy приложения.

Содержание

О проекте

Интерактивное веб-приложение, применяющее вероятностные методы финансовой математики к баскетбольной аналитике. Позволяет выбирать матчи NBA, настраивать стратегии бросков и запускать симуляции Монте-Карло для поиска оптимального соотношения 2-очковых/3-очковых бросков.

Ключевые возможности

Быстрый старт

Локально (30 секунд)

cd /opt/predicrionai
docker compose up --build

# Откройте http://localhost:8000

Production (с HTTPS)

# Настройте .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

Установка

Вариант 1: Docker Compose (рекомендуется)

# Клонируйте репозиторий
git clone <repo-url>
cd predicrionai

# Запустите
docker compose up -d --build

Что делает автоматически:

Вариант 2: Локальная разработка

# 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

Production развёртывание

Требования

Шаг 1: Настройка DNS (Cloudflare)

Добавьте 4 A-записи:

Name Content Proxy
monteYOUR_SERVER_IP✅ Proxied
jupyter.monteYOUR_SERVER_IP✅ Proxied
research.monteYOUR_SERVER_IP✅ Proxied
traefik.monteYOUR_SERVER_IP❌ DNS only

Шаг 2: Cloudflare API Token

  1. Cloudflare Dashboard → My ProfileAPI Tokens
  2. Create Token → шаблон Edit zone DNS
  3. Permissions: Zone → DNS → Edit
  4. Zone: ваш домен
  5. Скопируйте токен

Шаг 3: Конфигурация .env

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

Шаг 4: Запуск

# Запустите все сервисы
docker compose up -d --build

# Проверьте статус
docker ps

# Следите за логами (выпуск сертификатов)
docker logs traefik -f

# Ищите: "Server responded with a certificate"

Шаг 5: Проверка

curl -I https://monte.yourdomain.com           # 200
curl -I https://research.monte.yourdomain.com  # 200
curl -I https://jupyter.monte.yourdomain.com   # 302

Использование

Веб-интерфейс

  1. Выбор матча — две команды или матчи из вкладок Synthetic / Historical / Upcoming
  2. Источники матчей — бейджи на матчах: ESPN, nba.com или Synthetic (fallback)
  3. Ожидание данных — при запросе Historical/Upcoming показывается индикатор «Запрос к NBA API…»
  4. Просмотр профилей — текущие стратегии и Four Factors
  5. Настройка параметров:
    • 3-Point ratio (0-95%)
    • 3-Point FG% (20-50%)
    • Hot hand (ВКЛ/ВЫКЛ)
    • Iterations (1K-20K)
  6. Запуск симуляции — получите результаты
  7. Анализ — гистограммы, вероятности, рекомендации

Источники данных матчей

Список матчей запрашивается в следующем порядке (первый успешный источник выигрывает):

ПриоритетИсточникЧто даётsource
1ESPN Scoreboard APIРеальные матчи за последние 7 дней и ближайшие 7 днейespn
2stats.nba.com (nba_api)Исторические матчи сезона 2023-24nba_api
3SyntheticProviderДетерминированные синтетические пары (seed 42) — всегда работаетsynthetic

Ответы кешируются в Redis (ключ matches:{mode}:{count}, TTL по умолчанию 12 часов). При недоступности Redis используется in-memory кеш — поведение не меняется.

Jupyter Notebooks

# Запустите 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)

Технологии

КомпонентТехнологияВерсия
BackendFastAPI + Uvicorn0.115+
FrontendReact + Vite18 / 5
ГрафикиChart.js4.4
СимуляцияNumPy + SciPy1.24+
КешRedis7.x
КонтейнерыDocker + Composev2
ProxyTraefik + Let's Encrypt3.7.10

API документация

Эндпоинты

GET /api/teams

Получить список всех команд NBA.

curl http://localhost:8000/api/teams

GET /api/teams/{team_id}

Получить профиль команды (статистика бросков, Four Factors).

curl http://localhost:8000/api/teams/1610612747

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
}

GET /api/health

Health check эндпоинт.

curl http://localhost:8000/api/health

GET /api/matches?mode=<upcoming|history|synthetic>&count=N

Список матчей. Для upcoming/history данные запрашиваются из ESPN (fallback: stats.nba.com, затем синтетика) и кешируются в Redis.

curl "http://localhost:8000/api/matches?mode=history&count=5"

Каждый матч содержит поле sourceespn, 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

Troubleshooting

Порт 8000 занят

# Найти процесс
lsof -i :8000

# Остановить
kill -9 <PID>

# Или измените порт в docker-compose.yml
ports:
  - "8001:8000"

Frontend не загружается

# Пересоберите
cd frontend
npm run build

# Проверьте файлы
ls -la ../webapp/static/

Jupyter 500 ошибка

Проверьте хеш пароля в docker-compose.yml — все $ должны быть удвоены:

--NotebookApp.password='argon2:$$argon2id$$v=19$$...'

Traefik Dashboard 401

  1. Проверьте пароль в CREDENTIALS.txt
  2. Убедитесь что traefik.monte.yourdomain.com в DNS-only режиме (не proxied)

Сертификаты не выписываются

# Проверьте логи
docker logs traefik | grep -i error

# Частые причины:
# - Неверный CF_API_KEY
# - Token не имеет прав "Zone DNS Edit"
# - DNS записи отсутствуют

NBA API не отвечает

Не проблема! Данные матчей запрашиваются по цепочке ESPN → stats.nba.com → Synthetic. Если все реальные источники недоступны (или сейчас межсезонье и матчей нет), автоматически работает синтетический fallback — вы увидите бейдж "Synthetic". Если stats.nba.com временно блокирует запросы, ESPN продолжает работать и наоборот.

Redis не запущен

Приложение работает и без Redis: кеш автоматически переключается в in-memory режим (один процесс). Для восстановления Redis: docker compose up -d redis.

Дополнительно

Research Concentration under Professor Hesam Oveys
New York University | August 2026