3.2 KiB
3.2 KiB
Tasks
1. Add quality score helper function
- 1.1 Create
_compute_quality_score(rr, strength, distance, entry_price, *, w_rr=0.35, w_strength=0.35, w_proximity=0.30, rr_cap=10.0) -> floatfunction inapp/services/rr_scanner_service.pythat computes a weighted sum of normalized R:R, normalized strength, and normalized proximity - 1.2 Implement normalization:
norm_rr = min(rr / rr_cap, 1.0),norm_strength = strength / 100.0,norm_proximity = 1.0 - min(distance / entry_price, 1.0) - 1.3 Return
w_rr * norm_rr + w_strength * norm_strength + w_proximity * norm_proximity
2. Replace long setup selection logic
- 2.1 In
scan_ticker, replace the long setup loop that tracksbest_rr/best_targetwith a loop that computesquality_scorefor each candidate via_compute_quality_scoreand tracksbest_quality/best_candidate_rr/best_candidate_target - 2.2 Keep the
rr >= rr_thresholdfilter — only candidates meeting the threshold are scored - 2.3 Store the selected candidate's actual R:R ratio (not the quality score) in
TradeSetup.rr_ratio
3. Replace short setup selection logic
- 3.1 Apply the same quality-score selection change to the short setup loop, mirroring the long setup changes
- 3.2 Ensure distance is computed as
entry_price - lv.price_levelfor short candidates
4. Write unit tests for _compute_quality_score
- 4.1 Create
tests/unit/test_rr_scanner_quality_score.pywith tests for known inputs verifying the formula output - 4.2 Test edge cases: strength=0, strength=100, distance=0, rr at cap, rr above cap
- 4.3 Test that all normalized components stay in 0–1 range
5. Write exploratory bug-condition tests (run on unfixed code to confirm bug)
- 5.1 [PBT-exploration] Create
tests/unit/test_rr_scanner_bug_exploration.pywith a property test that generates multiple S/R levels with varying strengths and distances, callsscan_ticker, and asserts the selected target is NOT always the most distant level — expected to FAIL on unfixed code, confirming the bug
6. Write fix-checking tests
- 6.1 [PBT-fix] Create
tests/unit/test_rr_scanner_fix_check.pywith a property test that generates multiple candidate S/R levels meeting the R:R threshold, callsscan_tickeron fixed code, and asserts the selected target has the highest quality score among all candidates
7. Write preservation tests
- 7.1 [PBT-preservation] Create
tests/unit/test_rr_scanner_preservation.pywith a property test that generates zero-candidate and single-candidate scenarios and asserts the fixed function produces the same output as the original (no setup for zero candidates, same setup for single candidate) - 7.2 Add unit test verifying that when no S/R levels exist, no setup is produced (unchanged)
- 7.3 Add unit test verifying that when only one candidate meets threshold, it is selected (unchanged)
- 7.4 Add unit test verifying
get_trade_setupssorting is unchanged (R:R desc, composite desc)
8. Integration test
- 8.1 Add integration test in
tests/unit/test_rr_scanner_integration.pythat mocks DB with multiple S/R levels of varying quality, runsscan_ticker, and verifies the full flow: quality-based selection, correct TradeSetup fields, database persistence