9.7 KiB
Requirements Document
Introduction
This specification covers four dashboard enhancements for the stock signal platform: sentiment drill-down with OpenAI response details, fundamentals drill-down with missing-data transparency, TradingView-style chart improvements (zoom, crosshair), and S/R level clustering into filterable shaded zones. All changes target the existing TickerDetailPage and its child components, preserving the glassmorphism UI style.
Glossary
- Dashboard: The TickerDetailPage in the React frontend that displays ticker data, charts, scores, sentiment, and fundamentals.
- Sentiment_Panel: The SentimentPanel component that displays classification, confidence, dimension score, and source count for a ticker.
- Fundamentals_Panel: The FundamentalsPanel component that displays P/E Ratio, Revenue Growth, Earnings Surprise, and Market Cap for a ticker.
- Chart_Component: The CandlestickChart canvas-based component that renders OHLCV candlesticks and S/R level overlays.
- SR_Service: The backend service (sr_service.py) that detects, scores, merges, and tags support/resistance levels from OHLCV data.
- Sentiment_Provider: The OpenAISentimentProvider that calls the OpenAI Responses API with web_search_preview to produce sentiment classifications.
- FMP_Provider: The FMPFundamentalProvider that fetches fundamental data from Financial Modeling Prep stable endpoints.
- SR_Zone: A price range representing a cluster of nearby S/R levels, displayed as a shaded area on the chart instead of individual lines.
- Detail_Section: A collapsible/expandable UI region within a panel that reveals additional information on user interaction.
- Data_Availability_Indicator: A visual element within the Fundamentals_Panel that communicates which data fields are unavailable and the reason.
- Crosshair: A vertical and horizontal line overlay on the Chart_Component that tracks the cursor position and displays corresponding price and date values.
Requirements
Requirement 1: Sentiment Detail Storage
User Story: As a developer, I want the backend to store the full OpenAI response details (reasoning text, web search citations, and annotations) alongside the sentiment classification, so that the frontend can display drill-down information.
Acceptance Criteria
- WHEN the Sentiment_Provider receives a response from the OpenAI Responses API, THE Sentiment_Provider SHALL extract and return the reasoning text from the parsed JSON response.
- WHEN the Sentiment_Provider receives a response containing web_search_preview output items, THE Sentiment_Provider SHALL extract and return the list of source URLs and titles from the search result annotations.
- THE sentiment API endpoint SHALL include the reasoning text and citations list in the response payload for each sentiment score.
- IF the OpenAI response contains no annotations or citations, THEN THE Sentiment_Provider SHALL return an empty citations list without raising an error.
Requirement 2: Sentiment Drill-Down UI
User Story: As a user, I want to drill into the sentiment analysis to see the AI reasoning and source citations, so that I can evaluate the quality of the sentiment classification.
Acceptance Criteria
- THE Sentiment_Panel SHALL display a clickable expand/collapse toggle below the summary metrics.
- WHEN the user expands the Detail_Section, THE Sentiment_Panel SHALL display the reasoning text from the latest sentiment score.
- WHEN the user expands the Detail_Section and citations are available, THE Sentiment_Panel SHALL display each citation as a clickable link showing the source title and URL.
- WHEN the user collapses the Detail_Section, THE Sentiment_Panel SHALL hide the reasoning and citations without removing the summary metrics.
- THE Detail_Section SHALL default to the collapsed state on initial render.
Requirement 3: Fundamentals Data Availability Transparency
User Story: As a user, I want to understand why certain fundamental metrics are missing for a ticker, so that I can distinguish between "data not available from provider" and "data not fetched."
Acceptance Criteria
- WHEN the FMP_Provider receives an HTTP 402 response for a supplementary endpoint, THE FMP_Provider SHALL record the endpoint name and the reason "requires paid plan" in the response metadata.
- THE fundamentals API endpoint SHALL include a field listing which data fields are unavailable and the corresponding reason for each.
- WHEN a fundamental metric value is null and a corresponding unavailability reason exists, THE Fundamentals_Panel SHALL display the reason text (e.g., "Requires paid plan") instead of a dash character.
- WHEN a fundamental metric value is null and no unavailability reason exists, THE Fundamentals_Panel SHALL display a dash character as the placeholder.
Requirement 4: Fundamentals Drill-Down UI
User Story: As a user, I want to drill into the fundamentals data to see additional detail and data source information, so that I can better assess the fundamental metrics.
Acceptance Criteria
- THE Fundamentals_Panel SHALL display a clickable expand/collapse toggle below the summary metrics.
- WHEN the user expands the Detail_Section, THE Fundamentals_Panel SHALL display the data source name, the fetch timestamp, and any unavailability reasons for missing fields.
- WHEN the user collapses the Detail_Section, THE Fundamentals_Panel SHALL hide the detail information without removing the summary metrics.
- THE Detail_Section SHALL default to the collapsed state on initial render.
Requirement 5: Chart Zoom Capability
User Story: As a user, I want to zoom in and out on the candlestick chart, so that I can examine specific time periods in detail or see the full price history.
Acceptance Criteria
- WHEN the user scrolls the mouse wheel over the Chart_Component, THE Chart_Component SHALL zoom in or out by adjusting the visible date range.
- WHEN the user zooms in, THE Chart_Component SHALL increase the candle width and reduce the number of visible bars proportionally.
- WHEN the user zooms out, THE Chart_Component SHALL decrease the candle width and increase the number of visible bars proportionally.
- WHEN the chart is zoomed in, THE Chart_Component SHALL allow the user to pan left and right by clicking and dragging horizontally.
- THE Chart_Component SHALL constrain zoom limits so that the minimum visible range is 10 bars and the maximum visible range is the full dataset length.
- THE Chart_Component SHALL re-render S/R overlays correctly at every zoom level.
Requirement 6: Chart Crosshair
User Story: As a user, I want a crosshair overlay on the chart that tracks my cursor, so that I can precisely read price and date values at any point.
Acceptance Criteria
- WHEN the user moves the cursor over the Chart_Component, THE Chart_Component SHALL draw a vertical line at the cursor x-position spanning the full chart height.
- WHEN the user moves the cursor over the Chart_Component, THE Chart_Component SHALL draw a horizontal line at the cursor y-position spanning the full chart width.
- THE Chart_Component SHALL display the corresponding price value as a label on the y-axis at the horizontal crosshair position.
- THE Chart_Component SHALL display the corresponding date value as a label on the x-axis at the vertical crosshair position.
- WHEN the cursor leaves the Chart_Component, THE Chart_Component SHALL remove the crosshair lines and labels.
Requirement 7: S/R Level Clustering
User Story: As a user, I want nearby S/R levels to be clustered into zones, so that the chart is less cluttered and I can focus on the most significant price areas.
Acceptance Criteria
- THE SR_Service SHALL accept a configurable clustering tolerance parameter that defines the maximum price distance (as a percentage) for grouping levels into a single SR_Zone.
- WHEN two or more S/R levels fall within the clustering tolerance of each other, THE SR_Service SHALL merge those levels into a single SR_Zone with a price range (low bound, high bound) and an aggregated strength score.
- THE SR_Service SHALL compute the aggregated strength of an SR_Zone as the sum of constituent level strengths, capped at 100.
- THE SR_Service SHALL tag each SR_Zone as "support" or "resistance" based on the zone midpoint relative to the current price.
Requirement 8: S/R Zone Filtering
User Story: As a user, I want to see only the strongest S/R zones on the chart, so that I can focus on the most significant price areas.
Acceptance Criteria
- THE S/R API endpoint SHALL accept an optional parameter to limit the number of returned zones.
- WHEN a zone limit is specified, THE SR_Service SHALL return only the zones with the highest aggregated strength scores, up to the specified limit.
- THE Dashboard SHALL default to displaying a maximum of 6 SR_Zones on the chart.
Requirement 9: S/R Zone Chart Rendering
User Story: As a user, I want S/R zones displayed as shaded areas on the chart instead of individual lines, so that I can visually identify price ranges of significance.
Acceptance Criteria
- THE Chart_Component SHALL render each SR_Zone as a semi-transparent shaded rectangle spanning the zone price range (low bound to high bound) across the full chart width.
- THE Chart_Component SHALL use green shading for support zones and red shading for resistance zones.
- THE Chart_Component SHALL display a label for each SR_Zone showing the zone midpoint price and strength score.
- THE Chart_Component SHALL render SR_Zones behind the candlestick bodies so that candles remain fully visible.
- WHEN the chart is zoomed, THE Chart_Component SHALL re-render SR_Zones at the correct vertical positions for the current price scale.