dennisthiessen e982487abd
Deploy / lint (push) Successful in 7s
Deploy / test (push) Successful in 39s
Deploy / deploy (push) Successful in 25s
coordinate jobs: daily pipeline orchestrator runs the flow in order
Jobs were independent 24h timers with no ordering, so the scanner could run on
stale OHLCV, and manual runs desynced the offsets. New daily_pipeline job runs
the data→signal flow in dependency order: OHLCV → fundamentals → sentiment →
R:R scan → outcome eval (+paper close) → market regime. Each step keeps its own
enable flag and runtime status; a failing step is logged and the pipeline
continues.

The member jobs are registered PAUSED (no auto-fire) so they only run via the
pipeline — but stay manually triggerable from Admin → Jobs (shown as "runs in
daily pipeline"). Alerts (hourly), ticker universe sync, and backtest keep their
own independent cadence.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 10:16:41 +02:00
2026-03-03 20:25:18 +01:00
2026-03-03 15:20:18 +01:00
2026-03-03 20:45:28 +01:00
2026-02-27 16:08:09 +01:00
2026-02-20 17:31:01 +01:00
2026-03-03 20:35:11 +01:00
2026-03-03 15:20:18 +01:00

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

# 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

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

cd frontend
npm run build     # TypeScript check + production build → frontend/dist/
npm run preview   # Preview the production build locally

Tests

# 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

sudo apt update && sudo apt install -y python3.12 python3.12-venv postgresql nginx nodejs npm

2. Create service user

sudo useradd -r -s /usr/sbin/nologin stockdata

3. Deploy application

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

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

DB_NAME=stock_data_backend DB_USER=stock_backend DB_PASS=strong_password ./deploy/setup_db.sh

6. Build frontend

cd frontend
npm ci
npm run build

7. Systemd service

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

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.

sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d signal.thiessen.io

Verify

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)
S
Description
No description provided
Readme 2.5 MiB
Languages
Python 66.8%
TypeScript 32.6%
CSS 0.4%