Pickr is an explainable quantitative market-analysis platform. A deterministic Python engine transforms OHLCV data and optional external context into independent factor scores, confidence, a risk-adjusted recommendation, and a bounded trade plan. FastAPI serves a responsive React/TypeScript workspace with empirical backtests, authenticated live updates, and durable portfolio state.
This software provides analytical decision support, not investment advice.
React + TypeScript
├── TanStack Query / Table
├── Plotly and Recharts
└── REST + authenticated WebSocket
↓
FastAPI transport
├── typed schemas and stable error envelopes
├── authentication and rate limiting
└── request IDs and structured logging
↓
Application services
├── analysis
├── walk-forward backtesting
├── authentication
└── portfolio management
↓
Domain and quantitative engines
├── feature extraction
├── ten explicit factor outputs
├── weighted scoring and confidence
├── risk adjustment and trade planning
└── chronological execution simulation
↓
Provider and infrastructure adapters
├── Stooq, NewsAPI, FRED, and Alpha Vantage
├── SQLite repositories
└── monotonic TTL/LRU cache
See the architecture audit, current implementation status, and quantitative methodology.
- Every factor is normalized to
[-1, 1]and exposes availability, confidence, active weight, contribution, and evidence. - Missing news, macro, or fundamental data remains unavailable. It never becomes synthetic neutral evidence.
- Directional weights are renormalized over usable signals. Zero-confidence signals are excluded.
- Risk factors reduce score magnitude but never reverse direction.
- Position sizing is capped by capital at risk and maximum notional exposure.
- Historical score evolution reruns technical inputs available at each point. Current external context is never projected backward.
- Walk-forward backtests generate a signal at a historical close, execute at the next session, prevent overlapping trades, resolve same-bar ambiguity conservatively, and include configured fees and slippage.
Requirements: Python 3.11+ and Node.js 20+.
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -e ".[dev]"
Copy-Item .env.example .env
uvicorn stock_tracker.api.app:app --reload --port 8000In another terminal:
Set-Location frontend
npm ci
npm run devOpen http://localhost:5173. Vite proxies HTTP and WebSocket /api traffic
to FastAPI. Ctrl+K or Cmd+K focuses ticker search.
All settings use the STOCKCHECK_ prefix and are validated at startup. See
.env.example.
NEWS_API_KEYenables news sentiment.FRED_API_KEYenables yield-curve, VIX, and policy-rate context.ALPHA_VANTAGE_API_KEYenables company-quality fundamentals.DATABASE_PATHselects the SQLite analysis, account, and portfolio store.AUTH_SECRET_KEYmust be replaced with at least 32 random bytes. Production startup rejects the documented development placeholders.
External credentials are optional. Missing providers are explicitly marked unavailable.
Public analysis:
GET /api/v1/healthGET /api/v1/analysis/{ticker}GET /api/v1/analysis/{ticker}/historyGET /api/v1/backtests/{ticker}GET /api/v1/config/factors
Authentication and portfolio:
POST /api/v1/auth/registerPOST /api/v1/auth/loginGET /api/v1/auth/meGET|POST /api/v1/portfolio/positionsPUT|DELETE /api/v1/portfolio/positions/{position_id}
Live analysis:
WS /api/v1/stream/analysis/{ticker}- After connection, send
{"type":"authenticate","token":"<access token>"}as the first message.
Development OpenAPI documentation is available at GET /docs. REST errors use
a stable code, message, and request_id envelope.
python -m pytest --cov=stock_tracker --cov-report=term-missing
python -m compileall -q stock_tracker tests
python -m ruff check .
python -m mypy stock_tracker
Set-Location frontend
npm ci
npm run lint
npm run typecheck
npm run test
npm run build
npm audit --omit=devCI runs the same gates. The compatibility
stock_tracker.api.interface.MarketAnalyzer facade remains for existing Python
callers and delegates to the layered application service.
Copy-Item .env.example .env
$secret = python -c "import secrets; print(secrets.token_urlsafe(48))"
(Get-Content .env).Replace(
"replace-with-at-least-32-random-bytes",
$secret
) | Set-Content .env
# Add provider credentials to .env when those integrations are required.
docker compose up --build --waitThe web application is served on http://localhost:8080 by default. Change
STOCKCHECK_PORT and STOCKCHECK_PUBLIC_ORIGIN together when exposing a
different origin. nginx proxies REST and WebSocket traffic to the non-root,
read-only API container. A named volume persists SQLite state, both services
define health checks, and container logs are size-limited.
Useful lifecycle commands:
docker compose ps
docker compose logs -f
docker compose down
# Also delete persisted application data only when intentionally resetting:
docker compose down --volumes