Sentinel is a hackathon project for detecting trading behavior patterns from trade history.
It has:
- a React + TypeScript frontend (
webapp/) - a FastAPI backend (
app/api/) - an XGBoost model loaded at API startup (
app/mltraining/trader_classifier.json)
There is no separate rules engine service in this codebase.
- Upload flow from the UI (file chooser accepts
.csv,.xls,.xlsx) - Calls backend endpoints to upload data and fetch analysis/results
- Displays:
- behavioral profile and bias scores
- cumulative P/L chart
- trade heatmap
- coaching recommendations
- local saved session history (stored in
localStorage)
- Loads an XGBoost model on startup
- Stores uploaded datasets in memory by
session_id - Sanitizes and repairs CSV numeric gaps where possible (
app/api/csv_sanitizer.py) - Exposes endpoints for upload, metrics, analysis, data retrieval, what-if simulation, and health check
- Training script:
app/mltraining/train.py - Inference path:
app/api/analysis_service.py - Model artifacts:
app/mltraining/trader_classifier.jsonandapp/mltraining/trader_classifier95.json
POST /upload/trade-historyGET /data/{session_id}GET /data/{session_id}/rangeGET /metrics/{session_id}GET /analyze/{session_id}POST /what-if/{session_id}/simulatePOST /what-if/{session_id}/downloadGET /health
- Python 3.14+
- FastAPI
- Polars
- NumPy
- XGBoost
- React 19
- TypeScript
- Vite
- PapaParse
- SheetJS (
xlsx) - Custom CSS (not Tailwind)
NationalBankHachathon/
├── app/
│ ├── api/
│ │ ├── analysis_service.py
│ │ ├── csv_sanitizer.py
│ │ ├── data_service.py
│ │ ├── main.py
│ │ ├── routes.py
│ │ ├── schemas.py
│ │ └── state.py
│ ├── mltraining/
│ │ ├── train.py
│ │ ├── test.py
│ │ ├── trader_classifier.json
│ │ └── trader_classifier95.json
│ ├── Dockerfile
│ └── pyproject.toml
├── datasets/
├── webapp/
│ ├── src/
│ ├── Dockerfile
│ └── package.json
├── docker-compose.yml
└── README.md
docker compose up -d --build
docker compose psDefault ports from docker-compose.yml:
- backend:
http://localhost:8001(container port8000) - frontend:
http://localhost:5174(container port5173)
Stop services:
docker compose downOverride ports:
BACKEND_PORT=8000 FRONTEND_PORT=5173 docker compose up -d --buildcd app
uv sync
uv run uvicorn api.main:app --reload --host 0.0.0.0 --port 8000cd webapp
npm install
npm run dev- The frontend API URL is read from
VITE_API_BASE_URLinwebapp/src/lib/api.ts; if you pass only a number, it is treated as a local port (http://localhost:<port>). - The backend upload endpoint expects CSV content (
/upload/trade-historydecodes as UTF-8 CSV). - The what-if download endpoint currently supports CSV output only; XLSX returns an error by design.
Sample datasets are in datasets/ (for example calm_trader.csv, overtrader.csv, loss_averse_trader.csv, revenge_trader.csv, and mixed profiles).
MIT