8.2 KiB
Requirements Document
Introduction
This specification covers three UX improvements to the stock signal platform: (1) balanced support/resistance zone selection that ensures both zone types are represented on the chart, with a filtered levels table; (2) a Trade Scanner page enhanced with an explainer banner and detailed risk/reward analysis columns; and (3) a Rankings page weights form that replaces decimal number inputs with intuitive range sliders and automatic normalization.
Glossary
- SR_Service: The backend service (
sr_service.py) containingcluster_sr_zones()that clusters, scores, and selects S/R zones. - SR_API: The FastAPI router endpoint (
/sr-levels/{symbol}) that returns S/R levels and zones for a ticker. - SRLevelResponse: The Pydantic response model returned by the SR_API containing levels, zones, and metadata.
- Zone_Selector: The interleave-based selection logic within
cluster_sr_zones()that picks zones from support and resistance pools alternately. - Visible_Levels: The subset of all detected S/R levels whose price falls within the bounds of at least one returned zone.
- Ticker_Detail_Page: The frontend page (
TickerDetailPage.tsx) displaying chart, scores, sentiment, fundamentals, and S/R data for a single ticker. - SR_Levels_Table: The HTML table on the Ticker_Detail_Page that lists individual S/R levels sorted by strength.
- Scanner_Page: The frontend page (
ScannerPage.tsx) displaying trade setups with filtering and sorting. - Trade_Table: The table component (
TradeTable.tsx) rendering trade setup rows on the Scanner_Page. - Explainer_Banner: A static informational banner at the top of the Scanner_Page describing what the scanner does.
- Trade_Analysis: A set of computed fields (risk amount, reward amount, stop percentage, target percentage) derived client-side from each trade setup row.
- Rankings_Page: The frontend page displaying ticker rankings with configurable scoring weights.
- Weights_Form: The form component (
WeightsForm.tsx) on the Rankings_Page for adjusting scoring dimension weights. - Weight_Slider: A range input (0–100) replacing the current decimal number input for each scoring weight dimension.
- Normalization: The process of dividing each slider value by the sum of all slider values to produce decimal weights that sum to 1.0.
Requirements
Requirement 1: Balanced Zone Selection
User Story: As a trader, I want the S/R zone selection to include both support and resistance zones when both exist, so that I get a balanced view of key price levels regardless of the ticker's trend direction.
Acceptance Criteria
- WHEN both support and resistance zones exist and
max_zonesis 2 or greater, THE Zone_Selector SHALL return at least one support zone and at least one resistance zone. - THE Zone_Selector SHALL select zones by alternating picks from the support pool and the resistance pool, each sorted by strength descending, until
max_zonesis reached. - WHEN one pool is exhausted before
max_zonesis reached, THE Zone_Selector SHALL fill the remaining slots from the other pool in strength-descending order. - THE Zone_Selector SHALL sort the final selected zones by strength descending before returning them.
- WHEN no S/R levels are provided, THE SR_Service SHALL return an empty zones list.
- WHEN
max_zonesis zero or negative, THE SR_Service SHALL return an empty zones list.
Requirement 2: Visible Levels Filtering
User Story: As a trader, I want the API to provide a filtered list of S/R levels that correspond to the zones shown on the chart, so that the levels table only shows relevant data.
Acceptance Criteria
- THE SRLevelResponse SHALL include a
visible_levelsfield containing only the S/R levels whose price falls within the bounds of at least one returned zone. - THE
visible_levelsfield SHALL be a subset of thelevelsfield in the same response. - THE SRLevelResponse SHALL continue to include the full
levelsfield for backward compatibility. - WHEN the zones list is empty, THE SRLevelResponse SHALL return an empty
visible_levelslist.
Requirement 3: S/R Levels Table Filtering
User Story: As a trader, I want the S/R levels table below the chart to show only levels that correspond to zones visible on the chart, so that the table and chart are consistent.
Acceptance Criteria
- THE SR_Levels_Table SHALL render levels from the
visible_levelsfield of the API response instead of the fulllevelsfield. - THE SR_Levels_Table SHALL sort displayed levels by strength descending.
- THE SR_Levels_Table SHALL color-code each level row green for support and red for resistance.
- WHEN
visible_levelsis empty, THE Ticker_Detail_Page SHALL hide the SR_Levels_Table section.
Requirement 4: Trade Scanner Explainer Banner
User Story: As a user, I want to see a brief explanation of what the Trade Scanner does when I visit the page, so that I understand the purpose and methodology of the displayed trade setups.
Acceptance Criteria
- THE Scanner_Page SHALL display an Explainer_Banner above the filter controls.
- THE Explainer_Banner SHALL contain static text describing that the scanner identifies asymmetric risk-reward trade setups using S/R levels as targets and ATR-based stops.
- THE Explainer_Banner SHALL be visible on initial page load without requiring user interaction.
Requirement 5: Trade Scanner R:R Analysis Columns
User Story: As a trader, I want to see detailed risk/reward analysis data (risk amount, reward amount, percentage distances, and color-coded R:R ratio) for each trade setup, so that I can evaluate and compare setups at a glance.
Acceptance Criteria
- THE Trade_Table SHALL display the following additional columns: Risk
(absolute risk amount), Reward(absolute reward amount), % to Stop (percentage distance from entry to stop-loss), and % to Target (percentage distance from entry to target). - THE Trade_Analysis risk_amount SHALL be computed as the absolute difference between entry_price and stop_loss.
- THE Trade_Analysis reward_amount SHALL be computed as the absolute difference between target and entry_price.
- THE Trade_Analysis stop_pct SHALL be computed as risk_amount divided by entry_price multiplied by 100.
- THE Trade_Analysis target_pct SHALL be computed as reward_amount divided by entry_price multiplied by 100.
- WHEN the R:R ratio is 3.0 or greater, THE Trade_Table SHALL display the R:R value with green color coding.
- WHEN the R:R ratio is 2.0 or greater but less than 3.0, THE Trade_Table SHALL display the R:R value with amber color coding.
- WHEN the R:R ratio is less than 2.0, THE Trade_Table SHALL display the R:R value with red color coding.
Requirement 6: Rankings Weight Slider Input
User Story: As a user, I want to adjust scoring weights using range sliders with whole-number values instead of typing decimal numbers, so that the input is intuitive and less error-prone.
Acceptance Criteria
- THE Weights_Form SHALL render each weight dimension as a Weight_Slider with a range of 0 to 100 and a step of 1.
- THE Weights_Form SHALL display the current whole-number value next to each Weight_Slider.
- WHEN the Weights_Form receives API weight values (decimals between 0 and 1), THE Weights_Form SHALL convert each value to the 0–100 scale by multiplying by 100 and rounding to the nearest integer.
- THE Weights_Form SHALL display a humanized label for each weight dimension by replacing underscores with spaces.
Requirement 7: Weight Normalization on Submit
User Story: As a user, I want my slider values to be automatically normalized to valid decimal weights when I submit, so that I don't need to manually ensure they sum to 1.0.
Acceptance Criteria
- WHEN the user submits the Weights_Form and at least one slider value is greater than zero, THE Weights_Form SHALL normalize each slider value by dividing it by the sum of all slider values.
- WHEN all slider values are zero, THE Weights_Form SHALL disable the submit button.
- WHEN all slider values are zero, THE Weights_Form SHALL display a validation message stating that at least one weight must be greater than zero.
- THE Weights_Form SHALL send the normalized decimal weights to the API using the existing mutation hook.