Add product_scoring.py: 10 deterministic advisory product scores ∈[0,1] (market_fit/demand/supply_risk/future_competition/price_feasibility/infra_fit/ mortgage_sensitivity/differentiation/commercial/confidence), each derived from already-built forecasting + Site Finder services, graceful-None on thin data, §16-style RU reason per score. supply_risk/future_competition/mortgage_sensitivity inverted (high-bad→low). Weighted overall renormalized over available scores (§9.5 dispatch); commercial/infra degrade to None (not 0). Advisory cap inherited. Pure scorers unit-tested without DB; orchestrator via @patch of all backers. 101 tests.
141 lines
5.1 KiB
Python
141 lines
5.1 KiB
Python
"""Forecasting services — детерминированный форсайт-слой Site Finder v2.
|
||
|
||
#951 (Site Finder v2 / «GG-форсайт», EPIC 7 «Чувствительность к ключевой ставке»).
|
||
|
||
Этот пакет — фундамент data-independent логики прогноза: monthly макро-ряды,
|
||
классификатор режима ставки, лаговые помощники. Всё ДЕТЕРМИНИРОВАННО, БЕЗ LLM.
|
||
|
||
Слои (по PR):
|
||
• macro_series (#951b) — monthly макро-ряд + классификатор режима ставки (X-ось §9.6).
|
||
• sales_series (#951c) — monthly ряд продаж по сегменту (Y-ось §9.6).
|
||
• rate_sensitivity (#951d) — §9.6 чувствительность продаж к key_rate (CORE, ADVISORY).
|
||
• macro_coefficient (#951e) — §9.5 макро-коэффициент (композитный множитель, ADVISORY).
|
||
• demand_normalization (#951f) — §9.4 нормализация спроса под смену режима ставки (ADVISORY).
|
||
• demand_supply_forecast (#952a) — §9.8 центральный движок: спрос (§9.4×§9.5) vs
|
||
предложение (§9.3) по горизонтам → баланс/индекс дефицита (СБОРКА, ADVISORY).
|
||
• what_to_build (#981/952-B) — §9.7 ранкер сетки сегментов по deficit_index
|
||
(прогон #980 per-cell → DESC «что строить»; СБОРКА, ADVISORY).
|
||
• affordability (#981/952-B) — §7.9 MAI: ДЕГРАДИРОВАННЫЙ прокси платёжной
|
||
нагрузки (субсид. ставка, дохода нет → low-confidence; СБОРКА, ADVISORY).
|
||
• scenarios (#984/954-A) — §11 три макро-сценария (conservative/base/
|
||
aggressive) прогоном #952 под тремя конвертами ставки (СБОРКА, ADVISORY).
|
||
• product_scoring (#985/954-B) — §14.2 десять продуктовых скоров ∈ [0,1] (выше=
|
||
лучше) + взвешенный overall (renorm над доступными) + §16 причина на скор;
|
||
сводит #950…#984 + live-стек, graceful-None, ADVISORY.
|
||
|
||
Источники данных:
|
||
• макро — таблица macro_indicator через reader site_finder/macro.py (reuse).
|
||
• продажи — objective_corpus_room_month / objective_lots (см. sales_series).
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from app.services.forecasting.affordability import (
|
||
MortgageAffordabilityIndex,
|
||
compute_affordability,
|
||
)
|
||
from app.services.forecasting.demand_normalization import (
|
||
DemandNormalization,
|
||
compute_demand_normalization,
|
||
normalization_factor,
|
||
)
|
||
from app.services.forecasting.demand_supply_forecast import (
|
||
DemandSupplyForecast,
|
||
compute_demand_supply_forecast,
|
||
hold_last_rate,
|
||
)
|
||
from app.services.forecasting.macro_coefficient import (
|
||
MacroCoefficient,
|
||
assemble_coefficient,
|
||
compute_macro_coefficient,
|
||
f_issuance,
|
||
f_mortgage_rate,
|
||
f_overdue,
|
||
f_rate,
|
||
renormalize_contributions,
|
||
segment_steepness,
|
||
)
|
||
from app.services.forecasting.macro_series import (
|
||
MonthlyMacro,
|
||
classify_regime,
|
||
get_monthly_macro,
|
||
is_confounded_window,
|
||
macro_at_lag,
|
||
)
|
||
from app.services.forecasting.product_scoring import (
|
||
ProductScore,
|
||
ProductScoreCard,
|
||
compute_score_card,
|
||
)
|
||
from app.services.forecasting.rate_sensitivity import (
|
||
RateSensitivity,
|
||
best_lag,
|
||
compute_rate_sensitivity,
|
||
ols_slope_r2,
|
||
shrink,
|
||
)
|
||
from app.services.forecasting.sales_series import (
|
||
SalesSeries,
|
||
SegmentSpec,
|
||
build_sales_series,
|
||
fill_month_grid,
|
||
log_diff,
|
||
price_bucket_of,
|
||
room_area_bucket_of,
|
||
)
|
||
from app.services.forecasting.scenarios import (
|
||
ScenarioForecast,
|
||
build_rate_envelopes,
|
||
compute_scenarios,
|
||
)
|
||
from app.services.forecasting.what_to_build import (
|
||
RankedSegment,
|
||
WhatToBuildRanking,
|
||
rank_segments,
|
||
)
|
||
|
||
__all__ = [
|
||
"DemandNormalization",
|
||
"DemandSupplyForecast",
|
||
"MacroCoefficient",
|
||
"MonthlyMacro",
|
||
"MortgageAffordabilityIndex",
|
||
"ProductScore",
|
||
"ProductScoreCard",
|
||
"RankedSegment",
|
||
"RateSensitivity",
|
||
"SalesSeries",
|
||
"ScenarioForecast",
|
||
"SegmentSpec",
|
||
"WhatToBuildRanking",
|
||
"assemble_coefficient",
|
||
"best_lag",
|
||
"build_rate_envelopes",
|
||
"build_sales_series",
|
||
"classify_regime",
|
||
"compute_affordability",
|
||
"compute_demand_normalization",
|
||
"compute_demand_supply_forecast",
|
||
"compute_macro_coefficient",
|
||
"compute_rate_sensitivity",
|
||
"compute_scenarios",
|
||
"compute_score_card",
|
||
"f_issuance",
|
||
"f_mortgage_rate",
|
||
"f_overdue",
|
||
"f_rate",
|
||
"fill_month_grid",
|
||
"get_monthly_macro",
|
||
"hold_last_rate",
|
||
"is_confounded_window",
|
||
"log_diff",
|
||
"macro_at_lag",
|
||
"normalization_factor",
|
||
"ols_slope_r2",
|
||
"price_bucket_of",
|
||
"rank_segments",
|
||
"renormalize_contributions",
|
||
"room_area_bucket_of",
|
||
"segment_steepness",
|
||
"shrink",
|
||
]
|