TL;DR
Use this table for end-of-day stock and ETF prices, then inspect coverage before choosing the newest session. Dividend yield is stored as a percentage, and market capitalization uses unadjusted price with eligible shares; missing values remain missing. Split-adjusted closing prices cannot substitute in that calculation. Historical ticker changes and reused symbols require date-aware security mapping, while ETF rows can have prices without company fundamentals.
- Query name
- lake.sec_daily_ohlc
- Storage partition
- year
- Columns
- 30
Columns and types
VARCHAR
- ticker
- symbol
TIMESTAMP
- date
DOUBLE
- openingPrice
- highestPrice
- lowestPrice
- closingPrice
- volume
- marketCap
- peRatioTTM
- psRatioTTM
- pbRatioTTM
Showing 12 of 30 recorded rows. The complete table is below.
Current logical schema for lake.sec_daily_ohlc
Inspect the complete lake.sec_daily_ohlc schema
Scroll sideways to compare all columns. Select a heading to sort.
| ticker | VARCHAR |
| symbol | VARCHAR |
| date | TIMESTAMP |
| openingPrice | DOUBLE |
| highestPrice | DOUBLE |
| lowestPrice | DOUBLE |
| closingPrice | DOUBLE |
| volume | DOUBLE |
| marketCap | DOUBLE |
| peRatioTTM | DOUBLE |
| psRatioTTM | DOUBLE |
| pbRatioTTM | DOUBLE |
| enterpriseValue | DOUBLE |
| dividendYield | DOUBLE |
| unadjustedClose | DOUBLE |
| companyMarketCap | DOUBLE |
| sharesOutstanding | DOUBLE |
| sharesAsOf | TIMESTAMP |
| sharesOutstandingScope | VARCHAR |
| sharesOutstandingClass | VARCHAR |
| sharesAccession | VARCHAR |
| sharesAvailableAt | TIMESTAMP |
| sharesSourceFilingUrl | VARCHAR |
| source | VARCHAR |
| priceSource | VARCHAR |
| marketCapSource | VARCHAR |
| statementAccession | VARCHAR |
| statementRawArchiveKey | VARCHAR |
| statementSourceFilingUrl | VARCHAR |
| priceSourceCheckedAt | TIMESTAMP |
No matching rows. Clear the filter to see all records.
Current logical schema for lake.sec_daily_ohlc
Query lake.sec_daily_ohlc using the column names and types below. The query validator and engine use this logical catalog; a field absent from an older shard returns typed NULL.
What this table contains
Equity daily OHLC + light fundamentals (SEC SoT).
Screen the newest sufficiently covered session
Query example, not executed here. The dates and filters define the proposed research scope; returned rows and current coverage must be checked in your workspace.
The documented coverage rule admits a session with at least 90% of its trailing median ticker count, or with no prior median. Inspect the chosen date and coverage count; the rule is a coverage heuristic, not a claim of perfect completeness. This is end-of-day data, not a live quote.
WITH sessions AS (
SELECT CAST(date AS DATE) AS session, COUNT(DISTINCT ticker) AS tickers
FROM lake.sec_daily_ohlc
WHERE CAST(date AS DATE) >=
(SELECT MAX(CAST(date AS DATE)) FROM lake.sec_daily_ohlc) - INTERVAL 45 DAY
GROUP BY 1
), scored AS (
SELECT session, tickers,
MEDIAN(tickers) OVER (ORDER BY session ROWS BETWEEN 20 PRECEDING AND 1 PRECEDING) AS trailing_median
FROM sessions
), latest_full AS (
SELECT MAX(session) AS session
FROM scored
WHERE trailing_median IS NULL OR tickers >= 0.9 * trailing_median
)
SELECT ticker, date, closingPrice, volume
FROM lake.sec_daily_ohlc
WHERE CAST(date AS DATE) = (SELECT session FROM latest_full)
ORDER BY ticker
LIMIT 20;Five actual AAPL sessions from this canonical source
Show the table · 5 rows, 3 columns
Scroll sideways to compare all columns. Select a heading to sort.
| AAPL | 2024-01-02T21:00:00.000Z | 185.64 |
| AAPL | 2024-01-03T21:00:00.000Z | 184.25 |
| AAPL | 2024-01-04T21:00:00.000Z | 181.91 |
| AAPL | 2024-01-05T21:00:00.000Z | 181.18 |
| AAPL | 2024-01-08T21:00:00.000Z | 185.56 |
No matching rows. Clear the filter to see all records.
The canonical lake reader returned these five source rows on October 10, 2026. They are the same dated result used in the Python and TypeScript SQL guides. This smaller historical query is separate from the newest-session screen above; it demonstrates row units and timestamps without claiming the screen has run.
SELECT ticker, date, closingPrice FROM lake.sec_daily_ohlc WHERE ticker = 'AAPL' AND date::DATE BETWEEN DATE '2024-01-02' AND DATE '2024-01-08' ORDER BY date ASC LIMIT 5Submit the sec_daily_ohlc example and read back its parts
Run the exact SQL through the Python SDK
Save this page's SQL as query.sql and the runner below as query.py. Use a registered key with lake scope from Developers. The runner submits the displayed sec_daily_ohlc query once, saves its operation, waits on that same ID, saves the returned manifest and downloads its Parquet parts.
This submission has not been executed for the reference page. Inspect the SQL, dates and resource limits before running it. Reuse the request key only for this identical SQL and limits; use a new key when changing them.
python3 -m pip install nexustrade==1.42.0
export NEXUSTRADE_API_KEY="YOUR_LAKE_SCOPED_KEY"
python3 query.py
import json
from pathlib import Path
from nexustrade import NexusTradeClient
# Save the SQL displayed on this page as query.sql.
sql = Path("query.sql").read_text()
client = NexusTradeClient.from_environment()
operation = client.create_lake_query(
{"query": sql, "limits": {"timeoutSeconds": 30, "maxRows": 50,
"maxResultBytes": 1048576}},
idempotency_key="reference-sec_daily_ohlc-20261012-v1",
)
Path("query-operation.json").write_text(json.dumps(operation, indent=2))
finished = client.wait_for_lake_query(operation["id"])
if finished["status"] != "completed":
raise RuntimeError(finished)
manifest = client.get_lake_query_manifest(operation["id"])["result"]
Path("query-manifest.json").write_text(json.dumps(manifest, indent=2))
print(json.dumps(manifest, indent=2))
for part in manifest["parts"]:
Path(f"query-{part['part']}.parquet").write_bytes(
client.download_lake_query_part(operation["id"], part["part"], max_bytes=1048576)
)
Coverage and timing
Inspect source coverage and timing before using the rows
Equity daily OHLC + light fundamentals (SEC SoT).
Covers the tradable STOCK + ETF universe. ETFs and other non-filers (SPY, QQQ, USO) are present as price-only rows: OHLC and volume are populated, `peRatioTTM` / `psRatioTTM` / `pbRatioTTM` and other statement-linked fields are usually NULL. A null ratio means the issuer files no statements, not that the ticker is missing — query ETF price history exactly like equities.
`dividendYield` is ALREADY a percentage. Two percent is `dividendYield > 2`, not `> 0.02`.
`marketCap` is `unadjustedClose * sharesOutstanding` as of that date, and is NULL for ETFs and for filers whose only share figure is a period average. Filter with `marketCap IS NOT NULL` rather than treating NULL as zero. Never re-derive market cap from `closingPrice`, which is split- and dividend-adjusted — that basis mismatch reported a $31B company as $31,363.
`sharesAsOf` is when the share count was measured, not when it became public; between filings it is the precision bound on `marketCap`.
`sharesAvailableAt`, `sharesAccession`, and `sharesSourceFilingUrl` identify the selected share source; `sharesOutstandingScope` distinguishes issuer-wide, class-specific, and unqualified vendor counts. Older shards may have NULL source lineage. For a multi-class issuer, an issuer-wide count multiplied by one listed class's price is only a one-price company-value approximation, not a class-weighted valuation or independent confirmation of the share count.
Latest screens SHOULD pin to the newest session with full coverage, not raw `MAX(date)`: a partially published session can sit at the tip with a fraction of the universe. Use `WHERE date::DATE = (SELECT session FROM latest_full)` with `WITH latest_full AS (WITH sessions AS ( SELECT date::DATE AS session, COUNT(DISTINCT ticker) AS tickers FROM lake.sec_daily_ohlc WHERE date::DATE >= (SELECT MAX(date::DATE) FROM lake.sec_daily_ohlc) - INTERVAL 45 DAY GROUP BY 1 ), scored AS ( SELECT session, tickers, MEDIAN(tickers) OVER (ORDER BY session ROWS BETWEEN 20 PRECEDING AND 1 PRECEDING) AS trailing_median FROM sessions ) SELECT MAX(session) AS session FROM scored WHERE trailing_median IS NULL OR tickers >= 0.9 * trailing_median)`.
The daily tip is only admitted after the SEC price refresh finalizes a session (21:00 America/New_York); in-progress Polygon bars are never written. Do NOT write `date < CURRENT_DATE` — that lags a finished tip by a calendar day after the refresh lands. This table is end-of-day closes, not live quotes.
`ticker` is the symbol the security traded under ON THAT DATE. A company that changed ticker keeps its earlier rows under its earlier ticker (Facebook is `FB` before 2022-06-09 and `META` after; Cabot Oil & Gas is `COG` until 2021-10-01, then Coterra is `CTRA`), and a reused ticker holds a different company before its current holder listed (`CTRA` in 2019 is Contura Energy).
For one company's history across a rename, join `lake.security_segments` on `ticker` and the date span and filter its `canonical_symbol`, e.g. `JOIN lake.security_segments s ON o.ticker = s.ticker AND o.date::DATE BETWEEN s.from_date AND COALESCE(s.to_date, DATE '9999-12-31') WHERE s.canonical_symbol = 'META'`.
No comments yet.