# 🧠 Does the Language of Artificial Intelligence Move Markets? **UQO Working Paper No. 0002 (FIRC-funded)** — *A Semantic Analysis of Russell 3000 SEC Filings and the Cross-Section of Stock Returns, 2010–2026* — **Version 2.1, November 2026 (revised after peer review; v2.0 of October 28, 2026 was the Russell 3000 extension of the S&P 500 study, formerly WP 17 v1.1, archived in `docs/paper_v1.1_sp500_20261026/`). Research funded by the FIRC (Fonds institutionnel de recherche et de création, UQO). > **TL;DR (v2.1, revised after peer review)** — We embed every Form 10-K, 10-Q and 8-K of 2,375 U.S. firms (current S&P 500 members ∪ iShares Russell 3000 holdings, 527,548 filings, 2010–2026) with a sentence transformer, score each chunk against AI anchor concepts, and link the filing-year signal to forward returns whose timing is look-ahead-free (July Y+1 → June Y+2) on a current-membership universe. In the broad market AI language carries a **modest premium that is regression-robust and sort-fragile**: winsorized Fama–MacBeth slope +1.88 pp/SD (NW t 2.41, CI [+0.27, +3.49]); winsorized EW Q5–Q1 +3.9 pp/yr (NW t 2.00, plain 1.78, CI [-0.8, +8.6]; median +0.5); every level conditional on survival to October 2026. The **post-ChatGPT increase appears only among the largest 1,000 firms and in the 2024 cohort** (winsorized +3.1 → +12.7, +3.3 without 2024; remaining firms +4.0 → +3.5); the tested large-vs-small contrast is +10.8 pp (t 1.83 firm / 1.55 two-way, wild p 0.225, MDE 16.5), and the event-study gradient (largest 1,000 CDA t 3.02 under the 2022 IWV market model) falls to 1.12 / 1.22 / 1.38 / 0.52 under beta-only / market-adjusted / size×momentum / FF5+MOM benchmarks. **Disclosed AI projects** (SPID, gpt-4o-mini extraction, unvalidated) show no detectable premium (any-AI contrast +2.8 pp, t 0.77, MDE 10.1). --- ## 📌 Status | Item | Value | |---|---| | Version | **2.1 (November 2026)** — revised after the FIRC-0002 peer review (Stage D rebuilt panel and Stage E prose; `paper/sections/*.tex`, `paper/appendix/appendix.tex`); v2.0 (October 28, 2026) = Russell 3000 extension; à valider par les co-auteurs | | Funding | FIRC (UQO) | | Previous versions | v1.1 (S&P 500, 2026-10-17 review) and v1.0 (June 2026): `docs/paper_v1.1_sp500_20261026/` | | Code & data | **v2.0 exhibits**: produced by the committed `scripts/r3k_00…07` at commit `3cf7560` from `data/raw_russell3000/` (factor panel, filing-level scores, SPID counts, universe) and `data/processed_r3k/` (Yahoo prices and SEC share counts of the **2026-10-28 vintage**; sha256 manifest in `UQO-WP-REVIEW/reproducibility/FIRC-0002/environment/inputs.sha256`); these two directories are gitignored (≈ 320 MB) and must be deposited (spbgit release or M3U96b archive referenced by hash — pending author action) before the results can be called reproducible by a third party. The re-run of the committed chain reproduces `results.json` exactly, `results2.json` except the `spid` and `double_sort_*` blocks (stale at commit time) and `results_event.json` under the author's pandas 3.0.2 (see `reproducibility/FIRC-0002/baseline_rerun_diff.txt`). **v2.1 review chain** (`scripts/r3k_10…23`, `scripts/run_all.sh`, pinned `requirements.lock`, `tests/test_regenerate.py`): rebuilt panel (corrected market capitalization, cleaned returns, CIK-keyed), results in `results/r3k_v2/`. Raw filing text and embeddings come from the EDGAR Research Database (UQO WP 0001) and are not redistributed; FinData OS (FirstRate) raw closes are a licensed second price source (access documented in `data/processed_r3k_v2/README.md`). | ## 🏆 Headline results (Russell 3000 unless stated; v2.1 rebuilt panel, winsorized within formation year unless stated) | Object | Estimate (v2.1) | |---|---| | Panel | 27,354 firm-years, 2,375 firms, formation years 2010–2024 (6,719 firm-years of S&P 500 members); corrected market capitalization, cleaned returns (14 series breaks removed), CIK key | | Full-sample Q5–Q1 spread (composite) | EW raw +5.5 (NW t 2.40); EW winsorized +3.9 (NW t 2.00, plain 1.78, CI [-0.8, +8.6]); median +0.5; VW (corrected cap) +7.4 (t 2.69); S&P 500 members EW winsorized +5.7 | | Fama–MacBeth slope (composite) | winsorized +1.88 pp/SD (NW t 2.41, plain 2.51, CI [+0.27, +3.49]); raw +2.77 (t 2.44); with sector dummies, winsorized +0.88 (NW 2.80, plain 2.74); sector×year FE +0.75 (firm t 2.04, two-way 2.78) | | Pre / post ChatGPT, Russell 3000 (winsorized) | +3.4 → +6.0 (post CI [-25.5, +37.6], n = 3); cohorts 2022: -5.0, 2023: +3.1, 2024: +19.9; pooled post +6.2 (t 2.14 firm / 0.84 two-way, wild p 0.631); post − pre +2.4 (t 0.78 / 0.36, MDE 8.5); permutation p 0.31; sup-Wald p 0.59; post FF6 alpha -0.3 %/yr | | Pre / post, S&P 500 members (winsorized) | +3.8 → +13.2; cohorts 2022: +14.8, 2023: -7.1, 2024: +32.0; pooled post +13.3 (t 2.39 / 1.15); post Sharpe 0.69 | | Size (winsorized) | largest 1,000: +3.1 → +12.7 (ex-2024 +3.3); remaining: +4.0 → +3.5; contrast hi×post×large +10.8 (t 1.83 / 1.55, wild p 0.225, MDE 16.5); size-neutral full +4.9 (t 2.19) | | Event study (IWV market model, day 0 = 1 Dec 2022, N = 2,215) | 1-year H−L +14.2 pp (CDA 2.23; Welch 3.92 for reference); [0,+20] +1.0 (CDA 0.52); largest 1,000 +20.0 (CDA 3.02) vs remaining +12.2 (1.51); largest-1,000 CDA under beta-only / market-adjusted / size×mom / FF5+MOM: 1.12 / 1.22 / 1.38 / 0.52; 2022 ranks 1 of 8 placebo launches | | Sector / within-sector | post-launch sector×year FE slope +0.46 (t 0.43); sector-neutral sort full +1.4 (t 1.61); β_TECH post 0.37; FF6+TECH post alpha -2.1 %/yr | | Form-specific signals (winsorized) | 10-K only: full +6.2 (t 1.91); horse race 10-K +2.78 (t 2.23), 10-Q -0.32, 8-K +0.55; Wald equal slopes p 0.02 (raw p 0.23) | | SPID AI projects | any-AI firm-level +2.8 pp (t 0.77, CI [-4.3, +9.9], MDE 10.1); cohort-level MDE 12.7; SPID×post -1.93 (t -1.93 / -0.96); prevalence 2.0 % of firm-years; no human labels yet | | Placebo factors (post, two-way t) | cybersecurity interaction t 3.98 (RW p 0.05); AI disruption risk 0.96; ESG -1.48; only cybersecurity survives the family adjustment | | Construct validity | encoder window 256 tokens ≈ 195 words of 512 (94.8 % of chunks truncated; 61 % of AI-term hits beyond the window); keyword baseline ρ 0.13; Utilities 6.5 % of Q5 vs 3.2 % of sample; stripped-anchor composite ρ 0.98; negation probe 0.396 vs 0.578 | | Survivorship | EW panel − IWV +5.7 pp/yr (winsorized +3.6); 2019 IWV small tercile 61 % absent by 2025 vs large 16 %; exit-rate difference needed to generate the whole spread: 5.7 pp/yr (−50 % exit return); attrition by AI quintile not computable (X1) | | Multiple testing | Romano–Wolf p of the composite spread within its family 0.32; statistics with |t| > 3 across cohort families: 1; deflated Sharpe 0.35 (post 0.29); specification curve 1152 specs, 84 % positive, 39 % positive and significant, median +3.9 | The v2.0 values that these replace (EW +5.5, t 2.41; FM +3.07, t 2.80; within-sector t 4.38; largest 1,000 +2.9 → +12.8; event-study Welch 5.09 vs 1.55; Table 17 all t = 0.00) are recorded as BEFORE values in `UQO-WP-REVIEW/improvements/FIRC-0002/implemented_changes.md` and in the manuscript where the comparison matters. ## 🗂 Repository layout ``` ai-disclosure-stock-returns/ ├── data/raw_russell3000/ # factor panels, filing_scores, filings, companies, universe.json, spid_firm_year_signals.csv (from the EDGAR DB) ├── data/processed_r3k/ # prices (Yahoo), SEC share history, FF factors, merged/analysis panels, LS series, event CARs ├── scripts/r3k_00..07_*.py # the v2.0 pipeline, in order (01: Yahoo prices · 01c: SEC share counts · 02: panel · 03: core · 04: extended · 05: event · 06: figures · 07: tables + macros) ├── scripts/r3k_10..23_*.py # the v2.1 review chain (run_all.sh): second price pass, SEC shares, FinData checks, rebuilt panel, core/extended/event/survivorship, figures, tables + macros, bib, SPID frame, construct validity ├── scripts/stageE_*.py # Stage E writing helpers: macros_stageE.tex (prose numbers from results/), response_to_referees table ├── results/r3k/ # v2.0 results (results.json, results2.json, results_event.json, CSVs) ├── results/r3k_v2/, results/n1/ # v2.1 results (incl. inline_numbers.json, validation frames) and the node audit (corpus counts, tokenizer, keyword baseline, alternative anchors) ├── figures/r3k/, figures/r3k_v2/ # v2.0 figures; v2.1 figures (17, pdf + png) ├── paper/ # main.tex, sections/ (prose + macros_stageE.tex), appendix/, tables/ (generated, incl. macros.tex), figures_r3k/ → main.pdf ├── code/tex2docx/ # LaTeX → Word conversion (prep_tex.py, post_docx.py) └── docs/ # v1.1 archive, review report, changelog ``` ## 🚀 Quick start (v2.1 review chain — Stage D, 2026-11-05) ```bash uv venv .venv-review --python 3.12 && uv pip install --python .venv-review/bin/python -r requirements.lock bash scripts/run_all.sh # 10 (prices, FF daily) → 12 (SEC shares) → 13/13b (FinData checks) → 14…18 (panel, core, extended, event, survivorship) → 19/20 (figures, tables) → latexmk .venv-review/bin/python -I tests/test_regenerate.py --quick # schema / leakage / manifest checks; without --quick: full regeneration + diff at 1e-6 ``` ## 🚀 Quick start (v2.0 committed chain) ```bash python3 -m pip install -r requirements.txt python3 scripts/r3k_00_factors.py && python3 scripts/r3k_01_download_prices.py && python3 scripts/r3k_01c_sec_shares.py for s in 02_build_panel 03_analysis 04_extended 05_event_study 06_figures 07_tables; do python3 scripts/r3k_$s.py; done cd paper && latexmk # → main.pdf (every number in the text is a macro from tables/macros.tex) ``` ## 📊 Exhibit map (Stage E, exhibits director, 2026-11-05) Every table of the paper is a self-contained float generated by `scripts/r3k_20_tables_v2.py` into `paper/tables/.tex` (`\ExhibitTable{label}{caption}{size}{threeparttable + notes}`), and every figure by `scripts/r3k_19_figures_v2.py` into `figures/r3k_v2/.pdf` with a float wrapper `paper/figures_r3k/.tex` (`\ExhibitFigure{label}{caption}{\includegraphics}`). A bare `\input{tables/}` / `\input{figures_r3k/}` places the exhibit with its scientific caption, label and notes; inside an existing `\begin{table}` wrapper only the body is printed. `paper/tables/appendix_exhibits.tex` (input from `main.tex` after the appendix) prints, behind `\ExhibitOnce` guards, every table not placed earlier and the appendix-bound figures, so no exhibit is lost or duplicated. The full map (label → file → placement main/appendix → title → result-file sources) is `paper/tables/EXHIBIT_MAP.md` (also `.json`); the render-and-inspect audit is `UQO-WP-REVIEW/quality_control/_FIRC-0002_table_audit.csv` and `_figure_audit.csv`. Numbers in captions and notes are read from `results/r3k_v2/*` (BEFORE values of the committed v2.0, from `results/r3k/*`, appear only in `tab_hygiene` Panel B).