309 lines
12 KiB
Markdown
309 lines
12 KiB
Markdown
# Signal Dashboard
|
|
|
|
Investing-signal platform for NASDAQ stocks. Surfaces the best trading opportunities through weighted multi-dimensional scoring — technical indicators, support/resistance quality, sentiment, fundamentals, and momentum — with asymmetric risk:reward scanning.
|
|
|
|
**Philosophy:** Don't predict price. Find the path of least resistance, key S/R zones, and asymmetric R:R setups.
|
|
|
|
## Stack
|
|
|
|
| Layer | Tech |
|
|
|---|---|
|
|
| Backend | Python 3.12+, FastAPI, Uvicorn, async SQLAlchemy, Alembic |
|
|
| Database | PostgreSQL (asyncpg) |
|
|
| Scheduler | APScheduler — OHLCV, sentiment, fundamentals, R:R scan |
|
|
| Frontend | React 18, TypeScript, Vite 5 |
|
|
| Styling | Tailwind CSS 3 with custom glassmorphism design system |
|
|
| State | TanStack React Query v5 (server), Zustand (client/auth) |
|
|
| Charts | Canvas 2D candlestick chart with S/R overlays |
|
|
| Routing | React Router v6 (SPA) |
|
|
| HTTP | Axios with JWT interceptor |
|
|
| Data providers | Alpaca (OHLCV), OpenAI (sentiment, optional micro-batch), Fundamentals chain: FMP → Finnhub → Alpha Vantage |
|
|
|
|
## Features
|
|
|
|
### Backend
|
|
- Ticker registry with full cascade delete
|
|
- Universe bootstrap for `sp500`, `nasdaq100`, `nasdaq_all` via admin endpoint
|
|
- OHLCV price storage with upsert and validation
|
|
- Technical indicators: ADX, EMA, RSI, ATR, Volume Profile, Pivot Points, EMA Cross
|
|
- Support/Resistance detection with strength scoring and merge-within-tolerance
|
|
- Sentiment analysis with time-decay weighted scoring
|
|
- Fundamental data tracking (P/E, revenue growth, earnings surprise, market cap)
|
|
- 5-dimension scoring engine (technical, S/R quality, sentiment, fundamental, momentum) with configurable weights
|
|
- Risk:Reward scanner — long and short setups, ATR-based stops, configurable R:R threshold (default 1.5:1)
|
|
- Auto-populated watchlist (top-10 by composite score) + manual entries (cap: 20)
|
|
- JWT auth with admin role, configurable registration, user access control
|
|
- Scheduled jobs with enable/disable control and status monitoring
|
|
- Admin panel: user management, data cleanup, job control, system settings
|
|
|
|
### Frontend
|
|
- Glassmorphism UI with frosted glass panels, gradient text, ambient glow effects, mesh gradient background
|
|
- Interactive candlestick chart (Canvas 2D) with hover tooltips showing OHLCV values
|
|
- Support/Resistance level overlays on chart (top 6 by strength, dashed lines with labels)
|
|
- Data freshness bar showing availability and recency of each data source
|
|
- Watchlist with composite scores, R:R ratios, and S/R summaries
|
|
- Ticker detail page: chart, scores, sentiment breakdown, fundamentals, technical indicators, S/R table
|
|
- Rankings table with configurable dimension weights
|
|
- Trade scanner showing detected R:R setups
|
|
- Admin page: user management, job status with live indicators, enable/disable toggles, data cleanup, system settings
|
|
- Protected routes with JWT auth, admin-only sections
|
|
- Responsive layout with mobile navigation
|
|
- Toast notifications for async operations
|
|
|
|
## Pages
|
|
|
|
| Route | Page | Access |
|
|
|---|---|---|
|
|
| `/login` | Login | Public |
|
|
| `/register` | Register | Public (when enabled) |
|
|
| `/watchlist` | Watchlist (default) | Authenticated |
|
|
| `/ticker/:symbol` | Ticker Detail | Authenticated |
|
|
| `/scanner` | Trade Scanner | Authenticated |
|
|
| `/rankings` | Rankings | Authenticated |
|
|
| `/admin` | Admin Panel | Admin only |
|
|
|
|
## API Endpoints
|
|
|
|
All under `/api/v1/`. Interactive docs at `/docs` (Swagger) and `/redoc`.
|
|
|
|
| Group | Endpoints |
|
|
|---|---|
|
|
| Health | `GET /health` |
|
|
| Auth | `POST /auth/register`, `POST /auth/login` |
|
|
| Tickers | `POST /tickers`, `GET /tickers`, `DELETE /tickers/{symbol}` |
|
|
| OHLCV | `POST /ohlcv`, `GET /ohlcv/{symbol}` |
|
|
| Ingestion | `POST /ingestion/fetch/{symbol}` |
|
|
| Indicators | `GET /indicators/{symbol}/{type}`, `GET /indicators/{symbol}/ema-cross` |
|
|
| S/R Levels | `GET /sr-levels/{symbol}` |
|
|
| Sentiment | `GET /sentiment/{symbol}` |
|
|
| Fundamentals | `GET /fundamentals/{symbol}` |
|
|
| Scores | `GET /scores/{symbol}`, `GET /rankings`, `PUT /scores/weights` |
|
|
| Trades | `GET /trades` |
|
|
| Watchlist | `GET /watchlist`, `POST /watchlist/{symbol}`, `DELETE /watchlist/{symbol}` |
|
|
| Admin | `GET /admin/users`, `POST /admin/users`, `PUT /admin/users/{id}/access`, `PUT /admin/users/{id}/password`, `PUT /admin/settings/registration`, `GET /admin/settings`, `PUT /admin/settings/{key}`, `GET/PUT /admin/settings/recommendations`, `GET/PUT /admin/settings/ticker-universe`, `POST /admin/tickers/bootstrap`, `POST /admin/data/cleanup`, `GET /admin/jobs`, `POST /admin/jobs/{name}/trigger`, `PUT /admin/jobs/{name}/toggle`, `GET /admin/pipeline/readiness` |
|
|
|
|
## Development Setup
|
|
|
|
### Prerequisites
|
|
|
|
- Python 3.12+
|
|
- PostgreSQL (via Homebrew on macOS: `brew install postgresql@17`)
|
|
- Node.js 18+ and npm
|
|
|
|
### Backend Setup
|
|
|
|
```bash
|
|
# Create and activate virtual environment
|
|
python -m venv .venv
|
|
source .venv/bin/activate
|
|
pip install -e ".[dev]"
|
|
|
|
# Configure environment
|
|
cp .env.example .env
|
|
# Edit .env with your values (see Environment Variables below)
|
|
|
|
# Start PostgreSQL and create database
|
|
brew services start postgresql@17
|
|
createdb stock_data_backend
|
|
createuser stock_backend
|
|
|
|
# Run migrations
|
|
alembic upgrade head
|
|
|
|
# Start the backend
|
|
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
|
|
```
|
|
|
|
A default `admin`/`admin` account is created on first startup. Open http://localhost:8000/docs for Swagger UI.
|
|
|
|
### Frontend Setup
|
|
|
|
```bash
|
|
cd frontend
|
|
npm install
|
|
npm run dev
|
|
```
|
|
|
|
Open http://localhost:5173 for the Signal Dashboard. The Vite dev server proxies `/api/v1/` requests to the backend at `http://127.0.0.1:8000`.
|
|
|
|
### Frontend Build
|
|
|
|
```bash
|
|
cd frontend
|
|
npm run build # TypeScript check + production build → frontend/dist/
|
|
npm run preview # Preview the production build locally
|
|
```
|
|
|
|
### Tests
|
|
|
|
```bash
|
|
# Backend tests (in-memory SQLite — no PostgreSQL needed)
|
|
pytest tests/ -v
|
|
|
|
# Frontend tests
|
|
cd frontend
|
|
npm test
|
|
```
|
|
|
|
## Environment Variables
|
|
|
|
Configure in `.env` (copy from `.env.example`):
|
|
|
|
| Variable | Required | Default | Description |
|
|
|---|---|---|---|
|
|
| `DATABASE_URL` | Yes | — | PostgreSQL connection string (`postgresql+asyncpg://...`) |
|
|
| `JWT_SECRET` | Yes | — | Random secret for JWT signing |
|
|
| `JWT_EXPIRY_MINUTES` | No | `60` | JWT token expiry |
|
|
| `ALPACA_API_KEY` | For OHLCV | — | Alpaca Markets API key |
|
|
| `ALPACA_API_SECRET` | For OHLCV | — | Alpaca Markets API secret |
|
|
| `GEMINI_API_KEY` | For sentiment | — | Google Gemini API key |
|
|
| `GEMINI_MODEL` | No | `gemini-2.0-flash` | Gemini model name |
|
|
| `OPENAI_API_KEY` | For sentiment (OpenAI path) | — | OpenAI API key |
|
|
| `OPENAI_MODEL` | No | `gpt-4o-mini` | OpenAI model name |
|
|
| `OPENAI_SENTIMENT_BATCH_SIZE` | No | `5` | Micro-batch size for sentiment collector |
|
|
| `FMP_API_KEY` | Optional (fundamentals) | — | Financial Modeling Prep API key (first provider in chain) |
|
|
| `FINNHUB_API_KEY` | Optional (fundamentals) | — | Finnhub API key (fallback provider) |
|
|
| `ALPHA_VANTAGE_API_KEY` | Optional (fundamentals) | — | Alpha Vantage API key (fallback provider) |
|
|
| `DATA_COLLECTOR_FREQUENCY` | No | `daily` | OHLCV collection schedule |
|
|
| `SENTIMENT_POLL_INTERVAL_MINUTES` | No | `30` | Sentiment polling interval |
|
|
| `FUNDAMENTAL_FETCH_FREQUENCY` | No | `daily` | Fundamentals fetch schedule |
|
|
| `RR_SCAN_FREQUENCY` | No | `daily` | R:R scanner schedule |
|
|
| `FUNDAMENTAL_RATE_LIMIT_RETRIES` | No | `3` | Retries per ticker on fundamentals rate-limit |
|
|
| `FUNDAMENTAL_RATE_LIMIT_BACKOFF_SECONDS` | No | `15` | Base backoff seconds for fundamentals retry (exponential) |
|
|
| `DEFAULT_WATCHLIST_AUTO_SIZE` | No | `10` | Auto-watchlist size |
|
|
| `DEFAULT_RR_THRESHOLD` | No | `3.0` | Minimum R:R ratio for setups |
|
|
| `DB_POOL_SIZE` | No | `5` | Database connection pool size |
|
|
| `LOG_LEVEL` | No | `INFO` | Logging level |
|
|
|
|
## Production Deployment (Debian 12)
|
|
|
|
### 1. Install dependencies
|
|
|
|
```bash
|
|
sudo apt update && sudo apt install -y python3.12 python3.12-venv postgresql nginx nodejs npm
|
|
```
|
|
|
|
### 2. Create service user
|
|
|
|
```bash
|
|
sudo useradd -r -s /usr/sbin/nologin stockdata
|
|
```
|
|
|
|
### 3. Deploy application
|
|
|
|
```bash
|
|
sudo mkdir -p /opt/stock-data-backend
|
|
# Copy project files to /opt/stock-data-backend
|
|
cd /opt/stock-data-backend
|
|
python3.12 -m venv .venv
|
|
source .venv/bin/activate
|
|
pip install .
|
|
```
|
|
|
|
### 4. Configure
|
|
|
|
```bash
|
|
sudo cp .env.example /opt/stock-data-backend/.env
|
|
sudo chown stockdata:stockdata /opt/stock-data-backend/.env
|
|
# Edit .env with production values (strong JWT_SECRET, real API keys, etc.)
|
|
```
|
|
|
|
### 5. Database
|
|
|
|
```bash
|
|
DB_NAME=stock_data_backend DB_USER=stock_backend DB_PASS=strong_password ./deploy/setup_db.sh
|
|
```
|
|
|
|
### 6. Build frontend
|
|
|
|
```bash
|
|
cd frontend
|
|
npm ci
|
|
npm run build
|
|
```
|
|
|
|
### 7. Systemd service
|
|
|
|
```bash
|
|
sudo cp deploy/stock-data-backend.service /etc/systemd/system/
|
|
sudo systemctl daemon-reload
|
|
sudo systemctl enable --now stock-data-backend
|
|
```
|
|
|
|
### 8. Nginx reverse proxy
|
|
|
|
```bash
|
|
sudo cp deploy/nginx.conf /etc/nginx/sites-available/stock-data-backend
|
|
sudo ln -s /etc/nginx/sites-available/stock-data-backend /etc/nginx/sites-enabled/
|
|
sudo nginx -t && sudo systemctl reload nginx
|
|
```
|
|
|
|
Nginx serves the frontend static files from `frontend/dist/` and proxies `/api/v1/` to the backend.
|
|
|
|
### 9. SSL (recommended)
|
|
|
|
```bash
|
|
sudo apt install certbot python3-certbot-nginx
|
|
sudo certbot --nginx -d signal.thiessen.io
|
|
```
|
|
|
|
### Verify
|
|
|
|
```bash
|
|
curl https://signal.thiessen.io/api/v1/health
|
|
```
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
app/
|
|
├── main.py # FastAPI app, lifespan, router wiring
|
|
├── config.py # Pydantic settings from .env
|
|
├── database.py # Async SQLAlchemy engine + session
|
|
├── dependencies.py # DI: DB session, auth guards
|
|
├── exceptions.py # Exception hierarchy
|
|
├── middleware.py # Global error handler → JSON envelope
|
|
├── cache.py # LRU cache with per-ticker invalidation
|
|
├── scheduler.py # APScheduler job definitions
|
|
├── models/ # SQLAlchemy ORM models
|
|
├── schemas/ # Pydantic request/response schemas
|
|
├── services/ # Business logic layer
|
|
├── providers/ # External data provider integrations
|
|
└── routers/ # FastAPI route handlers
|
|
|
|
frontend/
|
|
├── index.html # SPA entry point
|
|
├── vite.config.ts # Vite config with API proxy
|
|
├── tailwind.config.ts # Tailwind + glassmorphism theme
|
|
├── package.json
|
|
└── src/
|
|
├── App.tsx # Route definitions
|
|
├── main.tsx # React entry point
|
|
├── api/ # Axios API client modules (one per resource)
|
|
├── components/
|
|
│ ├── admin/ # User table, job controls, settings, data cleanup
|
|
│ ├── auth/ # Protected route wrapper
|
|
│ ├── charts/ # Canvas candlestick chart
|
|
│ ├── layout/ # App shell, sidebar, mobile nav
|
|
│ ├── rankings/ # Rankings table, weights form
|
|
│ ├── scanner/ # Trade table
|
|
│ ├── ticker/ # Sentiment panel, fundamentals, indicators, S/R overlay
|
|
│ ├── ui/ # Badge, toast, skeleton, score card, confirm dialog
|
|
│ └── watchlist/ # Watchlist table, add ticker form
|
|
├── hooks/ # React Query hooks (one per resource)
|
|
├── lib/ # Types, formatting utilities
|
|
├── pages/ # Page components (7 pages)
|
|
├── stores/ # Zustand auth store
|
|
└── styles/ # Global CSS with glassmorphism classes
|
|
|
|
deploy/
|
|
├── nginx.conf # Reverse proxy + static file serving
|
|
├── setup_db.sh # Idempotent DB setup script
|
|
└── stock-data-backend.service # systemd unit
|
|
|
|
tests/
|
|
├── conftest.py # Fixtures, strategies, test DB
|
|
├── unit/ # Unit tests
|
|
└── property/ # Property-based tests (Hypothesis)
|
|
```
|