8-KMaterial events. Within 4 days.
Companies must file an 8-K within 4 business days of any material event. Earnings announcements, M&A deals, CEO departures, dividend declarations, guidance revisions — the 8-K is where corporate events hit the public record first. Valuein indexes every 8-K with filing date and accepted_at timestamps so you can build event-driven strategies with clean temporal boundaries.
- Earnings announcements (Item 2.02) with precise filing timestamps
- M&A events — acquisition agreements and closings
- Executive appointments and departures (Item 5.02)
- Dividend declarations and special distributions
- Guidance revisions and material contract disclosures
Why 8-K timing matters for backtesting
The accepted_at column in the filing table is the SEC acceptance timestamp — the moment the document became public. Use it as your event date, not filing_date (date-only) and never period_end, to avoid look-ahead bias in event-driven backtests.
All 8-K filing dates are available in the filing Parquet table, separate from the fact table which holds financial figures from 10-K and 10-Q filings.
Event-driven queries that deliver alpha
Production-ready queries using ValueinClient combining 8-K metadata with fundamental context.
Earnings Release Timeline — 8-K Item 2.02
Every 8-K carrying Item 2.02 (Results of Operations) from current S&P 500 members in the last year, with the event date and the exact SEC acceptance time. filing.items lists each 8-K's item numbers.
Show the query ↓Hide the query ↑
from valuein_sdk import ValueinClient, ValueinError sql = """SELECT r.symbol, r.name, r.sector, fi.report_date AS event_date, fi.filing_date, fi.accepted_at, fi.itemsFROM filing fiJOIN "references" r ON r.cik = fi.entity_id AND r.is_active AND r.is_primary_tickerJOIN index_membership im ON im.cik = r.cikWHERE fi.form_type = '8-K' AND list_contains(fi.items, '2.02') -- Item 2.02: Results of Operations AND im.index_name = 'SP500' AND im.removal_date IS NULL AND fi.filing_date >= current_date - INTERVAL 1 YEARORDER BY fi.accepted_at DESCLIMIT 100""" try: with ValueinClient() as client: df = client.run_query(sql) print(df.head(20))except ValueinError as e: print(f"Valuein error: {e}")M&A Event Screen — Items 1.01 and 2.01
Companies that filed material-agreement or completed-acquisition 8-Ks in the last year, with balance-sheet strength from their latest filed values. Low leverage plus cash makes a capable acquirer.
Show the query ↓Hide the query ↑
from valuein_sdk import ValueinClient, ValueinError sql = """WITH members AS ( SELECT r.cik, r.symbol, r.name, r.sector FROM "references" r JOIN index_membership im ON im.cik = r.cik WHERE im.index_name = 'SP500' AND im.removal_date IS NULL AND r.is_active AND r.is_primary_ticker),deals AS ( -- Item 1.01: material definitive agreement; 2.01: completed acquisition. SELECT entity_id, COUNT(*) AS deal_8ks, MAX(filing_date) AS latest_deal_8k FROM filing WHERE form_type = '8-K' AND (list_contains(items, '1.01') OR list_contains(items, '2.01')) AND filing_date >= current_date - INTERVAL 1 YEAR GROUP BY entity_id),balance_sheet AS ( SELECT entity_id, standard_concept, numeric_value FROM fact WHERE standard_concept IN ('CashAndEquivalents', 'LongTermDebt', 'TotalAssets') QUALIFY ROW_NUMBER() OVER ( PARTITION BY entity_id, standard_concept ORDER BY period_end DESC, accepted_at DESC ) = 1),strength AS ( SELECT entity_id, MAX(CASE WHEN standard_concept = 'CashAndEquivalents' THEN numeric_value END) AS cash, MAX(CASE WHEN standard_concept = 'LongTermDebt' THEN numeric_value END) AS long_term_debt, MAX(CASE WHEN standard_concept = 'TotalAssets' THEN numeric_value END) AS total_assets FROM balance_sheet GROUP BY entity_id)SELECT m.symbol, m.name, m.sector, d.deal_8ks, d.latest_deal_8k, ROUND(s.cash / 1e9, 2) AS cash_b, ROUND(s.long_term_debt / NULLIF(s.total_assets, 0), 2) AS debt_to_assetsFROM deals dJOIN members m ON m.cik = d.entity_idLEFT JOIN strength s ON s.entity_id = d.entity_idWHERE s.long_term_debt / NULLIF(s.total_assets, 0) < 0.3ORDER BY d.deal_8ks DESC, cash_b DESCLIMIT 20""" try: with ValueinClient() as client: df = client.run_query(sql) print(df)except ValueinError as e: print(f"Valuein error: {e}")Executive Change Tracker — Item 5.02
Director and officer departures or appointments (8-K Item 5.02) in the last year, next to the change in annual net income.
Show the query ↓Hide the query ↑
from valuein_sdk import ValueinClient, ValueinError sql = """WITH members AS ( SELECT r.cik, r.symbol, r.name, r.sector FROM "references" r JOIN index_membership im ON im.cik = r.cik WHERE im.index_name = 'SP500' AND im.removal_date IS NULL AND r.is_active AND r.is_primary_ticker),officer_changes AS ( -- Item 5.02: departure or appointment of directors and officers. SELECT entity_id, COUNT(*) AS item_502_count, MAX(filing_date) AS latest_change FROM filing WHERE form_type = '8-K' AND list_contains(items, '5.02') AND filing_date >= current_date - INTERVAL 1 YEAR GROUP BY entity_id),net_income AS ( -- Last two fiscal years of net income, latest-filed vintage each. SELECT entity_id, period_end, numeric_value FROM fact WHERE standard_concept = 'NetIncome' AND fiscal_period = 'FY' QUALIFY ROW_NUMBER() OVER ( PARTITION BY entity_id, period_end ORDER BY accepted_at DESC ) = 1),trend AS ( SELECT entity_id, numeric_value AS ni_latest, LAG(numeric_value) OVER (PARTITION BY entity_id ORDER BY period_end) AS ni_prior FROM net_income QUALIFY ROW_NUMBER() OVER (PARTITION BY entity_id ORDER BY period_end DESC) = 1)SELECT m.symbol, m.name, m.sector, o.item_502_count, o.latest_change, ROUND(t.ni_latest / 1e6, 0) AS net_income_latest_m, ROUND(t.ni_prior / 1e6, 0) AS net_income_prior_m, ROUND((t.ni_latest - t.ni_prior) / NULLIF(ABS(t.ni_prior), 0) * 100, 1) AS ni_change_pctFROM officer_changes oJOIN members m ON m.cik = o.entity_idLEFT JOIN trend t ON t.entity_id = o.entity_idORDER BY o.item_502_count DESCLIMIT 25""" try: with ValueinClient() as client: df = client.run_query(sql) print(df)except ValueinError as e: print(f"Valuein error: {e}")Dividend Sustainability Screen
Free cash flow coverage of dividends paid, from each company's latest fiscal year, to flag dividends at risk before a cut is announced.
Show the query ↓Hide the query ↑
from valuein_sdk import ValueinClient, ValueinError sql = """WITH members AS ( SELECT r.cik, r.symbol, r.name, r.sector FROM "references" r JOIN index_membership im ON im.cik = r.cik WHERE im.index_name = 'SP500' AND im.removal_date IS NULL AND r.is_active AND r.is_primary_ticker),annual AS ( SELECT entity_id, period_end, standard_concept, numeric_value FROM fact WHERE fiscal_period = 'FY' AND standard_concept IN ('OperatingCashFlow', 'CAPEX', 'Dividends') QUALIFY ROW_NUMBER() OVER ( PARTITION BY entity_id, standard_concept, period_end ORDER BY accepted_at DESC ) = 1),latest AS ( SELECT entity_id, period_end, MAX(CASE WHEN standard_concept = 'OperatingCashFlow' THEN numeric_value END) AS ocf, MAX(CASE WHEN standard_concept = 'CAPEX' THEN numeric_value END) AS capex, MAX(CASE WHEN standard_concept = 'Dividends' THEN numeric_value END) AS dividends FROM annual GROUP BY entity_id, period_end HAVING ocf IS NOT NULL AND capex IS NOT NULL AND dividends IS NOT NULL QUALIFY ROW_NUMBER() OVER (PARTITION BY entity_id ORDER BY period_end DESC) = 1)SELECT m.symbol, m.name, m.sector, l.period_end, ROUND((l.ocf - ABS(l.capex)) / 1e6, 0) AS fcf_m, ROUND(ABS(l.dividends) / 1e6, 0) AS div_paid_m, ROUND((l.ocf - ABS(l.capex)) / NULLIF(ABS(l.dividends), 0), 2) AS fcf_div_coverageFROM latest lJOIN members m ON m.cik = l.entity_idWHERE ABS(l.dividends) > 0ORDER BY fcf_div_coverage ASC NULLS LASTLIMIT 20""" try: with ValueinClient() as client: df = client.run_query(sql) print(df)except ValueinError as e: print(f"Valuein error: {e}")Event-driven research with AI
Ask Claude to surface recent 8-K activity, cross-reference with balance sheet health, and flag companies with high event density relative to sector peers.
Build your event-driven strategy today
Free Benchmark tier — no credit card. Combine 8-K events with fundamental context in one query.
Index names are trademarks of their owners; Valuein is not affiliated with or endorsed by any index provider.