SPB Git

spb/wp37_uqo

Public
10.1 KB

# WP37 — Preregistration of hypotheses, samples, estimands and analysis plan

Status: FROZEN on 2026-11-01 before any hypothesis-relevant estimation (hash recorded in research/decisions.md). Amendments after this date are logged in research/decisions.md with a reason; the paper reports both the preregistered and any amended analysis.

# 0. What was examined before freezing (disclosure)

Phase 0–1 work looked at: table counts, per-feed coverage, the event-log data-generating process, intra-day price oscillation diagnostics (share of A→B→A reversions, number of distinct price values, weekly Jaccard of value sets), unit-price coverage, the distribution of current discount depth (1 − price/regular_price, median 0.17), UPC validity, matching precision/recall and the validation sample. No cross-banner price gap, promotion duration, index, response model or forecast has been computed. The store-mixture finding (Phase 0 report §3.3) motivated the weekly modal-price definition below; this is a data-quality decision, not a result-driven one.

# 1. Universe, period and units

  • Snapshot foodka-snapshot-20261101 (sha256 3cd7684d…), event log 2026-08-12 → 2026-11-01, 12 complete circular weeks (Thu 2026-08-13 → Wed 2026-11-04 truncated at 2026-11-01; the first partial week 2026-08-06 and the last partial week 2026-10-29 are dropped from weekly analyses unless stated).
  • Grocery universe = listings from feeds whose store_format is not pharmacy or alcohol monopoly, in categories other than {Santé et beauté, Maison et entretien, Animaux, Bébé, Alcool}, with ≥ 1 observed price and no unrealistic-price flag.
  • Posted price of listing i in week w = duration-weighted modal price p_mode over the week (primary); p_min, p_max, p_twmean as sensitivity. Unit price = posted price / parsed package quantity (per 100 g, 100 ml or unit).
  • Matched product = cross-banner match group built from tiers A + B (primary); A+B+C and A+B+C+D in sensitivity; groups with > 1 simultaneously active listing from the same banner-channel are flagged ambiguous and excluded from the primary sample.
  • Channel: storefront vs circular. Same-banner channel links are not cross-banner comparisons.
  • Clustering default: two-way by match group and by banner (banner clusters are few — 17 banners with storefront feeds — so wild-cluster bootstrap p-values are reported alongside).

# 2. Hypotheses

# H1 — Matched-item cross-banner dispersion is economically meaningful and persistent

  • Sample: product-weeks of matched groups (A+B) with ≥ 2 banners posting a price in the same week; storefront channel only (primary), circulars added in sensitivity.
  • Outcome: log p_{irw}; dispersion statistics per group-week: coefficient of variation, max–min log gap, interquartile log range.
  • Estimand (Model A): log p_irw = α_iw + γ_r + ε_irw (product-week FE, banner FE). Banner effects γ_r are relative posted price levels; dispersion = sd of residual + sd of γ. Persistence: autocorrelation of the banner-pair log gap g_{i,rs,w} across weeks (AR(1) coefficient), share of pairs whose ranking never flips.
  • Null: median within-group max–min log gap = 0 (trivially rejected); the economic threshold we preregister is a median gap ≥ 0.05 (5 %) and AR(1) ≥ 0.5 for "meaningful and persistent".
  • Controls: none beyond FE in the primary spec; sensitivity adds category × week FE.
  • Missingness: a banner-week without a posted price is missing, not zero; groups with intermittent coverage are kept (unbalanced) and a balanced common-product panel is reported as robustness.
  • Falsification: Metro vs Super C exact-UPC pairs (same company, two formats) should show smaller dispersion than cross-company pairs if company-level pricing coordination exists; placebo: random re-assignment of banners within group-week should yield AR(1) ≈ 0.
  • Minimum duration: 8 weeks for AR(1); available.

# H2 — Promotion-adjusted price volatility differs from non-promotion volatility

  • Sample: listing-weeks of storefront feeds (grocery universe) with ≥ 8 observed weeks.
  • Promotion state inferred (storefront): a week is "promoted" if p_mode_w ≤ 0.90 × reference_w, where reference_w is the modal price over the trailing 8 weeks (including w) — the Nakamura–Steinsson/Kehoe–Midrigan reference filter; validated against the current on_sale flag in the snapshot week (report agreement) and against circular items of the same banner-week when matched.
  • Outcome: sd of weekly log price changes (i) raw, (ii) excluding promotion weeks (reference-price series).
  • Estimand: ratio of raw to reference-price volatility by banner and category; share of all weekly log changes attributable to promotion entry/exit.
  • Null: ratio = 1. Clustering: by banner × category (bootstrap over listings).
  • Falsification: single-store online shops (Shopify/WooCommerce feeds) must not display the 3–5-level oscillation; if they do, the store-mixture interpretation fails and H2 is re-examined at the daily frequency.
  • Missingness: weeks with no observed price are dropped from the change series (no interpolation).

# H3 — Promotions are associated with subsequent reference-price adjustments

  • Sample: promotion episodes (≥ 1 promoted week followed by return to a non-promoted week) in storefront feeds; circular items matched to a storefront listing of the same banner (tier channel link) provide the second sample with observed original_price.
  • Outcome: change in the reference price after the episode vs before: Δ log ref = log ref_{post} − log ref_{pre}.
  • Estimand (Model B): transition matrix regular↔promoted; episode duration, recurrence interval, depth; event-study of log price from −4 to +4 weeks around episode end with listing FE and week FE; test of pretrends (weeks −4…−2 coefficients jointly = 0).
  • Null: E[Δ log ref] = 0 (promotions neither precede nor follow reference increases). Direction is left to the data.
  • Falsification/censoring: episodes censored at panel edges are excluded; overlapping episodes within the same listing are merged; placebo events at random weeks must give Δ ≈ 0.
  • Minimum duration: 26 weeks for a well-powered test; with 12 weeks the test is exploratory and labelled so.

# H4 — Competitor responses are strongest for close substitutes and nearby stores

  • Store geography is unavailable → the "nearby stores" part is not testable and is stated as such. The testable part: banner-level weekly response of Δ log p_{irw} to lagged rival changes Δ log p_{isw−k} (k = 0…3) within matched group, with product-week and banner FE (Model C), separately for same-company rivals (Metro/Super C; Maxi/Provigo/Club Entrepôt) vs cross-company rivals.
  • Estimand: distributed-lag coefficients; contemporaneous (k = 0) coefficients are not causal (common shocks, simultaneity); k ≥ 1 coefficients are descriptive lead–lag associations. No IV/quasi-experiment is preregistered because no exogenous shifter is available.
  • Null: all lagged coefficients = 0.
  • Clustering: two-way group × week. Falsification: placebo with rival changes shifted forward (leads) must be ≈ 0.

# H5 — Package-size and assortment changes create gaps between naive and quality-consistent indices

  • Sample: grocery universe, weekly, storefront + circular.
  • Indices (Model D): (a) naive average posted price by category; (b) Jevons matched-model index (geometric mean of weekly log changes over listings present in both weeks); (c) fixed-basket Laspeyres with equal item weights (no expenditure weights exist — explicitly not a CPI); (d) chained version; (e) unit-price versions of (b)–(d) that re-match listings whose size label changed.
  • Estimand: cumulative difference between (a) and (b) over 12 weeks; count and unit-price effect of within-listing size changes.
  • Null: gap = 0. Uncertainty by listing-level bootstrap (B = 999, seed 20261101).
  • Benchmark: StatCan CPI "Food purchased from stores", Quebec, Aug→Sep 2026 (2 months) — comparison only, no superiority claim.

# H6 — Unconstrained minimum-price basket savings exceed savings feasible under constraints

  • Basket: 30 generic items specified by category and quantity (preregistered in config/basket.yaml before estimation), mapped to matched groups (A+B) and, where no matched group exists, to the cheapest listing per banner within a tight name rule (documented).
  • Model E: integer program minimising basket cost subject to at most K banners (K = 1…5), each item bought at one banner, availability = posted price exists that week. Travel costs are not observable; a sensitivity grid of fixed per-store costs (0, 5, 10, 20 CAD) is reported as illustrative, labelled as assumption-based.
  • Estimand: savings frontier S(K) = cost(K=1 best single banner) − cost(K); share of unconstrained savings attained at K = 2.
  • Null: S(∞) − S(2) = 0 (two banners capture everything).

# Forecasting (Model F) — preregistered evaluation

  • Target: next-week posted unit price (log) and next-week promotion indicator per listing (storefront).
  • Rolling origin: train weeks 1…t, test week t+1, t = 6…11; models: seasonal naive (last week), banner-category mean reversion, ridge, LightGBM; metrics: MAE / RMSE on log price, Brier / AUC on promotion. No future information in features (strict lags only).

# 3. QGPAI components (Phase 5) — fixed before computation

  1. Comparable Price Index: Jevons matched-model index over matched groups (A+B), weekly, base = week of 2026-08-13 = 100.
  2. Promotion Intensity: share of listing-weeks promoted; mean depth; sd of depth — storefront (inferred) and circular (observed) reported separately.
  3. Retail Price Dispersion: median within-group max–min log gap (H1 statistic).
  4. Feasible Basket Cost: Model E cost at K = 1 and K = 2.
  5. Access & Affordability: not computed (no geography/income data joined); placeholder documented. Aggregation: components are published separately; an equal-weight z-score composite is shown only as an illustration with alternative weights (0.5/0.5 on components 1 and 4) — not an empirical estimate.

# 4. Multiple testing

Six preregistered families (H1–H6); within each, Holm correction over the primary tests. Exploratory analyses are labelled.

Files · main
Menu

Theme