222 lines
17 KiB
Markdown
222 lines
17 KiB
Markdown
# Requirements Document
|
|
|
|
## Introduction
|
|
|
|
This document defines the requirements for the Stock Data Backend — an opinionated investing-signal platform built with Python/FastAPI and PostgreSQL, focused on NASDAQ stocks. The platform's philosophy: find the path of least resistance (trend direction), identify key support/resistance zones, detect asymmetric risk-reward setups, and surface the best opportunities through a unified scoring pipeline. It does not attempt to predict price — it identifies where conditions are most favorable.
|
|
|
|
Every data source (OHLCV, technical indicators, sentiment, fundamentals) feeds into a single composite scoring and ranking system that auto-populates a watchlist and flags trade setups. Data ingestion is exclusively via the configured market data provider — users do not upload data directly.
|
|
|
|
This is an MVP focused on delivering actionable signals. Engineering concerns (API format, database indexing, logging, connection pooling, graceful shutdown) are design constraints, not requirements.
|
|
|
|
## Glossary
|
|
|
|
- **Backend_Service**: The FastAPI-based Python web application that exposes REST API endpoints.
|
|
- **Ticker**: A unique NASDAQ stock symbol (e.g., AAPL, MSFT) being tracked by the system.
|
|
- **OHLCV_Record**: A single price data point containing Open, High, Low, Close, and Volume values for a specific Ticker on a specific date.
|
|
- **Ticker_Registry**: The subsystem responsible for adding, removing, listing, and looking up tracked NASDAQ tickers.
|
|
- **Price_Store**: The subsystem responsible for persisting and retrieving OHLCV price data in PostgreSQL.
|
|
- **Ingestion_Pipeline**: The subsystem responsible for importing stock data into the Price_Store via the configured market data provider.
|
|
- **Data_Collector**: A scheduled job that periodically fetches the latest price data for all tracked tickers and upserts it into the Price_Store.
|
|
- **Auth_Service**: The subsystem responsible for user registration, login, JWT token management, and role-based access control.
|
|
- **User**: A registered account with a username, hashed password, and assigned role (user or admin).
|
|
- **Admin**: A User with the admin role who can manage other users and configure system settings.
|
|
- **Access_Token**: A JWT token issued upon login, expires after 60 minutes.
|
|
- **ADX**: Average Directional Index — measures trend strength (0-100). Values above 25 indicate a strong trend.
|
|
- **EMA**: Exponential Moving Average — configurable period. EMA Cross (e.g., 20/50) determines directional bias.
|
|
- **RSI**: Relative Strength Index — momentum oscillator (0-100). Overbought >70, oversold <30.
|
|
- **ATR**: Average True Range — measures price volatility. Used for stop-loss and target placement.
|
|
- **Volume_Profile**: Distribution of traded volume across price levels, producing POC, Value Area, HVN, and LVN.
|
|
- **POC**: Point of Control — price level with highest traded volume.
|
|
- **HVN**: High Volume Node — above-average volume level, acts as support/resistance magnet.
|
|
- **LVN**: Low Volume Node — below-average volume level, acts as breakout zone.
|
|
- **Pivot_Point**: A support or resistance level from swing highs and swing lows.
|
|
- **SR_Level**: A support or resistance level tagged with type, strength score, and detection method.
|
|
- **SR_Detector**: The subsystem that auto-calculates support and resistance levels.
|
|
- **Sentiment_Score**: A record containing bullish/bearish/neutral classification, confidence (0-100), source, and timestamp for a Ticker.
|
|
- **Fundamental_Data**: Key financial metrics: P/E ratio, revenue growth rate, earnings surprise %, and market cap.
|
|
- **Composite_Score**: A weighted aggregate score (0-100) from all dimension scores for a Ticker.
|
|
- **Dimension_Score**: A normalized score (0-100) for a single analysis dimension (technical, S/R quality, sentiment, fundamental, momentum).
|
|
- **Scoring_Engine**: The subsystem that computes dimension scores, applies weights, and produces Composite_Scores.
|
|
- **RR_Scanner**: The subsystem that scans for asymmetric risk-reward trade setups.
|
|
- **Trade_Setup**: A detected trade opportunity with entry, stop-loss, target, R:R ratio, direction (long/short), and Composite_Score.
|
|
- **Watchlist**: A curated list of top-ranked tickers from the Scoring_Engine, with manual add/remove support.
|
|
- **System_Settings**: Persisted configuration values managed by admins.
|
|
|
|
## Requirements
|
|
|
|
### Requirement 1: Ticker Management
|
|
|
|
**User Story:** As a user, I want to manage the NASDAQ tickers I am tracking, so that I can control which stocks the system analyzes.
|
|
|
|
#### Acceptance Criteria
|
|
|
|
- 1.1 WHEN a user submits a valid NASDAQ ticker symbol, THE Ticker_Registry SHALL create a new ticker entry and return the created ticker with its metadata.
|
|
- 1.2 WHEN a user submits a ticker symbol that already exists, THE Backend_Service SHALL return a duplicate error.
|
|
- 1.3 WHEN a user submits an empty or whitespace-only ticker symbol, THE Backend_Service SHALL reject the request with a validation error.
|
|
- 1.4 WHEN a user requests the list of tracked tickers, THE Ticker_Registry SHALL return all tickers sorted alphabetically by symbol.
|
|
- 1.5 WHEN a user requests deletion of a tracked ticker, THE Ticker_Registry SHALL remove the ticker and all associated data (OHLCV, scores, setups).
|
|
- 1.6 WHEN a user requests deletion of a ticker that does not exist, THE Backend_Service SHALL return a not-found error.
|
|
|
|
### Requirement 2: OHLCV Price Data Storage
|
|
|
|
**User Story:** As a user, I want the system to store historical OHLCV price data, so that technical analysis and signal detection have a data foundation.
|
|
|
|
#### Acceptance Criteria
|
|
|
|
- 2.1 THE Price_Store SHALL persist each OHLCV_Record with: ticker symbol, date, open, high, low, close, and volume.
|
|
- 2.2 THE Price_Store SHALL enforce uniqueness on (ticker symbol, date).
|
|
- 2.3 THE Backend_Service SHALL reject OHLCV_Records where high < low, any price is negative, volume is negative, or date is in the future.
|
|
- 2.4 THE Backend_Service SHALL reject OHLCV_Records for tickers not in the Ticker_Registry.
|
|
|
|
### Requirement 3: Data Ingestion
|
|
|
|
**User Story:** As a user, I want the system to fetch stock data from the market data provider, so that my price history stays current.
|
|
|
|
#### Acceptance Criteria
|
|
|
|
- 3.1 WHEN a user requests a data fetch for a ticker and date range, THE Ingestion_Pipeline SHALL fetch from the configured provider and upsert into the Price_Store.
|
|
- 3.2 IF the provider is unreachable or errors, THE Ingestion_Pipeline SHALL return a descriptive error without modifying existing data.
|
|
- 3.3 IF the provider returns a rate-limit error, THE Ingestion_Pipeline SHALL record progress and return a response indicating how many records were ingested, so the fetch can be resumed without gaps.
|
|
- 3.4 WHEN a rate-limited fetch is resumed for the same ticker and date range, THE Ingestion_Pipeline SHALL continue from the last successfully ingested date.
|
|
|
|
### Requirement 4: Scheduled Data Collection
|
|
|
|
**User Story:** As a user, I want the system to automatically fetch the latest price data on a schedule, so that my data stays current without manual intervention.
|
|
|
|
#### Acceptance Criteria
|
|
|
|
- 4.1 THE Data_Collector SHALL periodically fetch the latest daily OHLCV data for all tracked tickers.
|
|
- 4.2 THE Data_Collector SHALL upsert records, updating existing ones if they already exist.
|
|
- 4.3 WHEN the Data_Collector encounters an error for a specific ticker, it SHALL log the error and continue with remaining tickers.
|
|
- 4.4 THE Data_Collector SHALL be configurable for frequency (daily, hourly) via configuration.
|
|
- 4.5 IF a rate limit is hit during collection, THE Data_Collector SHALL record the last successful ticker and resume from there on the next run.
|
|
|
|
### Requirement 5: Technical Analysis
|
|
|
|
**User Story:** As a user, I want the system to compute key technical indicators, so that trend strength, momentum, and volatility feed into the scoring pipeline.
|
|
|
|
#### Acceptance Criteria
|
|
|
|
- 5.1 THE Backend_Service SHALL compute the following from OHLCV data: ADX, EMA (default periods 20 and 50), RSI (default 14-period), ATR (default 14-period), Volume_Profile (POC, Value Area, HVN, LVN), and Pivot_Points (swing highs/lows).
|
|
- 5.2 WHEN an indicator is requested for a Ticker and date range, THE Backend_Service SHALL return both raw values and a normalized score (0-100).
|
|
- 5.3 WHEN an EMA Cross signal is requested, THE Backend_Service SHALL compare short vs long EMA and return directional bias (bullish, bearish, neutral).
|
|
- 5.4 IF insufficient data exists to compute an indicator, THE Backend_Service SHALL return an error indicating the minimum data requirement.
|
|
|
|
### Requirement 6: Support/Resistance Detection
|
|
|
|
**User Story:** As a user, I want the system to auto-calculate support and resistance levels, so that I can see key price zones where buying or selling pressure concentrates.
|
|
|
|
#### Acceptance Criteria
|
|
|
|
- 6.1 THE SR_Detector SHALL identify SR_Levels from Volume_Profile (HVN/LVN zones) and from Pivot_Points (swing highs/lows).
|
|
- 6.2 THE SR_Detector SHALL assign each level a strength score (0-100) based on how many times price has respected that level.
|
|
- 6.3 THE SR_Detector SHALL tag each level as "support" or "resistance" relative to current price.
|
|
- 6.4 WHEN new OHLCV data arrives for a Ticker, THE SR_Detector SHALL recalculate its SR_Levels.
|
|
- 6.5 THE SR_Detector SHALL merge levels from different methods within a configurable price tolerance (default 0.5%) into a single consolidated level.
|
|
- 6.6 WHEN a user requests SR_Levels for a Ticker, they SHALL be returned sorted by strength descending with detection method indicated.
|
|
|
|
### Requirement 7: Sentiment Data
|
|
|
|
**User Story:** As a user, I want sentiment data to feed into the scoring pipeline, so that social mood is factored into signal detection.
|
|
|
|
#### Acceptance Criteria
|
|
|
|
- 7.1 THE Backend_Service SHALL periodically collect sentiment data for all tracked tickers from a configured source at a configurable interval (default 30 minutes).
|
|
- 7.2 EACH Sentiment_Score SHALL contain: classification (bullish/bearish/neutral), confidence (0-100), source identifier, and timestamp.
|
|
- 7.3 IF the sentiment source is unreachable, THE Backend_Service SHALL log the error and retain existing data.
|
|
- 7.4 WHEN computing the sentiment Dimension_Score, THE Scoring_Engine SHALL aggregate recent scores within a configurable lookback window (default 24h) using configurable source weights and time decay.
|
|
|
|
### Requirement 8: Fundamental Data
|
|
|
|
**User Story:** As a user, I want key fundamental metrics to feed into the scoring pipeline, so that financial quality is factored into signal detection.
|
|
|
|
#### Acceptance Criteria
|
|
|
|
- 8.1 THE Backend_Service SHALL fetch and store Fundamental_Data for each tracked Ticker: P/E ratio, revenue growth rate, earnings surprise %, and market cap.
|
|
- 8.2 THE Data_Collector SHALL periodically fetch updated Fundamental_Data (default daily).
|
|
- 8.3 IF the data source is unreachable, THE Backend_Service SHALL log the error and retain the most recent data.
|
|
- 8.4 WHEN new Fundamental_Data arrives, THE Scoring_Engine SHALL mark the fundamental Dimension_Score as stale.
|
|
|
|
### Requirement 9: Composite Scoring and Ranking
|
|
|
|
**User Story:** As a user, I want each stock scored across all dimensions with configurable weights, so that I can rank stocks by a single unified metric tuned to my preferences.
|
|
|
|
#### Acceptance Criteria
|
|
|
|
- 9.1 THE Scoring_Engine SHALL compute a Dimension_Score (0-100) per Ticker for: technical, S/R quality, sentiment, fundamental, and momentum.
|
|
- 9.2 THE Scoring_Engine SHALL compute a Composite_Score as the weighted average of available Dimension_Scores using user-configurable weights.
|
|
- 9.3 WHEN a Ticker is missing data for one or more dimensions, THE Scoring_Engine SHALL use only available dimensions (re-normalizing weights) and indicate which are missing.
|
|
- 9.4 WHEN underlying data changes, THE Scoring_Engine SHALL mark the affected Composite_Score as stale.
|
|
- 9.5 WHEN a stale score is requested, THE Scoring_Engine SHALL recompute on-demand. No background recomputation.
|
|
- 9.6 WHEN a user requests rankings, THE Scoring_Engine SHALL return tickers sorted by Composite_Score descending with all Dimension_Scores included.
|
|
- 9.7 WHEN a user updates dimension weights, THE Scoring_Engine SHALL recompute all Composite_Scores.
|
|
|
|
### Requirement 10: Asymmetric R:R Trade Detection
|
|
|
|
**User Story:** As a user, I want the system to scan for trade setups with favorable risk-reward ratios, so that I see highly asymmetric opportunities without manual chart analysis.
|
|
|
|
#### Acceptance Criteria
|
|
|
|
- 10.1 THE RR_Scanner SHALL periodically scan all tracked tickers for Trade_Setups meeting a configurable R:R threshold (default 3:1).
|
|
- 10.2 FOR long setups: target = nearest SR_Level above price, stop = ATR-based distance below price.
|
|
- 10.3 FOR short setups: target = nearest SR_Level below price, stop = ATR-based distance above price.
|
|
- 10.4 EACH Trade_Setup SHALL include: entry price, stop-loss, target, R:R ratio, direction (long/short), and Composite_Score.
|
|
- 10.5 WHEN underlying SR_Levels or price data changes, THE RR_Scanner SHALL recalculate and remove setups that no longer meet the threshold.
|
|
- 10.6 THE RR_Scanner SHALL be configurable for scan frequency via configuration.
|
|
- 10.7 IF a Ticker lacks sufficient SR_Levels or ATR data, THE RR_Scanner SHALL skip it and log the reason.
|
|
- 10.8 WHEN a user requests trade setups, results SHALL be sorted by R:R descending (secondary: Composite_Score descending), with optional direction filter.
|
|
|
|
### Requirement 11: Watchlist
|
|
|
|
**User Story:** As a user, I want a watchlist of top-ranked stocks that auto-populates from scoring, so that I always have a curated shortlist of the best opportunities.
|
|
|
|
#### Acceptance Criteria
|
|
|
|
- 11.1 THE Watchlist SHALL auto-include the top-X tickers by Composite_Score (X configurable, default 10).
|
|
- 11.2 WHEN requested, THE Watchlist SHALL return each entry with Composite_Score, Dimension_Scores, R:R ratio (if setup exists), and active SR_Levels.
|
|
- 11.3 Users MAY manually add/remove tickers. Manual additions are tagged and not subject to auto-population rules.
|
|
- 11.4 THE Watchlist SHALL enforce a max size of auto-populate count + 10 manual additions (default max 20).
|
|
- 11.5 WHEN Composite_Scores are recomputed, auto-populated entries SHALL update to reflect new rankings.
|
|
- 11.6 THE Watchlist SHALL be sortable by Composite_Score, any Dimension_Score, or R:R ratio.
|
|
|
|
### Requirement 12: User Authentication
|
|
|
|
**User Story:** As a system owner, I want user registration and login with role-based access, so that only authorized users can access signals and analysis.
|
|
|
|
#### Acceptance Criteria
|
|
|
|
- 12.1 WHEN registration is enabled and valid credentials are submitted, THE Auth_Service SHALL create a User with no API access by default.
|
|
- 12.2 WHEN registration is disabled, THE Auth_Service SHALL reject registration.
|
|
- 12.3 WHEN valid login credentials are submitted, THE Auth_Service SHALL return an Access_Token (60-minute expiry).
|
|
- 12.4 WHEN invalid credentials are submitted, THE Auth_Service SHALL return an error without revealing which field was wrong.
|
|
- 12.5 Unauthenticated requests to protected endpoints SHALL receive 401. Authenticated users without granted access SHALL receive 403.
|
|
- 12.6 WHEN a token expires, THE Backend_Service SHALL return 401 indicating expiration.
|
|
|
|
### Requirement 13: Admin Management
|
|
|
|
**User Story:** As an admin, I want to manage users, control system settings, and perform data maintenance.
|
|
|
|
#### Acceptance Criteria
|
|
|
|
- 13.1 WHEN the system initializes for the first time, a default admin account SHALL be created (username: "admin", password: "admin").
|
|
- 13.2 Admins SHALL be able to: grant/revoke user access, toggle registration, list all users, reset user passwords, and create new user accounts.
|
|
- 13.3 Admins SHALL be able to: enable/disable scheduled jobs, update system settings (frequencies, thresholds, weights, watchlist size), and trigger manual job runs.
|
|
- 13.4 Admins SHALL be able to delete all data older than a specified number of days (OHLCV, sentiment, fundamentals). Ticker entries, user accounts, and latest scores SHALL be preserved.
|
|
- 13.5 Admin endpoints SHALL be restricted to users with the admin role.
|
|
|
|
## Design Constraints
|
|
|
|
The following are engineering concerns to be addressed during design, not user-facing requirements:
|
|
|
|
- Consistent JSON API envelope (status, data, error fields) with appropriate HTTP status codes
|
|
- OpenAPI/Swagger documentation endpoint
|
|
- Versioned URL prefixes (/api/v1/)
|
|
- Composite database index on (ticker, date) for range query performance
|
|
- Date-only storage for OHLCV (no time component)
|
|
- Database migrations for schema management
|
|
- Structured JSON logging with configurable levels
|
|
- Database connection pooling (default 5 connections)
|
|
- Health check endpoint (unauthenticated)
|
|
- Graceful shutdown (complete in-flight requests, stop jobs, close pool)
|
|
- Market data provider behind an interface/protocol for swappability
|