10-QQuarterly momentum. Before the crowd.
10-Q filings are filed three times per year — for Q1, Q2, and Q3 — making them the primary source of intra-year earnings momentum signals. Beat-and-raise patterns, working capital inflection, and gross margin inflection all show up here first.
- Q1–Q3 unaudited financials for 28,000+ companies
- QoQ and YoY growth calculations with single-query pivots
- Amendment tracking — 10-Q/A restated values vs original
- accepted_at timestamps for point-in-time backtesting
- YTD cash flow corrections via derived_quarterly_value
A note on cash flow in 10-Q filings
The SEC requires Q2 and Q3 cash flow statements to be reported on a year-to-date basis. Valuein automatically computes the quarter-specific (incremental) cash flow and stores it in derived_quarterly_value. There is no Q4 10-Q: on the FY row, the same column holds Q4.
Always use COALESCE(derived_quarterly_value, numeric_value) for cash flow metrics in 10-Q queries to get the correct quarterly figure rather than the YTD cumulative.
SQL queries that deliver alpha
Production-ready queries using ValueinClient. Copy, run, adapt to your strategy.
Earnings Momentum — QoQ and YoY Revenue Growth
Latest quarter's revenue against the previous quarter and the same quarter a year earlier. Quarter-only values come from derived_quarterly_value, so year-to-date filings and the Q4 implied by the 10-K line up; companies with gaps in their history are skipped.
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),quarters AS ( -- Quarter-only revenue: Q2/Q3 may be filed year-to-date and the FY row -- carries Q4, so read derived_quarterly_value first. SELECT entity_id, period_end, COALESCE(derived_quarterly_value, numeric_value) AS revenue FROM fact WHERE standard_concept = 'TotalRevenue' AND fiscal_period IN ('Q1', 'Q2', 'Q3', 'FY') AND (fiscal_period <> 'FY' OR derived_quarterly_value IS NOT NULL) -- FY only for its Q4 QUALIFY ROW_NUMBER() OVER ( PARTITION BY entity_id, period_end ORDER BY accepted_at DESC ) = 1),growth AS ( SELECT *, LAG(revenue, 1) OVER (PARTITION BY entity_id ORDER BY period_end) AS prev_qtr_rev, LAG(revenue, 4) OVER (PARTITION BY entity_id ORDER BY period_end) AS same_qtr_prior_yr, -- gaps in the history would compare the wrong quarters: keep only clean runs period_end - LAG(period_end, 1) OVER (PARTITION BY entity_id ORDER BY period_end) AS days_to_prev, period_end - LAG(period_end, 4) OVER (PARTITION BY entity_id ORDER BY period_end) AS days_to_year_ago FROM quarters QUALIFY ROW_NUMBER() OVER (PARTITION BY entity_id ORDER BY period_end DESC) = 1)SELECT m.symbol, m.name, m.sector, g.period_end, ROUND(g.revenue / 1e6, 1) AS revenue_m, ROUND((g.revenue / NULLIF(g.prev_qtr_rev, 0) - 1) * 100, 1) AS qoq_growth_pct, ROUND((g.revenue / NULLIF(g.same_qtr_prior_yr, 0) - 1) * 100, 1) AS yoy_growth_pctFROM growth gJOIN members m ON m.cik = g.entity_idWHERE g.days_to_prev BETWEEN 80 AND 100 AND g.days_to_year_ago BETWEEN 350 AND 380 AND g.revenue / NULLIF(g.same_qtr_prior_yr, 0) > 1.10 AND g.revenue / NULLIF(g.prev_qtr_rev, 0) > 1.0ORDER BY yoy_growth_pct DESCLIMIT 25""" try: with ValueinClient() as client: df = client.run_query(sql) print(df)except ValueinError as e: print(f"Valuein error: {e}")Beat-and-Raise Pattern Detector
Companies whose diluted EPS beat the same quarter a year earlier in each of their last three 10-Qs — a programmatic beat-and-raise signal derived purely from filed data.
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),eps_qtrs AS ( -- Diluted EPS as filed in 10-Qs. EPS is not additive, so there is no -- derived Q4: compare each fiscal quarter with the same quarter a year earlier. SELECT entity_id, period_end, fiscal_period, numeric_value AS eps_diluted FROM fact WHERE standard_concept = 'EPSDiluted' AND fiscal_period IN ('Q1', 'Q2', 'Q3') AND period_span_days BETWEEN 80 AND 100 -- three-month figures only QUALIFY ROW_NUMBER() OVER ( PARTITION BY entity_id, period_end ORDER BY accepted_at DESC ) = 1),yoy AS ( SELECT *, LAG(eps_diluted) OVER (PARTITION BY entity_id, fiscal_period ORDER BY period_end) AS eps_year_ago, ROW_NUMBER() OVER (PARTITION BY entity_id ORDER BY period_end DESC) AS recency FROM eps_qtrs),streak AS ( SELECT entity_id, MAX(period_end) AS latest_quarter, ARG_MAX(eps_diluted, period_end) AS eps_latest, ARG_MAX(eps_year_ago, period_end) AS eps_year_ago FROM yoy WHERE recency <= 3 GROUP BY entity_id HAVING COUNT(*) = 3 AND BOOL_AND(eps_diluted > eps_year_ago) -- up year over year, three quarters running)SELECT m.symbol, m.name, s.latest_quarter, ROUND(s.eps_latest, 2) AS eps_latest, ROUND(s.eps_year_ago, 2) AS eps_year_ago, ROUND((s.eps_latest / NULLIF(s.eps_year_ago, 0) - 1) * 100, 1) AS yoy_growth_pctFROM streak sJOIN members m ON m.cik = s.entity_idWHERE s.eps_year_ago > 0ORDER BY yoy_growth_pct DESCLIMIT 20""" try: with ValueinClient() as client: df = client.run_query(sql) print(df)except ValueinError as e: print(f"Valuein error: {e}")Working Capital Deterioration Signal
Working capital (current assets minus total current liabilities) down two quarters running — a leading indicator of liquidity stress before it becomes a headline.
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),balances AS ( -- Balance-sheet values are point-in-time, so every quarter-end row counts. SELECT entity_id, period_end, standard_concept, numeric_value FROM fact WHERE standard_concept IN ('CurrentAssets', 'TotalCurrentLiabilities') QUALIFY ROW_NUMBER() OVER ( PARTITION BY entity_id, standard_concept, period_end ORDER BY accepted_at DESC ) = 1),wc AS ( SELECT entity_id, period_end, MAX(CASE WHEN standard_concept = 'CurrentAssets' THEN numeric_value END) - MAX(CASE WHEN standard_concept = 'TotalCurrentLiabilities' THEN numeric_value END) AS working_capital FROM balances GROUP BY entity_id, period_end HAVING working_capital IS NOT NULL),trend AS ( SELECT *, LAG(working_capital, 1) OVER (PARTITION BY entity_id ORDER BY period_end) AS wc_q1_ago, LAG(working_capital, 2) OVER (PARTITION BY entity_id ORDER BY period_end) AS wc_q2_ago FROM wc QUALIFY ROW_NUMBER() OVER (PARTITION BY entity_id ORDER BY period_end DESC) = 1)SELECT m.symbol, m.name, t.period_end, ROUND(t.working_capital / 1e6, 0) AS wc_latest_m, ROUND(t.wc_q1_ago / 1e6, 0) AS wc_q1_ago_m, ROUND(t.wc_q2_ago / 1e6, 0) AS wc_q2_ago_mFROM trend tJOIN members m ON m.cik = t.entity_idWHERE t.working_capital < t.wc_q1_ago AND t.wc_q1_ago < t.wc_q2_agoORDER BY wc_latest_m ASCLIMIT 20""" try: with ValueinClient() as client: df = client.run_query(sql) print(df)except ValueinError as e: print(f"Valuein error: {e}")Gross Margin Compression — Sector Benchmarks
Average quarter-only gross margin by sector for the last 18 months, bucketed by calendar quarter so different fiscal calendars line up. Banks and REITs drop out: gross margin does not describe their business.
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),quarters AS ( SELECT entity_id, period_end, standard_concept, COALESCE(derived_quarterly_value, numeric_value) AS quarter_value FROM fact WHERE standard_concept IN ('GrossProfit', 'TotalRevenue') AND fiscal_period IN ('Q1', 'Q2', 'Q3', 'FY') AND (fiscal_period <> 'FY' OR derived_quarterly_value IS NOT NULL) -- FY only for its Q4 AND period_end >= current_date - INTERVAL 18 MONTH QUALIFY ROW_NUMBER() OVER ( PARTITION BY entity_id, standard_concept, period_end ORDER BY accepted_at DESC ) = 1),per_company AS ( SELECT entity_id, period_end, MAX(CASE WHEN standard_concept = 'GrossProfit' THEN quarter_value END) / NULLIF(MAX(CASE WHEN standard_concept = 'TotalRevenue' THEN quarter_value END), 0) AS gross_margin FROM quarters GROUP BY entity_id, period_end)SELECT m.sector, date_trunc('quarter', p.period_end) AS calendar_quarter, ROUND(AVG(p.gross_margin) * 100, 1) AS avg_gross_margin_pct, COUNT(*) AS companiesFROM per_company pJOIN members m ON m.cik = p.entity_idWHERE p.gross_margin BETWEEN 0 AND 1 -- banks and REITs have no meaningful gross marginGROUP BY m.sector, calendar_quarterORDER BY m.sector, calendar_quarter""" try: with ValueinClient() as client: df = client.run_query(sql) print(df.pivot_table(index="sector", columns="calendar_quarter", values="avg_gross_margin_pct"))except ValueinError as e: print(f"Valuein error: {e}")Natural language over quarterly data
The Valuein MCP server connects Claude and other AI assistants to your 10-Q dataset. Ask plain-English questions about quarterly momentum, beat-and-raise patterns, and sector trends — no SQL required.
Catch earnings acceleration before the crowd
Free Benchmark tier — no credit card. From install to DataFrame in 60 seconds.
Index names are trademarks of their owners; Valuein is not affiliated with or endorsed by any index provider.