Files
signal-platform/.kiro/specs/score-transparency-trade-overlay/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

8.1 KiB

Implementation Plan: Score Transparency & Trade Overlay

Overview

Extend the scoring API and UI to expose full score breakdowns (sub-scores, weights, raw values, formulas) for each dimension and the composite score. Add trade setup chart overlays (entry, stop-loss, take-profit zones) to the candlestick chart on the ticker detail page. Backend changes are in Python/FastAPI, frontend in React/TypeScript.

Tasks

  • 1. Add score breakdown schemas and refactor scoring service

    • 1.1 Add breakdown Pydantic models to app/schemas/score.py

      • Add SubScoreResponse, ScoreBreakdownResponse, CompositeBreakdownResponse models
      • Extend DimensionScoreResponse with optional breakdown: ScoreBreakdownResponse field
      • Extend ScoreResponse with optional composite_breakdown: CompositeBreakdownResponse field
      • Requirements: 1.1, 1.7
    • 1.2 Refactor _compute_technical_score in app/services/scoring_service.py to return breakdown

      • Change return type to tuple[float | None, ScoreBreakdown | None]
      • Return sub-scores for ADX (weight 0.4), EMA (weight 0.3), RSI (weight 0.3) with raw indicator values
      • Include formula description string
      • Add unavailable sub-scores with reason when data is insufficient
      • Requirements: 1.2, 1.8
    • 1.3 Refactor _compute_sentiment_score to return breakdown

      • Return record count, decay rate, lookback window, and weighted average formula parameters as sub-score metadata
      • Requirements: 1.3, 1.8
    • 1.4 Refactor _compute_fundamental_score to return breakdown

      • Return PE Ratio, Revenue Growth, Earnings Surprise sub-scores with raw metric values and normalization formula
      • Requirements: 1.4, 1.8
    • 1.5 Refactor _compute_momentum_score to return breakdown

      • Return 5-day ROC (weight 0.5) and 20-day ROC (weight 0.5) sub-scores with raw ROC percentages
      • Requirements: 1.5, 1.8
    • 1.6 Refactor _compute_sr_quality_score to return breakdown

      • Return strong count (max 40 pts), proximity (max 30 pts), avg strength (max 30 pts) sub-scores with input values
      • Requirements: 1.6, 1.8
    • 1.7 Update get_score to assemble composite breakdown and pass dimension breakdowns through

      • Build CompositeBreakdownResponse with original weights, available/missing dimensions, re-normalized weights, and formula
      • Wire dimension breakdowns into the response dict
      • Requirements: 1.7, 3.2
    • 1.8 Update read_score in app/routers/scores.py to populate breakdown fields from service response

      • Map breakdown dicts from service into the new Pydantic response models
      • Requirements: 1.1
    • * 1.9 Write property test: Dimension breakdown contains correct sub-scores (Property 1)

      • Property 1: Dimension breakdown contains correct sub-scores
      • Use hypothesis to generate valid input data for each dimension type
      • Verify returned breakdown has expected sub-score names, correct weights, and non-null raw values
      • Validates: Requirements 1.1, 1.2, 1.3, 1.4, 1.5, 1.6
    • * 1.10 Write property test: Composite re-normalization correctness (Property 2)

      • Property 2: Composite re-normalization correctness
      • Use hypothesis to generate random subsets of dimensions with random weights
      • Verify re-normalized weights sum to 1.0 and each equals original_weight / sum(available_weights)
      • Validates: Requirements 1.7, 3.2
  • 2. Checkpoint — Backend score breakdown

    • Ensure all tests pass, ask the user if questions arise.
  • 3. Add frontend types and DimensionBreakdownPanel component

    • 3.1 Extend frontend types in frontend/src/lib/types.ts

      • Add SubScore, ScoreBreakdown, CompositeBreakdown interfaces
      • Extend DimensionScoreDetail with optional breakdown field
      • Extend ScoreResponse with optional composite_breakdown field
      • Requirements: 1.1, 1.7
    • 3.2 Create frontend/src/components/ticker/DimensionBreakdownPanel.tsx

      • Expandable panel showing sub-score rows: name, score value, weight badge, raw input value
      • Formula description text section
      • Muted "unavailable" labels for missing sub-scores with reason
      • Requirements: 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8
    • 3.3 Modify frontend/src/components/ui/ScoreCard.tsx for composite transparency

      • Make each dimension row expandable, rendering DimensionBreakdownPanel when expanded
      • Show dimension weight next to each bar
      • Show missing dimensions with muted styling and "redistributed" indicator
      • Add tooltip/inline text explaining weighted average with re-normalization
      • Requirements: 3.1, 3.2, 3.3
    • * 3.4 Write property test: Dimension breakdown UI rendering completeness (Property 3)

      • Property 3: Dimension breakdown UI rendering completeness
      • Use fast-check to generate random ScoreBreakdown objects with 1-5 sub-scores
      • Render DimensionBreakdownPanel and verify DOM contains exactly N sub-score rows with all required fields
      • Validates: Requirements 2.1
    • * 3.5 Write property test: Composite weight display (Property 4)

      • Property 4: Composite weight display
      • Use fast-check to generate random score responses with random available/missing dimension combinations
      • Render ScoreCard and verify weight labels present and missing dimensions visually distinct
      • Validates: Requirements 3.1, 3.2
  • 4. Checkpoint — Score transparency UI

    • Ensure all tests pass, ask the user if questions arise.
  • 5. Add trade setup chart overlay

    • 5.1 Modify frontend/src/components/charts/CandlestickChart.tsx to accept and render trade overlay

      • Add optional tradeSetup?: TradeSetup prop
      • Draw entry price as dashed horizontal line (blue/white) spanning full chart width
      • Draw stop-loss zone as red semi-transparent rectangle between entry and stop-loss
      • Draw take-profit zone as green semi-transparent rectangle between entry and target
      • Include entry, stop-loss, target in y-axis price range calculation
      • Add hover tooltip showing direction, entry, stop, target, R:R ratio
      • Render no overlay when prop is absent
      • Requirements: 4.1, 4.2, 4.3, 4.4, 4.5, 4.6
    • * 5.2 Write property test: Trade overlay y-axis range includes all trade levels (Property 5)

      • Property 5: Trade overlay y-axis range includes all trade levels
      • Use fast-check to generate random OHLCV data and random trade setups
      • Extract the y-axis range computation logic and verify all three trade levels fall within [lo, hi]
      • Validates: Requirements 4.4
  • 6. Integrate trade setup data on ticker detail page

    • 6.1 Update frontend/src/hooks/useTickerDetail.ts to include trades data

      • Add trades query to the hook return value
      • Requirements: 5.1
    • 6.2 Modify frontend/src/pages/TickerDetailPage.tsx to wire trade overlay

      • Fetch trade setups via useTrades(), filter for current symbol, pick latest by detected_at
      • Pass tradeSetup prop to CandlestickChart
      • Render trade setup summary card below chart (direction, entry, stop, target, R:R)
      • Handle trades API failure gracefully — chart renders without overlay, error logged
      • Requirements: 5.1, 5.2, 5.3, 5.4, 5.5
    • * 6.3 Write property test: Trade setup selection picks latest matching symbol (Property 6)

      • Property 6: Trade setup selection picks latest matching symbol
      • Use fast-check to generate random lists of trade setups with random symbols and timestamps
      • Verify selection logic returns the latest setup for the target symbol, or null if no match
      • Validates: Requirements 5.1, 5.5
  • 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
  • Each task references specific requirements for traceability
  • Property tests use hypothesis (Python) and fast-check (TypeScript) with minimum 100 iterations
  • No new database tables — breakdowns are computed on-the-fly from existing data
  • Trade overlay uses the existing lightweight-charts rendering pipeline, no new library needed