major update
This commit is contained in:
142
.kiro/specs/score-transparency-trade-overlay/tasks.md
Normal file
142
.kiro/specs/score-transparency-trade-overlay/tasks.md
Normal file
@@ -0,0 +1,142 @@
|
||||
# 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
|
||||
|
||||
- [x] 1. Add score breakdown schemas and refactor scoring service
|
||||
- [x] 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_
|
||||
|
||||
- [x] 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_
|
||||
|
||||
- [x] 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_
|
||||
|
||||
- [x] 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_
|
||||
|
||||
- [x] 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_
|
||||
|
||||
- [x] 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_
|
||||
|
||||
- [x] 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_
|
||||
|
||||
- [x] 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**
|
||||
|
||||
- [x] 2. Checkpoint — Backend score breakdown
|
||||
- Ensure all tests pass, ask the user if questions arise.
|
||||
|
||||
- [x] 3. Add frontend types and DimensionBreakdownPanel component
|
||||
- [x] 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_
|
||||
|
||||
- [x] 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_
|
||||
|
||||
- [x] 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**
|
||||
|
||||
- [x] 4. Checkpoint — Score transparency UI
|
||||
- Ensure all tests pass, ask the user if questions arise.
|
||||
|
||||
- [x] 5. Add trade setup chart overlay
|
||||
- [x] 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**
|
||||
|
||||
- [x] 6. Integrate trade setup data on ticker detail page
|
||||
- [x] 6.1 Update `frontend/src/hooks/useTickerDetail.ts` to include trades data
|
||||
- Add trades query to the hook return value
|
||||
- _Requirements: 5.1_
|
||||
|
||||
- [x] 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**
|
||||
|
||||
- [x] 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
|
||||
Reference in New Issue
Block a user