Skip to main content

Valuein Logo

PyPI version Python 3.10+ License

💎 Valuein Python SDK: Frictionless Financial Data

A high-performance toolkit for querying point-in-time US fundamentals from SEC EDGAR, built for quants, analysts, and data engineers.

The Valuein SDK, is a complete infrastructure solution for consuming point-in-time accurate US Core financial fundamentals (facts) on your daily workflow. Whether you are building complex asynchronous Python pipelines or executing templated SQL, this library provides frictionless, zero-setup access to institutional-grade data.

The Data Engine

Powered by survivorship-bias-free data containing 12M+ filings and 120.5M+ facts from 10-Ks, 10-Qs, 8-Ks, 20-Fs, 40-Fs, and amendments across 19,000+ active and delisted US companies since 1993 (the SEC EDGAR electronic-filing floor).

Why use this toolkit?

⚡ Lightning-Fast Python SDK: Execute blazing-fast queries against remote Parquet files hosted on R2, powered entirely by DuckDB under the hood. No database setup, no massive local downloads.

🛠️ Plug-and-Play SQL Templates: Skip the boilerplate. Use our pre-built SQL templates to immediately extract insights, calculate intrinsic values, or model standardized financial statements.

📚 Comprehensive Context: Deep-dive documentation mapping out table schemas, primary keys, and field definitions to support your specific financial research use cases.

🚀 Why Valuein Data and SDK Library

Easy of use and intelligence.

Feature Benefit
🕒 Point‑in‑Time Data Eliminate look‑ahead bias in backtests
⚖️ Survivorship‑Bias Free Includes bankrupt, delisted, and acquired firms
📊 Standardized Concepts ~11,966 raw XBRL tags mapped to ~292 canonical financial concepts
🚀 DuckDB SQL Engine Millisecond analytics directly in Python
☁️ Cloud Parquet Streaming No local data downloads required
🧩 Financial Templates Production‑ready investment signals
🔬 Backtest Engine Evaluate a factor in one call — look-ahead and survivorship closed by construction
🎲 Monte Carlo Seeded, reproducible simulation on your own strategy's returns
🔒 Reproducible Bundles Freeze a study's inputs and hash them, so results stay traceable

🧠 What You Can Do With This Repository

Use Case Who Where to Start
Query financial data via Python Quants, data engineers Quickstart
Call every SDK method AI agents, integrators API Reference
Backtest a factor without bias Quants, PMs Quant Cookbook
Run 57 pre-built financial signals Analysts, quants SQL Templates
Learn with interactive notebooks Students, new users Python Examples
Prove data quality to stakeholders Institutional buyers, compliance Research & Quality Proofs
Read methodology and compliance docs Due diligence, enterprise Documentation
Contribute templates, examples, research Open-source contributors Contributing

⚡ Quickstart

1. Install Package

Pick the workflow you already use — both work, no extra setup:

# Option A — pip (universal, ships with Python)
python -m venv .venv && source .venv/bin/activate
pip install valuein-sdk
# Option B — uv (10–100× faster; install from https://docs.astral.sh/uv/)
uv venv && source .venv/bin/activate
uv pip install valuein-sdk

2. Backtest a factor — no token, no signup, one command

valuein backtest mom_12m --start 2021-01-01 --end 2025-12-31 --freq ME
Backtest — 'mom_12m' | long/short | top/bottom 5 quantiles | equal-weighted
  execution lag 1 trading day(s), costs 10.0 bps per unit traded, 11.78 rebalances/yr

NET OF COSTS
  Periods             40 @ 11.78/yr
  Annualized return   -2.04%
  Annualized vol      15.41%
  Sharpe              -0.06
  Max drawdown        -23.64%
  Hit rate            62.5%

  gross annualized   -0.87%   (cost drag 1.17%)
  mean IC            +0.0076   IC-IR 0.04
  mean turnover      50.4% one-way per rebalance
  universe return    +1.22% per period (equal-weight, same universe)

EXCLUSIONS
  dates used 40 of 52 — 12 skipped for thin coverage
  names scored 450/date (71% of universe had a usable signal)
  positions truncated by delisting: 0

That is a real run on the free tier, cold, in under 7 seconds — and it is a real answer: on the 500-name sample slice, 12-month momentum did not pay after costs. The point is that you found that out in one command instead of in two weeks, and that the assumptions are printed next to the number. A Sharpe ratio quoted without its execution lag and cost assumption is not a result.

The EXCLUSIONS block is there for the same reason. It tells you what the backtest could not use — thin dates, unscored names, positions truncated by a delisting — because a study that silently drops what it cannot handle reports the survivors' returns and calls them the strategy's.

Same thing from Python, plus the diagnostics:

from valuein_sdk import ValueinClient

with ValueinClient() as client:  # no API key needed
    result = client.factor_backtest(
        "mom_12m",
        start="2021-01-01",
        end="2025-12-31",
        freq="ME",
    )
    print(result.summary())
    print(result.mean_ic, result.ic_ir)  # signal quality
    print(result.quantile_summary())  # is it monotonic?
    result.equity_curve().plot()

Look-ahead and survivorship bias are closed by construction, not by convention: the universe comes from index-membership spells so delisted companies are present on the dates they were members, and every fundamental is filtered to accepted_at <= as_of, the moment the SEC actually published it. You cannot accidentally turn them off.

→ Full quickstart · Quant cookbook

Add a token at any time to widen the universe from 500 names to 19,000+ — the code above does not change.

🔑 2. Get Your API Token

Data Plan Coverage Price Get Access
Sample S&P 500 universe, last 5 years
Active & delisted companies
Free No registration
Benchmark Full S&P 500 universe, full history (1993 → present)
Active & delisted companies
Free Register
Pro Full US universe (19,000+ entities, active + delisted)
15-year rolling point-in-time window (2011 → present)
10-K, 10-Q, 8-K, 20-F + amendments
Individual / single-seat license, no redistribution
$49 / mo · $490 / yr Subscribe
Institutional Everything in Pro plus the smart-money dataset (Forms 3/4/5/144 + 13F/13D/13G), foreign issuers, full history back to 1993, intraday accepted_at, filing-event webhooks, commercial redistribution license, business-hours SLA $499 / mo · $4,790 / yr Subscribe
Enterprise (custom) Dedicated infrastructure, zero-retention option, sub-minute filing push, multi-seat team access, white-label resale, bespoke SLA Talk to sales Contact

🔐 3. Set Your API Token

# optional — sample tier works without a key
echo 'VALUEIN_API_KEY="your_token"' >> .env

▶️ 4. Production-ready code

The ValueinClient handles authentication, table discovery, and local caching in a high-performance DuckDB instance.

The Recommended Way For Production is the Context Manager block/pattern because it ensures that temporary files and database connections are closed automatically, even if your script crashes.

from valuein_sdk import ValueinClient, ValueinError

# Two-level try/except is intentional:
#   outer = init errors (auth, manifest fetch, gateway 503 at __enter__)
#   inner = per-query errors (rate-limit, plan denial, bad SQL, validation)

try:
    with ValueinClient() as client:
        try:
            # 1) Build & run a raw SQL query → pandas DataFrame
            sql = "SELECT COUNT(cik) FROM entity"
            result_df = client.run_query(sql)
            print(result_df)

            # 2) Run a named SQL template with kwargs (the SDK quotes safely)
            df = client.run_template(
                "fundamentals_by_ticker",
                ticker="AAPL",
                start_date="2020-01-01",
                end_date="2024-01-01",
                form_types=["10-K", "10-Q"],
                metrics=["TotalRevenue", "NetIncome", "OperatingCashFlow"],
            )
            print(df)
        except ValueinError as ve:
            print(f"Query failed: {ve}")
except Exception as e:
    print(f"Initialization failed: {e}")

🧰 API Reference

Everything below is importable from the top-level package (from valuein_sdk import ...) and fully type-hinted with help()-ready docstrings — so an LLM reading the signatures can call it correctly on the first try.

Company identifiers: ticker OR CIK, anywhere you see ticker/tickers. A ticker ("AAPL", "BRK.B") resolves through references, preferring active listings. A CIK ("0000714154", "714154", or the int 714154 — any of the three) is used directly — it never touches references, so it resolves even for a delisted/inactive company whose ticker was retired or later recycled by an unrelated issuer (DEC used to be Digital Equipment; today it's Diversified Energy). Mixed lists work: client.prices(["AAPL", "0000714154", 320193]). Call client.resolve(identifiers) to see exactly what each one matched (symbol, name, is_active, matched_by) before it feeds a backtest.

ValueinClient(as_of=None, api_key=None, gateway_url=None, tables=None, config=None)

Method Returns What it does
Querying
run_query(sql) DataFrame Run read-only DuckDB SQL (SELECT / WITH / EXPLAIN only). PIT-filtered via the views.
run_template(name, **params) DataFrame Run a named SQL template from queries/ with validated, injection-safe params.
read_table(table, *, columns=None, limit=None, tickers=None) DataFrame Recommended whole-table read — PIT-safe, loads on demand, optional column/row subset. tickers accepts CIKs too and fetches only those companies' per-CIK partitions.
get(table) DataFrame Lower-level: download a table's raw Parquet (does not apply the as_of filter).
to_arrow(sql) pyarrow.Table Zero-copy Arrow output (Spark/Polars hand-off).
to_polars(sql) polars.DataFrame Zero-copy Polars output (needs pip install valuein-sdk[polars]).
stream(sql, batch_size=10_000) Iterator[DataFrame] Chunked iteration for results too large to materialize.
Typed helpers
factor_scores(ticker=None, sector=None, min_composite_rank=None, limit=100) DataFrame Cross-sectional factor scores + percentile ranks.
earnings_signals(ticker=None, min_surprise_pct=None, direction=None, limit=100) DataFrame EPS trend / surprise + YoY revenue change.
pit_universe(as_of_date, index="SP500", as_of_basis="effective") DataFrame Survivorship-free index members on a historical date.
Quant research (see the cookbook)
factor_backtest(signal, *, start, end, freq="ME", ...) BacktestResult Universe → signal → forward returns → quantile backtest, in one call. Look-ahead-free and survivorship-free by construction.
universe(index_name="SP500", *, start, end, freq) DataFrame Index membership resolved at each rebalance date — delisted and acquired companies included.
signal_panel(universe, *, ratios=, concepts=, factors=, momentum_months=) DataFrame (date × member) panel where every value is the latest vintage with accepted_at <= date.
forward_returns(panel, *, execution_lag=1) DataFrame Realized return to the next rebalance, delisting-aware (truncated / entry_stale flags).
trading_days(start, end) / rebalance_dates(start, end, freq=) DatetimeIndex / list[str] Calendars derived from the actual bars — no hardcoded holiday table.
write_bundle(path, *, tables, ...) BundleManifest Freeze a PIT slice to Parquet with a SHA-256 per file.
ValueinClient.from_bundle(path) ValueinClient Replay a bundle offline; every hash verified before mounting.
Market data
prices(tickers) PriceQuery Lazy daily-bar builder — .between(), .fields(), .last(), .to_pandas()/.to_arrow()/.to_polars().
total_return(ticker, start, end, *, basis="total_return") float Splits and dividends, counted once.
price_panel(tickers, start, end, *, field="total_return") DataFrame Wide matrix, one column per ticker.
pit_panel(tickers, dates, *, concepts=) DataFrame Last knowable price + fundamentals per (ticker, date) cell.
price_health() dict Coverage and integrity of your tier's price data.
Introspection
resolve(identifiers) DataFrame What each ticker/CIK matched — cik, symbol, name, is_active, matched_by.
me() dict Plan, status, email for the current token.
manifest() / refresh_manifest() dict Snapshot metadata (5-min cache / force-refresh).
health() dict Gateway health.
tables() list[str] Loaded table names.
list_templates() list[str] Every runnable SQL template name (pass to run_template).
filing_links(ticker, ...) DataFrame SEC EDGAR provenance links per filing — inline-XBRL viewer, rendered document, and filing-index URLs for auditor click-through.
get_schema(table) dict[str, str] Column → DuckDB type for any known table.
cache_info() dict Where the on-disk cache is, how big it is, and whether hits are revalidated.
clear_cache(*, table=None, all_plans=False) dict Delete cached Parquet and force the next read to refetch.
Document generation (Pro+ — proxies to the MCP server)
generate_dcf_xlsx(ticker, *, as_of_date=None, depth="standard") dict DCF workbook → 15-min presigned download URL.
generate_research_brief_docx(ticker, *, as_of_date=None, depth="full", peers=None) dict Institutional research brief .docx.
generate_comps_xlsx(ticker, *, peers=None, as_of_date=None) dict Peer-comparables workbook.
Feedback (every tier — no token required)
report_issue(message, *, category="bug", severity=None, subject=None, fact_id=None, ticker=None, expected_value=None) FeedbackReceipt File a bug / feature request / data-quality report straight from the SDK — see Reporting a Data Issue.
Lifecycle
close() / with ValueinClient() as c: — Release DuckDB + HTTP resources (use the context manager).

The on-disk cache

Downloaded Parquet is cached under ~/.cache/valuein-sdk (override with ValueinConfig(cache_dir=...)) so a second process starts warm instead of re-downloading. Two things keep it honest, and both are automatic:

  • Hits are revalidated. Before a cached object is served, the SDK checks its ETag against the published one — a single body-free HEAD per object per session. Most publishes land under a new snapshot_YYYYMMDD prefix, which a cache addressed by snapshot name already sees; but some do not — a same-day re-publish and a targeted fix both rewrite objects inside the live prefix. Those are usually bug fixes, and a name-addressed cache would hide exactly the correction you were waiting for. The check fails open: if the gateway cannot be reached, you get the cached bytes rather than an error. Turn it off for a deliberately frozen read with ValueinConfig(cache_revalidate=False).
  • Superseded snapshots are pruned when a client starts, so the cache does not accumulate a copy of every dataset you have ever read.

You should not need to clear it. If you want to anyway:

valuein cache stats                 # where it is, how big it is
valuein cache clear                 # all of it
valuein cache clear --table fact    # just one table
client.clear_cache(table="fact")  # {'entries': 1, 'bytes': 189384807}
client.cache_info()  # root, size, snapshot, revalidate policy

The CLI commands talk to no gateway and need no API key — they are meant to work on the plane, on an expired token, and during an outage.

Alpha framework

from valuein_sdk import AlphaEngine, ROE, GROSS_MARGIN, CURRENT_RATIO

with ValueinClient() as client:
    result = (
        AlphaEngine(client)
        .add_factors(ROE, GROSS_MARGIN, CURRENT_RATIO)
        .compute(as_of="2024-01-01")
    )
    top = result.rank().combine()  # composite cross-sectional score
    print(top.head())

Built-ins: ROE, GROSS_MARGIN, OPERATING_MARGIN, NET_PROFIT_MARGIN, REVENUE_GROWTH_YOY, FCF_TO_ASSETS, DEBT_TO_EQUITY, ASSET_TURNOVER, CURRENT_RATIO, PIOTROSKI_F_SCORE (all in BUILTIN_FACTORS). Define your own with AlphaFactor.

One token, four channels

Your Stripe-issued Bearer token unlocks every Valuein surface at your tier — no per-channel billing:

Channel How Best for
Python SDK (this package) pip install valuein-sdk Heavy out-of-core DuckDB compute
MCP server mcp.valuein.biz/mcp AI agents (Claude, Cursor, Codex) — reasoning + 50+ tools
Bulk Data API GET data.valuein.biz/v1/{plan}/{table} Direct HTTP / partner integrations (raw Parquet streams)
Web dashboard / Workspace valuein.biz Browser analysis, theses, watchlists, reports

The SDK is the Muscle (compute); the MCP server is the Nervous System (reasoning). The generate_* methods above are the bridge — they let SDK power users reach the MCP's document-generation tools without writing a JSON-RPC client.


🗂️ Data Schema

The authoritative schema is embedded in each tier's R2 manifest.json (written by data-pipeline/run_exports.py). The SDK fetches it at init and exposes the active version via client.get_schema(table) — there is no bundled schema file in this package. Use print(client.get_schema("fact")) to inspect column types live.

Current snapshot: schema v3.0.0, 22 tables (14 core on every tier + 6 smart-money and 2 Form ADV tables on the Institutional tier). The exact column list for any table is live in the manifest — run client.get_schema("fact"). Intrinsic value has no precomputed table — the valuation table was removed 2026-09-14; compute it on demand via the MCP compute_dcf tool with your own WACC / terminal growth / horizon assumptions. Parameter-free price multiples (pe_ratio, pb_ratio, ev_ebitda, dividend_yield, market_cap, graham_number, ncav_per_share) still ship precomputed under ratio.category = 'valuation'.

Table Description Records
references Start here. Flat join of entity + security (one row per security) with cik, symbol, name, sector, industry, sic_code, is_active, FIGI. For index membership (current OR historical) JOIN index_membership on cik = cik. There is no is_sp500 flag — it was dropped 2026-05-02 because it was snapshot-only and single-index. 19K+
entity Company metadata. business_address + mailing_address, sic_description, state_of_incorporation_description, country_code, is_foreign, flags, has_insider_transactions, is_insider_owner, former_names (JSON). 19K+
security Ticker history (SCD Type 2). is_primary_ticker for multi-share-class issuers (BRK-A/BRK-B, GOOG/GOOGL). 19K+
filing Filing metadata since 1993. is_xbrl_numeric flags filings whose XBRL exhibit carries numeric facts; superseded_by chains the amendment lineage; core_type strips /A for form-family filtering. 12M+
fact Standardized financial facts. Bloomberg Option-C restatement columns (value_current, value_as_filed, first_filed_at, restated), quality columns (confidence_score — filter >= 0.95 for Bloomberg-grade; reliability_code 1–4), accounting_standard (US-GAAP/IFRS), reporting_currency, and PIT semantics via accepted_at. 120.5M+
ratio Pipeline-computed financial ratios per entity per fiscal period (ratio_name, category, value, fiscal_period, is_ttm, confidence_score, computed_at). Holds both annual (fiscal_period='FY', is_ttm=false) and trailing-twelve-month (fiscal_period='TTM', is_ttm=true) rows per company — TTM is the most-current trailing read (latest quarter close). 164 unique ratio_names: profitability 32, leverage 14, efficiency 15, per_share 11, liquidity 5 (all five have TTM), forensic 5, growth/CAGR 60, sector-percentile 22 — category='rank' (these three are annual-only). ⚠️ A raw read_table('ratio') query that does not filter is_ttm / fiscal_period double-counts each metric — always WHERE is_ttm = FALSE (or fiscal_period = 'FY'); the SDK's financial_ratios_* templates already filter and are safe. Full ratio-name catalog in SQL_CHEATSHEET.md. Recomputed each run; freshness via computed_at. 10M+
standard_concept Curated gold-standard concept catalog — the dictionary for fact.standard_concept. Carries level, statement_type, definition, unit_default, bloomberg_equivalent, factset_equivalent. The cpa_verified_concepts template surfaces CPA-reviewed concepts via review_confidence as that field rolls out (v3.4.0). ~292
taxonomy_guide Raw SEC us-gaap tag reference for the fact.concept column (human_name, definition, balance_type, level). ~11,966
index_membership Survivorship-free index constituents — SP500, RUSSELL1000, RUSSELL2000, RUSSELL3000. Keyed on cik (since migration 0015 — same column name as references.cik). effective_date / removal_date use [) interval semantics; carries removal_reason, successor_cik, source, confidence. announcement_date / removal_announcement_date exist in the schema but are not populated (NULL on every row, by decision) — pit_universe(as_of_basis="announcement") refuses rather than return an empty universe. 4 indices
factor_scores Cross-sectional factor scores + percentile ranks (10 factors + composite_rank) from recent annual filings. 1M+
earnings_signals Trailing earnings-trend estimate + EPS surprise %, plus YoY revenue change. 500K+
stock_price Coarse EOD price pre-aggregation of stock_price_daily, on every tier: one row per entity at each period_end plus monthly closes (observation = 'period_end' | 'monthly'), each carrying the priced listing's total_return_index (schema 3.3.0) — so tri_b / tri_a - 1 between two month-end rows is the total return for that span, dividends between the month-ends included. No OHLC/volume/adjusted_close — exists so valuation overlays, price-derived ratios and monthly-rebalanced backtests never need a daily-bar scan. Resolved to the issuer's primary listing before alignment, with security_id/symbol recording which, so a P/E is auditable back to the share class it was computed from. PIT via accepted_at (the market-close stamp). 19K+ entities
stock_price_daily Pro and Institutional only (schema 3.3.0, 2026-09-17) — the free tiers do not carry the daily series (licensed market data; a free-plan read raises ValueinDataError naming the plan). Daily OHLCV bars, 1994 onward (tier-windowed): open/high/low/close, adjusted_close, volume, div_cash, split_factor, plus security_id/symbol/is_primary_listing/total_return_index (schema 2.29.0). ⚠️ Grain is one row per (SECURITY, day), not per company — an issuer with two listings contributes two rows, so partition on security_id or filter is_primary_listing. ⚠️ For return math use total_return_index, not adjusted_close (the vendor populates it on ~2% of bars) and never raw close (a 4-for-1 split reads −75%). The SDK's price_field="total_return" does this for you. ⚠️ Prices are licensed market data, not EDGAR, so they do NOT share the 1993 fundamentals floor — the earliest bar differs per security and is 1994 or later. 1994→ daily
restatement_events Restatement Radar — every fact a later SEC filing materially changed, back to 1993, as a before/after diff with both accessions deep-linked. disclosure_class = non_reliance (a real 8-K Item 4.02) | amended (10-K/A, 10-Q/A) | undisclosed (changed inside a routine filing). Available on every tier including anonymous guest. 150K events
insider_party · insider_filing · insider_transaction · institutional_filing · institutional_holding · insider_ownership Smart-money dataset — Forms 3/4/5/144 + 13F-HR + SC 13D/13G. Institutional / full plan only. FULL tier
investment_adviser · investment_adviser_private_fund SEC Form ADV Part 1A / Schedule D 7.B.(1) — RIA firm profiles + private funds. CRD-keyed, not CIK-keyed (advisers file into FINRA-operated IARD); cik is a nullable soft link on ~26% of filers. ⚠️ Items 5.A–5.F are absent for Exempt Reporting Advisers (a different filing obligation, not missing data); raum_total is structurally double-counted across sub-advisory relationships — per-firm only, never aggregate. Institutional / full plan only. FULL tier

🔗 Key Joins

references.cik                  →  entity.cik  (references is the fast entry point)
security.entity_id              →  entity.cik
filing.entity_id                →  entity.cik
fact.entity_id                  →  entity.cik
fact.accession_id               →  filing.accession_id
index_membership.cik            →  entity.cik   (same column name on both sides
                                                 since migration 0015 — JOIN as
                                                 references.cik = im.cik)

🎯 Survivorship-free PIT universe (the canonical backtest pattern)

-- All SP500 members on a historical as_of_date, resolved to active ticker.
-- index_membership keys on `cik` (since pipeline migration 0015) — same column
-- name as references.cik / entity.cik, so the join read straight across.
SELECT m.cik, s.id AS security_id, s.symbol AS ticker_at_date,
       e.name AS company_name, m.effective_date, m.removal_date, m.confidence
FROM index_membership m
JOIN entity e ON e.cik = m.cik
LEFT JOIN security s ON s.entity_id = m.cik
    AND s.is_primary_ticker = TRUE
    AND $as_of_date >= s.valid_from
    AND $as_of_date <  COALESCE(s.valid_to, '9999-12-31'::DATE)
WHERE m.index_name = 'SP500'
  AND $as_of_date >= m.effective_date
  AND $as_of_date <  COALESCE(m.removal_date, '9999-12-31'::DATE);

LEFT JOIN security so delisted companies still surface (ticker_at_date = NULL). is_primary_ticker = TRUE pins multi-share-class issuers to one row per CIK — universe count stays at ~500 even when BRK-A and BRK-B both exist in security. [) semantics — a company removed on 2017-06-19 is NOT a member ON 2017-06-19.

⚡ DuckDB Query Patterns

Three patterns that eliminate redundant joins and scans on every cross-company query:

1. references replaces the entity + security join; index_membership stays separate

-- Filter current S&P 500 tech companies (membership lives in index_membership).
-- The previous references.is_sp500 flag was dropped 2026-05-02 — both
-- snapshot-only and single-index, two footguns avoided by JOIN-on-membership.
SELECT 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.sector ILIKE '%technology%'
  AND  r.is_active     = TRUE

2. LATERAL for the latest filing per company

JOIN LATERAL (
  SELECT accession_id, filing_date
  FROM   filing
  WHERE  entity_id = r.cik AND form_type = '10-K'
  ORDER  BY filing_date DESC
  LIMIT  1
) f ON true

3. Pivot multiple concepts in one fact scan

-- Debt + equity in one pass — no self-join
SELECT
  MAX(CASE WHEN standard_concept = 'LongTermDebt'       THEN numeric_value END) AS debt,
  MAX(CASE WHEN standard_concept = 'StockholdersEquity' THEN numeric_value END) AS equity
FROM fact WHERE standard_concept IN ('LongTermDebt', 'StockholdersEquity')
GROUP BY accession_id

For quarterly cash flow metrics, use COALESCE(derived_quarterly_value, numeric_value) — Q2/Q3 10-Qs report YTD; this column isolates the single quarter.

See valuein_sdk/queries/SQL_CHEATSHEET.md for 8 complete patterns including FCF screens, PIT backtesting, and restatement auditing.


🏷️ Standard Concept Names

📅 Date Columns Reference

Column Table Use for
report_date / period_end filing / fact Aligning to fiscal calendar
filing_date filing PIT backtest filter — when the SEC received the filing
accepted_at fact Millisecond-precision PIT for intraday signal research

🧩 Template Categories

57 templates ship in valuein_sdk/queries/, auto-discovered by filename. Run any of them with client.run_template("<name>", ...):

Category Templates (examples)
Data Access fundamentals_by_ticker, figi_to_fundamentals_mapping, peer_group_comparison, survivorship_bias_free_screen
Income Statement revenue_yoy_growth, trailing_twelve_months_ttm, margin_analysis, free_cash_flow, rnd_intensity
Balance Sheet liquidity_ratios, solvency_debt_to_equity, interest_coverage, efficiency_cash_conversion, capex_to_revenue
Investment Scores dupont_analysis_inputs, piotroski_f_score_inputs, altman_z_score_inputs, earnings_quality_accruals_anomaly
Valuation & Screening sector_relative_valuation_outperformers, financial_ratios_screener, shareholder_dilution, factor_screen_top_quintile
Smart-money & Ownership (FULL tier) insider_buys, blockholders, top_institutional_holders, manager_portfolio
Event & Short Signals late_reporter_short_signal, restatement_history, 8k_material_event_signal, ghost_company_screener
Advanced Analytics true_point_in_time_backtest_engine, time_series_outlier_detection_zscore, seasonal_frame_based_extraction, cpa_verified_concepts

See valuein_sdk/queries/SQL_CHEATSHEET.md for the full reference with copy-paste DuckDB patterns.

📚 Documentation

Document Description Where
Methodology Data sourcing, PIT architecture, restatement handling, XBRL normalization valuein.biz/docs · public hub
Compliance & DDQ Data provenance, MNPI policy, PIT integrity, security, SLA summary public hub
SLA Uptime targets, data freshness SLAs, support response times valuein.biz/sla
Data Catalog Every column, type, definition, sample value public hub DATA_CATALOG.xlsx
Live schema Machine-readable schema for the active snapshot client.get_schema("<table>") — read from the R2 manifest at runtime

🐍 Python Examples

Standalone Python scripts and ten Jupyter notebooks, designed to go from install to insight in under 3 minutes.

Ticker lookup example

Run any SQL against the data lake. No downloads. No local database. DuckDB executes your queries in-process.

from valuein_sdk import ValueinClient

client = ValueinClient(tables=["entity", "security"])
# This client only fetch these 2 tables, making it faster!

df = client.run_query("""
    SELECT e.cik, e.name, e.sector, e.status,
           s.symbol, s.exchange
    FROM   security s
    JOIN   entity   e ON s.entity_id = e.cik
    WHERE  s.symbol = 'AAPL' AND s.is_active = TRUE
""")
print(df)

You are now querying SEC financial statements directly from the cloud.

Python scripts (examples/python/)

Script Level What it demonstrates
getting_started.py Beginner Auth check, first query, entity counts by sector
usage.py Reference Every public SDK method demonstrated end to end
production-ready.py Reference Context-manager pattern, config, full error hierarchy
entity_screening.py Beginner Screen by sector, SIC code, active vs inactive status
financial_analysis.py Intermediate Revenue trends, margins, concept normalization, peer comparison
pit_backtest.py Intermediate Correct PIT discipline, restatement impact, filing_date vs report_date
survivorship_bias.py Intermediate Delisted/bankrupt companies, index_membership, bias quantification

Jupyter notebooks (notebooks/)

Notebook Open in Colab
01_quickstart Open in Colab
02_dcf_valuation Open in Colab
03_piotroski_screen Open in Colab
04_earnings_quality Open in Colab
05_factor_backtest Open in Colab
06_sector_comparison Open in Colab
07_restatement_alpha Open in Colab
08_capital_allocation Open in Colab
09_filing_delay Open in Colab
10_survivorship_demo Open in Colab

🛡️ Error Handling

from valuein_sdk import (
    ValueinAuthError,  # HTTP 401/403 — invalid or expired token
    ValueinPlanError,  # HTTP 403 — endpoint requires a higher plan
    ValueinNotFoundError,  # HTTP 404 — no table found
    ValueinRateLimitError,  # HTTP 429 — includes .retry_after (seconds)
    ValueinAPIError,  # HTTP 5xx — includes .status_code
    ValueinClient,
)

client = None
try:
    client = ValueinClient()
    df = client.run_query("SELECT * FROM fact LIMIT 1000000")
except ValueinAuthError:
    print("Check your VALUEIN_API_KEY. It might be expired or invalid.")
except ValueinPlanError:
    print("This requires a higher-tier plan. Upgrade at valuein.biz.")
except ValueinRateLimitError as e:
    print(f"Slow down! Retry allowed in {e.retry_after}s.")
except ValueinNotFoundError as e:
    print(f"That table or endpoint doesn't exist: {e}")
except ConnectionError as e:
    print(f"Physical network issue: {e}")
except ValueinAPIError as e:
    print(f"The Gateway is having a bad day (Status {e.status_code}).")
except Exception as e:
    print(f"Non-SDK error (Python/Logic): {e}")
finally:
    # Always close manually if not using a context manager and if a client was created.
    if client is not None:
        client.close()

📮 Reporting a Data Issue

Found a stale figure, a bad citation, or a rough edge? report_issue() files it straight to the Valuein team over the MCP submit_feedback tool — no API token required, so it works even in sample mode. Pass ticker and/or fact_id when you have them so the report is checkable against the source filing.

from valuein_sdk import FeedbackError, ValueinClient

client = ValueinClient()  # works even with no API key
try:
    receipt = client.report_issue(
        "get_financial_ratios returns a stale P/E for AAPL",
        category="data_quality",  # "bug" | "feature_request" | "experience" | "data_quality" | "other"
        ticker="AAPL",
        fact_id="3f9c1a2b...",
        expected_value="24.1",
    )
    print(receipt.feedback_id, receipt.status)  # e.g. "fb_9f2c...", "open"
except FeedbackError as e:
    print(f"Valuein rejected the report: {e}")

🔬 Research & Quality Proofs

The ten notebooks double as runnable due-diligence proofs — PIT correctness, survivorship-bias quantification, restatement alpha, and balance-sheet identity checks — all against live data. Install the research extras to run them locally:

# pip
pip install "valuein-sdk[research]"
# uv (dev workflow)
uv sync --group research

For institutional due-diligence material (methodology, compliance/DDQ, SLA, and the full reproducible research suite) see the open-source hub at github.com/valuein/valuein.


🤝 Contributing

We welcome contributions including SQL templates, notebooks, scripts, research modules, and documentation improvements.

See CONTRIBUTING.md for code standards, naming conventions, and the PR process.

📄 License

Apache-2.0 License — see LICENSE.

Disclosure: This repository is for research and educational purposes only and does not constitute financial advice.

Metadata

Release files for valuein-sdk 5.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for valuein-sdk 5.4.0
File Size Uploaded
valuein_sdk-5.4.0.tar.gz 249.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for valuein-sdk 5.4.0
File Interpreter ABI Platform
valuein_sdk-5.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 551.2 kB

Release files / valuein_sdk-5.4.0.tar.gz

Download URL valuein_sdk-5.4.0.tar.gz
Size 249.9 kB
Tags Source
SHA-256 checksum
How to use checksums
b13e0a9726133d3483f48e342568dc42a97a159607fcfba90704984c47672db4
BLAKE2b-256 checksum
How to use checksums
8ab0ae251360895024bc1a2142b841c0547070d082dd914d0398de003f2cea03
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 28, 2026.

Transparency log

Release files / valuein_sdk-5.4.0-py3-none-any.whl

Download URL valuein_sdk-5.4.0-py3-none-any.whl
Size 301.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f389a51c98101c8123e535add38c053b3818b57002e8cafa633a731dfc076a81
BLAKE2b-256 checksum
How to use checksums
110a93be973b9d7a020af07141b5e9996b04789e309225d9d2cb554a974c5d6a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 28, 2026.

Transparency log

Release history Release notifications | RSS feed

6.0.0

2 release files

5.4.1

2 release files

This release

5.4.0 This release

2 release files

5.3.0

2 release files

5.2.0

2 release files

5.1.0

2 release files

5.0.0

2 release files

4.1.0

2 release files

4.0.0

2 release files

3.8.0

2 release files

3.7.1

2 release files

3.6.0

2 release files

3.5.1

2 release files

3.4.0

2 release files

3.3.1

2 release files

3.3.0

2 release files

3.2.0

2 release files

3.1.0

2 release files

3.0.1

2 release files

3.0.0

2 release files

2.4.1

2 release files

2.4.0

2 release files

2.3.0

2 release files

2.2.1

2 release files

2.1.0

2 release files

2.0.3

2 release files

2.0.0

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.7

2 release files

0.7.6

2 release files

0.7.5

2 release files

0.7.4

2 release files

0.7.3

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.4

2 release files

0.6.3

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.8

2 release files

0.5.6

2 release files

0.5.5

2 release files

0.5.4

2 release files

0.5.3

2 release files

0.5.2

2 release files

0.5.0

2 release files

0.4.1

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.2.2

2 release files

0.2.0

2 release files

0.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page