Files
signal-platform/.kiro/specs/ux-improvements/tasks.md
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

7.9 KiB
Raw Blame History

Implementation Plan: UX Improvements

Overview

Implement four UX improvements: balanced S/R zone selection in the backend, visible levels filtering (backend + frontend), Trade Scanner explainer banner and R:R analysis columns, and Rankings weight slider form. Backend changes use Python (FastAPI/Pydantic), frontend changes use TypeScript (React).

Tasks

  • 1. Implement balanced S/R zone selection in cluster_sr_zones()

    • 1.1 Refactor cluster_sr_zones() to use interleave-based balanced selection

      • In app/services/sr_service.py, after clustering and computing zones, split zones into support_zones and resistance_zones pools sorted by strength descending
      • Implement round-robin interleave picking: alternate strongest from each pool until max_zones is reached or both pools exhausted
      • If one pool is exhausted, fill remaining slots from the other pool
      • Sort final selected zones by strength descending before returning
      • Requirements: 1.1, 1.2, 1.3, 1.4, 1.5, 1.6
    • * 1.2 Write property test: balanced zone selection guarantees both types

      • Property 1: Balanced zone selection guarantees both types
      • Validates: Requirement 1.1
      • In tests/unit/test_cluster_sr_zones.py, use Hypothesis to generate sets of levels with at least one support and one resistance zone, verify output contains at least one of each type when max_zones >= 2
    • * 1.3 Write property test: interleave selection correctness

      • Property 2: Interleave selection correctness
      • Validates: Requirements 1.2, 1.3
      • Verify the selected zones match the expected round-robin interleave from support and resistance pools
    • * 1.4 Write property test: zone output sorted by strength

      • Property 3: Zone output is sorted by strength
      • Validates: Requirement 1.4
      • For any input, verify returned zones are sorted by strength descending
    • 1.5 Update existing unit tests for balanced selection behavior

      • Update tests/unit/test_cluster_sr_zones.py to add tests for: mixed support/resistance input produces balanced output, all-support input fills from support only, all-resistance input fills from resistance only, single zone edge case
      • Requirements: 1.1, 1.2, 1.3, 1.5, 1.6
  • 2. Implement visible_levels filtering in backend

    • 2.1 Add visible_levels field to SRLevelResponse schema

      • In app/schemas/sr_level.py, add visible_levels: list[SRLevelResult] = [] to SRLevelResponse
      • Requirements: 2.1, 2.3
    • 2.2 Compute visible_levels in the SR levels router

      • In app/routers/sr_levels.py, after computing zones, filter level_results to only those whose price_level falls within the [low, high] range of at least one zone
      • Set the filtered list as visible_levels on the SRLevelResponse
      • When zones list is empty, visible_levels should be empty
      • Requirements: 2.1, 2.2, 2.4
    • * 2.3 Write property test: visible levels subset within zone bounds

      • Property 4: Visible levels are a subset within zone bounds
      • Validates: Requirements 2.1, 2.2
      • Verify every entry in visible_levels appears in levels and has a price within at least one zone's [low, high] range
    • 2.4 Update router unit tests for visible_levels

      • In tests/unit/test_sr_levels_router.py, add tests verifying: visible_levels is present in response, visible_levels contains only levels within zone bounds, visible_levels is empty when zones are empty
      • Requirements: 2.1, 2.2, 2.4
  • 3. Checkpoint - Ensure all backend tests pass

    • Ensure all tests pass, ask the user if questions arise.
  • 4. Update frontend types and S/R levels table filtering

    • 4.1 Add visible_levels to frontend SRLevelResponse type

      • In frontend/src/lib/types.ts, add visible_levels: SRLevel[] to the SRLevelResponse interface
      • Requirements: 2.1
    • 4.2 Update TickerDetailPage to use visible_levels for the S/R table

      • In frontend/src/pages/TickerDetailPage.tsx, change sortedLevels to derive from srLevels.data.visible_levels instead of srLevels.data.levels
      • Keep sorting by strength descending
      • Hide the S/R Levels Table section when visible_levels is empty
      • Maintain existing color coding (green for support, red for resistance)
      • Requirements: 3.1, 3.2, 3.3, 3.4
  • 5. Add Trade Scanner explainer banner and R:R analysis columns

    • 5.1 Add explainer banner to ScannerPage

      • In frontend/src/pages/ScannerPage.tsx, add a static informational banner above the filter controls
      • Banner text: describe that the scanner identifies asymmetric risk-reward trade setups using S/R levels as targets and ATR-based stops
      • Banner should be visible on initial page load without user interaction
      • Requirements: 4.1, 4.2, 4.3
    • 5.2 Add R:R analysis columns to TradeTable

      • In frontend/src/components/scanner/TradeTable.tsx, add computed columns: Risk (`|entry_price - stop_loss|`), Reward (|target - entry_price|), % to Stop (risk / entry * 100), % to Target (reward / entry * 100)
      • Color-code the existing R:R ratio column: green for ≥ 3.0, amber for ≥ 2.0, red for < 2.0
      • Update the SortColumn type and columns array to include the new columns
      • Update sortTrades in ScannerPage.tsx to handle sorting by new computed columns
      • Requirements: 5.1, 5.2, 5.3, 5.4, 5.5, 5.6, 5.7, 5.8
    • * 5.3 Write property test: trade analysis computation correctness

      • Property 5: Trade analysis computation correctness
      • Validates: Requirements 5.2, 5.3, 5.4, 5.5
      • Using fast-check, for any trade with positive entry_price, stop_loss, and target, verify risk_amount == |entry_price - stop_loss|, reward_amount == |target - entry_price|, stop_pct == risk_amount / entry_price * 100, target_pct == reward_amount / entry_price * 100
  • 6. Convert Rankings weight inputs to sliders

    • 6.1 Replace number inputs with range sliders in WeightsForm

      • In frontend/src/components/rankings/WeightsForm.tsx, replace <input type="number"> with <input type="range" min={0} max={100} step={1}>
      • On mount, convert API decimal weights to 0100 scale: Math.round(w * 100)
      • Display current whole-number value next to each slider
      • Show humanized label (replace underscores with spaces)
      • Requirements: 6.1, 6.2, 6.3, 6.4
    • 6.2 Implement weight normalization on submit

      • On submit, normalize slider values: divide each by the sum of all values
      • Disable submit button when all sliders are zero
      • Show validation message "At least one weight must be greater than zero" when all are zero
      • Send normalized decimal weights via existing useUpdateWeights mutation
      • Requirements: 7.1, 7.2, 7.3, 7.4
    • * 6.3 Write property test: weight conversion round-trip

      • Property 6: Weight conversion round-trip
      • Validates: Requirement 6.3
      • Using fast-check, verify that converting decimal weights to slider scale and normalizing back preserves relative proportions within floating-point tolerance
    • * 6.4 Write property test: normalized weights sum to one

      • Property 7: Normalized weights sum to one
      • Validates: Requirement 7.1
      • Using fast-check, for any set of slider values (integers 0100) where at least one > 0, verify normalized weights sum to 1.0 within ±1e-9
  • 7. Final checkpoint - Ensure all tests pass

    • Ensure all tests pass, ask the user if questions arise.

Notes

  • Tasks marked with * are optional and can be skipped for faster MVP
  • Backend uses Python (Hypothesis for property tests), frontend uses TypeScript/React (fast-check for property tests)
  • Each task references specific requirements for traceability
  • Checkpoints ensure incremental validation after backend and full implementation phases
  • Property tests validate universal correctness properties from the design document