SPB Git

spb/qwhpi Public

QHPI — Quebec Housing Price Index: quality-adjusted, hierarchically pooled housing price indexes.

Python 63.9% TypeScript 25.4% CSS 5.5% TeX 3.5% SQL 0.8% Makefile 0.5% Dockerfile 0.5%
3.9 KB · 149 lines python
Raw Blame History
1# =============================================================================2# QWHPI — Quebec Weekly Housing Price Index3# Author  : Simon-Pierre Boucher4# Contact : contact@spboucher.ai5# File    : api/app/schemas.py6# Purpose : Pydantic response schemas (monthly v2.1) — uncertainty and7#           reliability are always present, never hidden.8# =============================================================================9"""API response schemas — QHPI monthly."""1011from __future__ import annotations1213from pydantic import BaseModel1415AUTHOR = "Simon-Pierre Boucher"16CONTACT = "contact@spboucher.ai"171819class Credit(BaseModel):20    author: str = AUTHOR21    contact: str = CONTACT222324class Observation(BaseModel):25    period: str26    index: float | None27    index_smoothed: float28    representative_value: float | None29    transactions: int30    effective_sample_size: float | None31    monthly_pct: float | None32    three_month_pct: float | None33    six_month_pct: float | None34    yoy_pct: float | None35    lower_95: float36    upper_95: float37    reliability_grade: str38    shrinkage_weight: float | None39    is_partial_month: bool404142class SeriesResponse(Credit):43    geography: str44    geography_name: str45    geography_level: str46    property_type: str47    frequency: str = "monthly"48    base_period: str = "2021 average = 100"49    model_version: str50    data_vintage: str51    total_observations: int52    offset: int = 053    limit: int | None = None54    observations: list[Observation]555657class LatestResponse(Credit):58    geography: str59    geography_name: str60    property_type: str61    frequency: str = "monthly"62    period: str63    latest_index: float64    latest_index_raw: float | None65    representative_value: float | None66    monthly_change: float | None67    three_month_change: float | None68    yoy_change: float | None69    transactions: int70    effective_sample_size: float | None71    reliability: str72    lower_95: float73    upper_95: float74    is_partial_month: bool75    model_version: str76    data_vintage: str777879class GeographyNode(BaseModel):80    geography_id: str81    geography_name: str82    geography_level: str83    property_types: list[str]848586class GeographiesResponse(Credit):87    data_vintage: str88    published_series: list[GeographyNode]89    coverage_matrix_url: str = "/v1/geographies/coverage"909192class LiquidityPoint(BaseModel):93    period: str94    transactions: int959697class LiquidityResponse(Credit):98    geography: str99    property_type: str100    median_monthly_transactions: float101    observations: list[LiquidityPoint]102103104class MapCell(BaseModel):105    geography_id: str106    geography_name: str107    value: float | None108    reliability_grade: str109    transactions: int110111112class MapResponse(Credit):113    metric: str114    level: str115    property_type: str116    period: str117    cells: list[MapCell]118119120class VintageObservation(BaseModel):121    period: str122    first_release_index_smoothed: float123    current_index_smoothed: float124    first_release_vintage: str125    current_vintage: str126    revision_pct: float127128129class MetaResponse(Credit):130    name: str = "QHPI — Quebec Housing Price Index (monthly)"131    model_version: str132    data_vintage: str133    frequency: str = "monthly"134    base_period: str = "2021 average = 100"135    methodology: str = (136        "Robust monthly architecture: province paths by rolling-time-dummy "137        "hedonic (13-month Huber-IRLS windows, mean splice — revision-free); "138        "liquid cells (≥40 tx/month) estimated directly by local robust "139        "time-dummy with state-space smoothing; thin cells shrunk toward "140        "their parent path via a heteroskedastic local-level Kalman model. "141        "Validated against repeat sales, stratified matched-cell medians, "142        "downsampling and composition-shock simulations."143    )144    methodology_url: str = "/methodology"145    seasonal_adjustment: str = "NSA (no stable monthly seasonality detected)"146    series_count: int147    periods: int148    latest_complete_period: str149