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%
2.0 KB · 61 lines python
Raw Blame History
1# =============================================================================2# QWHPI — Quebec Weekly Housing Price Index3# Author  : Simon-Pierre Boucher4# Contact : contact@spboucher.ai5# File    : engine/tests/test_state_space.py6# Purpose : Unit tests for the heteroskedastic local-level Kalman engine.7# =============================================================================8"""State-space unit tests."""910from __future__ import annotations1112import sys13from pathlib import Path1415sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))1617import numpy as np1819from qwhpi.state_space import fit_local_level2021RNG = np.random.default_rng(0)222324def test_recovers_constant_signal():25    T, n = 150, 3026    y = 0.05 + RNG.normal(0, 0.2 / np.sqrt(n), T)27    fit = fit_local_level(y, np.full(T, n), sigma2=0.04)28    assert abs(fit.smoothed[T // 2] - 0.05) < 0.0229    assert fit.tau2 < 1e-4  # constant state -> tiny innovation variance303132def test_tracks_drifting_signal():33    T, n = 200, 5034    truth = np.cumsum(RNG.normal(0, 0.01, T))35    y = truth + RNG.normal(0, 0.3 / np.sqrt(n), T)36    fit = fit_local_level(y, np.full(T, n), sigma2=0.09)37    rmse = np.sqrt(np.mean((fit.smoothed - truth) ** 2))38    assert rmse < 0.02394041def test_empty_weeks_are_predicted_not_dropped():42    T = 10043    n = np.full(T, 20.0)44    n[40:60] = 0  # 20-week gap45    truth = np.cumsum(RNG.normal(0, 0.02, T))  # real innovation -> tau2 > 046    y = np.where(n > 0, truth + RNG.normal(0, 0.05, T), np.nan)47    fit = fit_local_level(y, n, sigma2=0.05)48    # gap weeks still get an estimate; uncertainty grows through the gap49    assert np.all(np.isfinite(fit.smoothed))50    assert fit.filtered_var[59] > fit.filtered_var[41] > fit.filtered_var[39]51    assert fit.gain[50] == 0.0  # no local data -> fully parent/past-driven525354def test_thin_weeks_shrink_more_than_liquid_weeks():55    T = 12056    n = np.full(T, 2.0)57    n[:60] = 200.058    y = RNG.normal(0, 0.05, T)59    fit = fit_local_level(y, n, sigma2=0.09)60    assert fit.gain[:60].mean() > fit.gain[60:].mean()61