Files
Dennis Thiessen 181cfe6588
Some checks failed
Deploy / lint (push) Failing after 8s
Deploy / test (push) Has been skipped
Deploy / deploy (push) Has been skipped
major update
2026-02-27 16:08:09 +01:00

8.2 KiB
Raw Permalink Blame History

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) containing cluster_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 (0100) 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

  1. WHEN both support and resistance zones exist and max_zones is 2 or greater, THE Zone_Selector SHALL return at least one support zone and at least one resistance zone.
  2. THE Zone_Selector SHALL select zones by alternating picks from the support pool and the resistance pool, each sorted by strength descending, until max_zones is reached.
  3. WHEN one pool is exhausted before max_zones is reached, THE Zone_Selector SHALL fill the remaining slots from the other pool in strength-descending order.
  4. THE Zone_Selector SHALL sort the final selected zones by strength descending before returning them.
  5. WHEN no S/R levels are provided, THE SR_Service SHALL return an empty zones list.
  6. WHEN max_zones is 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

  1. THE SRLevelResponse SHALL include a visible_levels field containing only the S/R levels whose price falls within the bounds of at least one returned zone.
  2. THE visible_levels field SHALL be a subset of the levels field in the same response.
  3. THE SRLevelResponse SHALL continue to include the full levels field for backward compatibility.
  4. WHEN the zones list is empty, THE SRLevelResponse SHALL return an empty visible_levels list.

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

  1. THE SR_Levels_Table SHALL render levels from the visible_levels field of the API response instead of the full levels field.
  2. THE SR_Levels_Table SHALL sort displayed levels by strength descending.
  3. THE SR_Levels_Table SHALL color-code each level row green for support and red for resistance.
  4. WHEN visible_levels is 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

  1. THE Scanner_Page SHALL display an Explainer_Banner above the filter controls.
  2. 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.
  3. 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

  1. 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).
  2. THE Trade_Analysis risk_amount SHALL be computed as the absolute difference between entry_price and stop_loss.
  3. THE Trade_Analysis reward_amount SHALL be computed as the absolute difference between target and entry_price.
  4. THE Trade_Analysis stop_pct SHALL be computed as risk_amount divided by entry_price multiplied by 100.
  5. THE Trade_Analysis target_pct SHALL be computed as reward_amount divided by entry_price multiplied by 100.
  6. WHEN the R:R ratio is 3.0 or greater, THE Trade_Table SHALL display the R:R value with green color coding.
  7. 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.
  8. 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

  1. THE Weights_Form SHALL render each weight dimension as a Weight_Slider with a range of 0 to 100 and a step of 1.
  2. THE Weights_Form SHALL display the current whole-number value next to each Weight_Slider.
  3. WHEN the Weights_Form receives API weight values (decimals between 0 and 1), THE Weights_Form SHALL convert each value to the 0100 scale by multiplying by 100 and rounding to the nearest integer.
  4. 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

  1. 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.
  2. WHEN all slider values are zero, THE Weights_Form SHALL disable the submit button.
  3. 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.
  4. THE Weights_Form SHALL send the normalized decimal weights to the API using the existing mutation hook.