SPB Git

spb/wp37_uqo

Public
10.1 KB · 80 lines markdown
1# WP37 — Preregistration of hypotheses, samples, estimands and analysis plan23Status: **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.45## 0. What was examined before freezing (disclosure)67Phase 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.89## 1. Universe, period and units1011- 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).12- 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.13- **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).14- **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.15- Channel: storefront vs circular. Same-banner channel links are not cross-banner comparisons.16- 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).1718## 2. Hypotheses1920### H1 — Matched-item cross-banner dispersion is economically meaningful and persistent21- 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.22- Outcome: `log p_{irw}`; dispersion statistics per group-week: coefficient of variation, max–min log gap, interquartile log range.23- 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.24- 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".25- Controls: none beyond FE in the primary spec; sensitivity adds category × week FE.26- 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.27- 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.28- Minimum duration: 8 weeks for AR(1); available.2930### H2 — Promotion-adjusted price volatility differs from non-promotion volatility31- Sample: listing-weeks of storefront feeds (grocery universe) with ≥ 8 observed weeks.32- 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.33- Outcome: sd of weekly log price changes (i) raw, (ii) excluding promotion weeks (reference-price series).34- Estimand: ratio of raw to reference-price volatility by banner and category; share of all weekly log changes attributable to promotion entry/exit.35- Null: ratio = 1. Clustering: by banner × category (bootstrap over listings).36- 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.37- Missingness: weeks with no observed price are dropped from the change series (no interpolation).3839### H3 — Promotions are associated with subsequent reference-price adjustments40- 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`.41- Outcome: change in the reference price after the episode vs before: `Δ log ref = log ref_{post} − log ref_{pre}`.42- 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).43- Null: E[Δ log ref] = 0 (promotions neither precede nor follow reference increases). Direction is left to the data.44- 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.45- Minimum duration: 26 weeks for a well-powered test; with 12 weeks the test is **exploratory** and labelled so.4647### H4 — Competitor responses are strongest for close substitutes and nearby stores48- 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.49- 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.50- Null: all lagged coefficients = 0.51- Clustering: two-way group × week. Falsification: placebo with rival changes shifted forward (leads) must be ≈ 0.5253### H5 — Package-size and assortment changes create gaps between naive and quality-consistent indices54- Sample: grocery universe, weekly, storefront + circular.55- 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.56- Estimand: cumulative difference between (a) and (b) over 12 weeks; count and unit-price effect of within-listing size changes.57- Null: gap = 0. Uncertainty by listing-level bootstrap (B = 999, seed 20261101).58- Benchmark: StatCan CPI "Food purchased from stores", Quebec, Aug→Sep 2026 (2 months) — comparison only, no superiority claim.5960### H6 — Unconstrained minimum-price basket savings exceed savings feasible under constraints61- 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).62- 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.63- Estimand: savings frontier S(K) = cost(K=1 best single banner) − cost(K); share of unconstrained savings attained at K = 2.64- Null: S(∞) − S(2) = 0 (two banners capture everything).6566### Forecasting (Model F) — preregistered evaluation67- Target: next-week posted unit price (log) and next-week promotion indicator per listing (storefront).68- 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).6970## 3. QGPAI components (Phase 5) — fixed before computation711. Comparable Price Index: Jevons matched-model index over matched groups (A+B), weekly, base = week of 2026-08-13 = 100.722. Promotion Intensity: share of listing-weeks promoted; mean depth; sd of depth — storefront (inferred) and circular (observed) reported separately.733. Retail Price Dispersion: median within-group max–min log gap (H1 statistic).744. Feasible Basket Cost: Model E cost at K = 1 and K = 2.755. Access & Affordability: **not computed** (no geography/income data joined); placeholder documented.76Aggregation: 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.7778## 4. Multiple testing79Six preregistered families (H1–H6); within each, Holm correction over the primary tests. Exploratory analyses are labelled.80
Files · 6b98ba74da2dd3460762f3a83a17630795fba248
Menu

Theme