SPB Git

spb/wp39_uqo

Public
10.8 KB

# 🕰️ The Invisible Balance Sheet

UQO Working Paper No. 39 — Can Intraday Financial Markets Detect Corporate Deterioration Before Accounting Disclosures?

Paper Python Data Reproducible Institution Author

TL;DR — Do one-minute markets see a firm's forthcoming accounting deterioration before daily markets do? On a strictly point-in-time panel of 3,796 U.S. firms and 102,522 firm-quarters (2013–2026) built from 6.7 billion raw 1-minute bars and quarterly statements with release dates, we forecast an adverse operating-income surprise 20 trading days before the earnings release with nested information sets of equal capacity. Fundamentals do most of the work, daily OHLCV adds a clear increment (Δ log loss −0.0068 with boosted trees), and 1-minute families add nothing: +0.0013 [−0.0013, +0.0041] (logistic) and +0.0016 [+0.0010, +0.0023] (trees) on an untouched 2021–2026 test period. The null holds at five horizons, for five accounting targets, a volatility placebo, unseen firms, every refit year and every subgroup; the signal is already in prices at the cutoff and has no factor-adjusted economic value. A precise null: the minute-by-minute tape adds noise, not foresight — on survivors (see Limitations).


# 📌 Status

Item Value
Version 1.0 (November 2026) — built autonomously on 2026-11-02 under the owner's brief (CLAUDE.md); phases 0–7 complete
SSRN not yet submitted
Journal target: JAR / JFE / RFS (finance–accounting interface); internal referee reports in docs/REFEREE_REPORTS.md list the v1.1 revisions
Code & data reproducible from scripts/ against FinData OS (private FirstRate Data lakehouse); raw records not redistributed

# 🎯 What this paper does

Anticipation is not the question — prices lead earnings at daily horizons and we reproduce it. The question is the marginal information value of sampling frequency: holding the universe, calendar, cutoff, horizon, feature families and tuning budget fixed, do 30-minute, 5-minute and 1-minute OHLCV bars add forecasting content about the accounting outcome beyond point-in-time fundamentals and daily bars? Targets are accounting surprises against a seasonal random walk with drift (never prices); the reveal date is the earnings press release; the information set at cutoff c holds bars with session ≤ c and facts with available_at ≤ c only, with twelve leakage guards as unit tests.

text
S_{i,q} = (X_{i,q} − E_c[X_{i,q}]) / TA_{i,q−1},   D_{i,q} = 1[S_{i,q} ≤ −0.5 %]
E_c[X_q] = X_{q−4} + ¼ Σ_{k=0..3} (X_{q−1−k} − X_{q−5−k})   (quarters available at c only)

# 🏆 Headline results (test period 2021–2026, h = 20, N = 53,667)

Object Estimate
Base rate of adverse surprise 31.5 %
Log loss: base rate / fundamentals / + daily (LightGBM) 0.628 / 0.494 / 0.487 (AUC 0.797 / 0.803)
Daily increment LB2 − LB1 −0.0068 [−0.0095, −0.0042]
1-minute increment B5 − B2 (logistic) +0.0013 [−0.0013, +0.0041], GW p = 0.52
1-minute increment LB5 − LB2 (LightGBM) +0.0016 [+0.0010, +0.0023] (a deterioration)
30-min / 5-min increments (LightGBM) +0.0017 / +0.0021
Pre-registered MDE (80 % power) 0.0025
Horizon gradient (H4) none (Spearman −0.5, p ≈ 0.35)
Panel: surprise on LFDS_B2 / incremental LFDS_B5−B2 β = −0.0765 (t = −32) / −0.0129 (t = −1.8)
Announcement CAR on LFDS_B5 β ≈ 0 (t = 0.01): signal already in prices
L/S decile alpha (FF5+MOM), LB5 scores −0.59 %/mo (t = −1.85) gross, −0.62 % net of 20 bps

# 🗂 Repository layout

text
invisible-balance-sheet/            # project id wp39_uqo
├── CLAUDE.md · README.md · PROGRESS.md · DECISIONS.md · DATA_AUDIT.md · LIMITATIONS.md
├── configs/        research.yaml (frozen design) · data_contract.yaml · models.yaml
├── docs/           RESEARCH_DESIGN.md · PIT_PROTOCOL.md · NOVELTY_MEMO.md · API_INTEGRATION.md · COMPUTE_BUDGET.md · REPLICATION.md · REFEREE_REPORTS.md
├── literature/     RELATED_WORK_MATRIX.csv · references.bib (94 entries verified on Crossref)
├── src/wp39/       api_client · provenance · calendar · instruments · pit_fundamentals · corporate_actions · ingest · features · labels · samples · splits · models · inference · portfolio · robustness · figures · pipeline
├── scripts/        00_probe … 09_make_manuscript (+ 01a node extracts)
├── tests/          29 tests (timestamps/DST, PIT leakage, labels, splits, train-only transforms, corporate actions, ids, reproducibility, API contract incl. live as-of equivalence, features)
├── artifacts/      manifests (hashes, dataset versions, design freeze) · evaluation (csv/json) · logs
├── results/        audits, cascades, metrics, contrasts, regressions
├── paper/          main.tex · sections/ · tables/ (generated) · figures/ (generated) · results_macros.tex (206 macros) · main.pdf
└── data/           README only (no licensed records committed)

# 🚀 Quick start

bash
uv venv -p 3.12 .venv && uv pip install -e ".[dev]"
export FINDATA_BASE_URL=http://127.0.0.1:8600/api/v1 WP39_CACHE=~/wp39-cache   # on the FinData node
bash scripts/01a_extract_node_tables.sh && for s in 00 01 02 03 04 05 06 07 08 09; do .venv/bin/python scripts/${s}_*.py; done
pytest -q            # WP39_LIVE=1 adds the live API tests
cd paper && make     # latexmk → main.pdf

Measured wall-times (Mac Studio M3 Ultra, 28 cores): universe audit 17 min (SEC), PIT panel 8 min, features 58 min (8 workers), sample 30 s, baselines 30 s, LightGBM 29 min, evaluation 1 min, robustness 25 s, manuscript 10 s.

# 🗃 Data

FinData OS (findata.spboucher.ai/api/v1), the owner's private lakehouse of FirstRate Data: raw 1-minute bars (2000–2026, 16,195 symbols incl. 8,069 delisted), quarterly fundamentals (5,451 entities, 67 metrics, filing dates 2012–2026), 364,783 earnings-release events (node extract), splits/dividends (node extract). Public: SEC company_tickers.json + submissions (CIK/SIC), Kenneth French daily factors. Universe cascade: 5,451 → 5,018 (≥ 8 quarters) → 4,568 (1-minute coverage); event sample 481,159 observations after admissibility and exclusions (results/table_sample_cascade_event.csv). Full audit: DATA_AUDIT.md.

# 🔬 Methodology

  1. Clocks and cutoffs (samples.py, calendar.py): c = A_q − h, h ∈ {40, 20, 10, 5, 1}; c < min(A_q, F_q), c > A_{q−1}.
  2. PIT fundamentals (pit_fundamentals.py): local as-of join on available_at, verified live against the API.
  3. Labels (labels.py): seasonal-random-walk-with-drift surprises, primary and secondary targets, symmetric placebo.
  4. Features (features.py): same 19 families from 1m/5m/30m buckets of the regular session, daily block, split/dividend-adjusted returns.
  5. Ladder (models.py): B0–B5 logistic (C on validation), LB1–LB5 LightGBM (24-trial equal budget), ridge for the continuous target.
  6. Validation (splits.py): chronological with purge/embargo, expanding-window annual refits, 20 % firm hold-out.
  7. Inference (inference.py): block bootstrap by calendar quarter, Giacomini–White, Holm, two-way clustered panels.
  8. Robustness and pricing (robustness.py, portfolio.py): shuffled labels, subgroups, CAR regressions, decile sorts with FF5+MOM and costs.

# 🖼 Figures & tables inventory

Figure Content
fig01_timeline event-time design and no-leakage rule (schematic)
fig02_coverage firms and adverse rate by year
fig03_prevalence conditional prevalence by size, illiquidity, leverage, release timing
fig04_frequency_gains Δ log loss vs B2 for 30m/5m/1m/all, logistic and LightGBM, 95 % block-bootstrap CIs
fig05_reliability calibration deciles
fig06_signal_evolution AUC and Δ by horizon (H4)
fig07_heterogeneity Δ by pre-specified subgroup (H3)
fig08_rolling annual refits: AUC and Δ by year
fig09_economic decile returns and alphas

Tables (paper/tables/*.tex): universe and sample cascades, summary statistics, information sets, headline metrics, paired contrasts, horizon ladder, secondary targets, firm hold-out, panel regressions, subgroups, placebo, continuous target, economic value, CAR regressions.

# ⚠️ Limitations

  • Accounting panel conditioned on firms listed in November 2026 (no delisted entities from the vendor): survivorship.
  • available_at = filing_date + 1 is a vendor policy; all facts are revision 1 (current values): PIT proxy, no as-originally-reported history.
  • OHLCV bars only: no quotes, trades or order flow; bar statistics are not interpreted as informed trading.
  • Logistic-family CI (±0.0027) is comparable to the MDE (0.0025); the precise-null claim rests mainly on the boosted family (±0.0006).
  • No neural/text models (owner instruction to minimise AI use). Full list: LIMITATIONS.md; planned v1.1 revisions: docs/REFEREE_REPORTS.md.

# 📝 Citation

bibtex
@techreport{boucher2026invisible,
  author      = {Boucher, Simon-Pierre},
  title       = {The Invisible Balance Sheet: Can Intraday Financial Markets Detect Corporate Deterioration Before Accounting Disclosures?},
  institution = {Universit\'e du Qu\'ebec en Outaouais, D\'epartement des sciences administratives},
  type        = {Working Paper},
  number      = {39},
  year        = {2026},
  month       = {November}
}

# 👤 Author & contact

Simon-Pierre Boucher — Département des sciences administratives, Université du Québec en Outaouais (UQO), Gatineau, QC. 📧 simon-pierre.boucher@uqo.ca

# 🗒 Notes

  • Built in one autonomous Claude Code session on 2026-11-02 (phases 0–7 of CLAUDE.md); gates requiring owner approval are recorded as self-approved under the autonomous mandate (DECISIONS D-010) and remain open to veto.
  • Directory name follows the series convention (finance/<slug>); project id and spbgit repository are wp39_uqo.
  • Data attribution: FirstRate Data via FinData OS (private license; no raw records in this repository).
Files · 40c2540090ce3abd70e4c52d4d84d83308220e72
Menu

Theme