Add scenarios.py: run the #952 demand↔supply engine under three key-rate envelopes (base = hold_last_rate flat; conservative +2.0 п.п.; aggressive −3.0 п.п., widening with horizon, clamped ≥0) → one ScenarioForecast each. Single lever = rate_path into #952 (β stays counted-once in §9.4). Pure build_rate_envelopes separated from DB orchestrator; advisory inherits #952 cap; graceful no-macro. Deterministic, no LLM, no SQL. 47 tests.
130 lines
4.6 KiB
Python
130 lines
4.6 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).
|
||
|
||
Источники данных:
|
||
• макро — таблица 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.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",
|
||
"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",
|
||
"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",
|
||
]
|