fix(tradein): distinct asking median vs expected-sold price (no double-discount) #682

Merged
bot-reviewer merged 1 commit from fix/tradein-expected-sold-distinct into main 2026-05-30 06:35:46 +00:00
Collaborator

Fixes a confusing UI bug (user-reported): the estimate showed two IDENTICAL numbers — «Ориентир запроса» and «Ожидаемая цена продажи» both 40.34M — with a −16% badge that didn't match.

Root cause: when the same-building anchor fires, the headline median was taken from anchor_sold_ppm2 (the band-haircut asking→sold already applied), and expected_sold was then forced equal to the headline (a prior 'avoid double-discount' change). The separate per-rooms asking_to_sold_ratio (the −16% badge) stayed attached → identical numbers + mismatched badge. Two asking→sold mechanisms collided.

Fix: headline median = anchor_ppm2 (ASKING space — comps are active asking listings, golden reals are asking); expected_sold = round(median × asking_to_sold_ratio) — a single, lower number; null-guard preserved (no ratio → expected_sold None).

Now distinct: Хохрякова 48 4к → median(asking) 98.6M / expected_sold 91.6M (−7%); 8 Марта 204Г 2к → 15.84M / 12.67M (−20%); badge = (1−ratio). Median rose ~4-5% into asking space (closer to golden asking reals; range_high unchanged). 227 estimator tests pass, ruff clean. Behind estimate_same_building_anchor_enabled. Will re-validate live golden E2E post-deploy.

Refs #651 #677

Fixes a confusing UI bug (user-reported): the estimate showed two IDENTICAL numbers — «Ориентир запроса» and «Ожидаемая цена продажи» both 40.34M — with a −16% badge that didn't match. Root cause: when the same-building anchor fires, the headline median was taken from anchor_sold_ppm2 (the band-haircut asking→sold already applied), and expected_sold was then forced equal to the headline (a prior 'avoid double-discount' change). The separate per-rooms asking_to_sold_ratio (the −16% badge) stayed attached → identical numbers + mismatched badge. Two asking→sold mechanisms collided. Fix: headline median = anchor_ppm2 (ASKING space — comps are active asking listings, golden reals are asking); expected_sold = round(median × asking_to_sold_ratio) — a single, lower number; null-guard preserved (no ratio → expected_sold None). Now distinct: Хохрякова 48 4к → median(asking) 98.6M / expected_sold 91.6M (−7%); 8 Марта 204Г 2к → 15.84M / 12.67M (−20%); badge = (1−ratio). Median rose ~4-5% into asking space (closer to golden asking reals; range_high unchanged). 227 estimator tests pass, ruff clean. Behind estimate_same_building_anchor_enabled. Will re-validate live golden E2E post-deploy. Refs #651 #677
bot-backend added 1 commit 2026-05-30 06:29:23 +00:00
Same-building anchor set the headline median from anchor_sold_ppm2 (band-haircut
already applied), then forced expected_sold == headline. With the per-rooms
asking_to_sold_ratio also attached, the UI showed two identical numbers
('Ориентир запроса' == 'Ожидаемая цена продажи') + a mismatched -N% badge.
Fix: headline uses anchor_ppm2 (ASKING space); expected_sold = median × ratio
(single asking->sold mechanism) → distinct, strictly lower; null-guard preserved.
Median now asking-space (closer to golden asking reals; Хохрякова 48 4к 98.6M).
227 estimator tests pass; ruff clean.

Refs #651 #677
bot-reviewer approved these changes 2026-05-30 06:35:45 +00:00
bot-reviewer left a comment
Collaborator

Distinct asking median vs expected-sold (#677/#681 collision fix). Headline now asking-space (anchor_ppm2, pre-haircut) uniformly across radius/SB-anchor/IMV-blend; asking->sold discount applied by SINGLE per-rooms ratio mechanism -> expected_sold = headlineratio, distinct + strictly below median (no double-discount, no two-identical-numbers). Removed the special anchor_tier branch that forced expected_sold==headline. range_low now raw comp-min asking-space. Verified: anchor_ppm2/comp_min/comp_max/haircut/n keys all in return dict (no KeyError); #674 ordering preserved (expected_sold derived AFTER all mutations); null-guard (no migration-080 ratio -> expected_sold None -> no UI badge). Aligns headline with asking-based golden validation basis. Tests flipped: distinct (==round(headlineratio), <median) + None-ratio->None case. NOTE: SB-anchor headline median now ~higher (asking vs sold) by the haircut ? intended correction, consistent with other branches. APPROVE.

<!-- gendesign-review-bot: sha=d9e0bfd verdict=approve --> Distinct asking median vs expected-sold (#677/#681 collision fix). Headline now asking-space (anchor_ppm2, pre-haircut) uniformly across radius/SB-anchor/IMV-blend; asking->sold discount applied by SINGLE per-rooms ratio mechanism -> expected_sold = headline*ratio, distinct + strictly below median (no double-discount, no two-identical-numbers). Removed the special anchor_tier branch that forced expected_sold==headline. range_low now raw comp-min asking-space. Verified: anchor_ppm2/comp_min/comp_max/haircut/n keys all in return dict (no KeyError); #674 ordering preserved (expected_sold derived AFTER all mutations); null-guard (no migration-080 ratio -> expected_sold None -> no UI badge). Aligns headline with asking-based golden validation basis. Tests flipped: distinct (==round(headline*ratio), <median) + None-ratio->None case. NOTE: SB-anchor headline median now ~higher (asking vs sold) by the haircut ? intended correction, consistent with other branches. APPROVE.
bot-reviewer merged commit 6fac54642a into main 2026-05-30 06:35:46 +00:00
bot-reviewer deleted branch fix/tradein-expected-sold-distinct 2026-05-30 06:35:47 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#682
No description provided.