feat(forecasting): months-of-inventory (MOI) — discriminating §9.8 metric #1055

Merged
bot-backend merged 1 commit from feat/demand-supply-months-of-inventory into main 2026-06-05 02:37:28 +00:00
Collaborator

What — §9.8 deficit fix: months-of-inventory (MOI)

deficit_index pins to −1.0 for every ЕКБ segment (12mo demand FLOW vs multi-year supply STOCK — L1 open_units = entire unsold pipeline — → log-ratio clamps) → zero discriminating power. The oversupply is partly REAL (ЕКБ new-build glut at key_rate 14.5%), but the metric can't differentiate parcels.

Fix (user-approved: MOI-primary + honest absolute deficit): ADD months_of_inventory (MOI = gross_competing_supply / demand_per_mo) — the real-estate absorption standard — as an additive discriminating companion. deficit_index math kept exactly as-is (honest absolute: −1 = genuinely oversupplied; docstrings clarify it's common at current rates and MOI is the companion). No recalibration/overfit.

Prod ground-truth (h=12, modified code in-container, restored after)

micro MOI (gross) deficit
Уралмаш 42 −1.0
Академический 55 −1.0
Уктус 78 −1.0
Чермет 109 −1.0

MOI discriminates (42→109mo) where deficit is uniformly −1.0.

How

  • months_of_inventory: float | None on DemandSupplyForecast (+as_dict). _gross_supply() extract-method (single source of truth; _project_supply/deficit_index/balance_ratio behavior byte-identical — code-review-verified line-by-line). Guards: no demand→None, no supply→0, no div-by-zero.
  • Surfaced in §22 report: future_market (per-horizon passthrough) + exec_summary (_primary_months_of_inventory mirrors _primary_deficit_index; key_numbers + verdict clause "≈N мес конкурирующего предложения"). Advisory.

Quality

  • code-review APPROVE — verified line-by-line that deficit/projected_supply are byte-identical (the refactor is pure extract-method), MOI uses gross + sound guards, and the discrimination test is genuine (two segments both deficit −1 but MOI 240≠120; fails if MOI sourced from the clamped ratio).
  • 871 forecasting tests pass (+exporters); ruff clean. No analyze/orchestrator touched (Step 3). Refs #952.
## What — §9.8 deficit fix: months-of-inventory (MOI) `deficit_index` pins to **−1.0 for every ЕКБ segment** (12mo demand FLOW vs multi-year supply STOCK — L1 open_units = entire unsold pipeline — → log-ratio clamps) → zero discriminating power. The oversupply is partly REAL (ЕКБ new-build glut at key_rate 14.5%), but the metric can't differentiate parcels. **Fix (user-approved: MOI-primary + honest absolute deficit):** ADD `months_of_inventory` (MOI = gross_competing_supply / demand_per_mo) — the real-estate absorption standard — as an additive **discriminating** companion. `deficit_index` math kept **exactly as-is** (honest absolute: −1 = genuinely oversupplied; docstrings clarify it's common at current rates and MOI is the companion). No recalibration/overfit. ## Prod ground-truth (h=12, modified code in-container, restored after) | micro | MOI (gross) | deficit | |---|---|---| | Уралмаш | 42 | −1.0 | | Академический | 55 | −1.0 | | Уктус | 78 | −1.0 | | Чермет | 109 | −1.0 | MOI **discriminates** (42→109mo) where deficit is uniformly −1.0. ## How - `months_of_inventory: float | None` on `DemandSupplyForecast` (+as_dict). `_gross_supply()` extract-method (single source of truth; `_project_supply`/`deficit_index`/`balance_ratio` behavior **byte-identical** — code-review-verified line-by-line). Guards: no demand→None, no supply→0, no div-by-zero. - Surfaced in §22 report: `future_market` (per-horizon passthrough) + `exec_summary` (`_primary_months_of_inventory` mirrors `_primary_deficit_index`; key_numbers + verdict clause "≈N мес конкурирующего предложения"). Advisory. ## Quality - **code-review APPROVE — verified line-by-line** that deficit/projected_supply are byte-identical (the refactor is pure extract-method), MOI uses gross + sound guards, and the discrimination test is genuine (two segments both deficit −1 but MOI 240≠120; fails if MOI sourced from the clamped ratio). - 871 forecasting tests pass (+exporters); ruff clean. No analyze/orchestrator touched (Step 3). Refs #952.
bot-backend added 1 commit 2026-06-05 02:37:26 +00:00
feat(forecasting): add months-of-inventory (MOI) to §9.8 demand-supply forecast
All checks were successful
Deploy / changes (push) Successful in 6s
Deploy / build-frontend (push) Has been skipped
Deploy / build-backend (push) Successful in 1m21s
Deploy / build-worker (push) Successful in 2m17s
Deploy / deploy (push) Successful in 1m12s
01a74ade7a
deficit_index pins to -1.0 for every ЕКБ segment (12mo demand flow vs multi-year
supply stock → log-ratio clamps) → zero discriminating power, though the oversupply
is partly real. Add MOI (gross competing supply / demand_per_mo), the real-estate
absorption standard, as an additive non-saturating companion that DISCRIMINATES
(Уралмаш 42mo … Чермет 109mo) where deficit cannot. deficit_index math kept exactly
as-is (honest absolute: -1 = genuinely oversupplied); docstrings clarify -1 is common
and MOI is the discriminating companion (no recalibration). _gross_supply extract-method
(single source of truth; _project_supply behavior byte-identical, code-review-verified).
Surface MOI in §22 future_market (passthrough) + exec_summary key_numbers/verdict.
Guards: no demand → None, no supply → 0. Prod: MOI varies 42→109mo, deficit stays -1.
Discrimination test pins MOI separating two segments both at deficit -1. Refs #952.
bot-backend merged commit 01a74ade7a into main 2026-06-05 02:37:28 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
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#1055
No description provided.