Insights
Point-in-Time Market Data API for Honest Backtests
Alphanume Team · August 19, 2026
A point-in-time market data API should let a backtest reconstruct what was knowable on each decision date. For a market-cap screen, that means using market cap and shares outstanding recorded for the rebalance date and joining the dated optionability snapshot selected for that decision. Ticker Classification is current-state and has no date field, so an honest historical study must freeze and version that mapping or use a separate point-in-time taxonomy. A current company snapshot applied to old prices does not meet that standard.
This is the practical difference between asking which companies are small caps today and asking which companies a researcher could have classified as small caps on March 31, 2022. The Historical Market Cap dataset supplies the dated size inputs for the second question. It does not, by itself, solve every source of backtest bias.
The data contract an honest size screen needs
Every observation from the historical market cap endpoint is keyed by date and ticker. The two research fields are market_cap and shares_outstanding. They are stored observations for that trading date, not old prices multiplied by today's share count.
Field | Meaning in a backtest | Timing rule |
|---|---|---|
date | Trading date described by the row | Match it to the rebalance date or the latest permitted prior date |
ticker | Equity identifier for the row | Do not begin with today's surviving ticker list |
market_cap | Company value recorded for that date | Apply size thresholds to this value, not a current quote page |
shares_outstanding | Company-level share count for that date | Use changes to detect issuance or repurchases, not tradeable float |
Market cap is the product of price and shares outstanding: market_cap(t) = price(t) * shares_outstanding(t). Both inputs can change. If a company issued stock in 2024, multiplying a 2021 price by the 2024 share count creates a value nobody knew in 2021. The error can move a company across a size threshold and change whether the backtest owns it.
The existing explainer on what point-in-time market cap means focuses on that field-level problem. This guide goes one step further: it treats the API result as one dated input in a reproducible universe-building contract.
Reproduce one dated API request
Start with a single ticker and date. The request below is deliberately narrow, which makes the returned observation easy to inspect before it enters a larger pipeline. Replace the example key with your own key.
import requests
url = "https://api.alphanume.com/v1/historical-market-cap"
params = {
"ticker": "AAPL",
"date": "2026-02-06",
"api_key": "YOUR_API_KEY",
}
response = requests.get(url, params=params, timeout=30)
response.raise_for_status()
row = response.json()["data"][0]
print(row)A documented response for that request has this shape:
{
"date": "2026-02-06",
"ticker": "AAPL",
"market_cap": 4109599296360,
"shares_outstanding": 14776353000
}For cross-sectional work, request one date to receive the covered tickers for that session. A range without a ticker is limited to seven calendar days. Large results use keyset pagination: pass both values from next_cursor back as cursor_date and cursor_ticker, and stop when has_more is false. Sending only half of the cursor returns an error. The full parameter and field reference is at the Historical Market Cap API documentation.
Build the universe as it stood on each rebalance date
Suppose the research rule is: hold US technology companies with market cap between $500 million and $5 billion that had listed options on the rebalance date. Write the eligibility rule before pulling returns:
eligible = (
market_cap_rows
.merge(optionable_rows, on=["date", "ticker"], how="inner")
.merge(classification_rows, on="ticker", how="left")
.query("500_000_000 <= market_cap <= 5_000_000_000")
.query("alphanume_sector == 'technology'")
)
assert eligible["date"].max() <= rebalance_dateThe inner join to the dated optionable universe is intentional. It answers whether options were available then, not whether they are available now. Classification requires its own timing decision because a taxonomy can be updated independently of prices and share counts. Record the classification source, the date it was retrieved, and whether the research treats the label as static or historically versioned.
- Freeze the decision timestamp. Define when the screen runs and exclude records published after it.
- Join on dated keys. Use
dateandtickerwherever the source is point-in-time. - Save the empty set. A missing ticker is not the same as a company with market cap zero.
- Separate selection from returns. Build and store the eligible universe before attaching forward performance.
Failure modes the endpoint cannot fix for you
Dated market cap removes one important leak. It does not make a backtest honest automatically. A study can still use a present-day ticker master and exclude delisted failures, mishandle ticker changes, attach returns before they were observable, or ignore splits, mergers, and distributions. It can also confuse shares outstanding with free float. The latter excludes restricted and closely held shares; this endpoint reports the company-level outstanding count.
Coverage begins on different dates for different tickers. Check the companion /v1/historical-market-cap/tickers endpoint before a long backfill and keep first-available dates in the audit trail. A missing early history should remain missing. Filling it with the first later value would push future information backward.
Free access is limited to the trailing 20 trading sessions and is delayed by one trading session. That is enough to verify a request and join logic, but not enough to support a long historical size-factor claim. A result should state its actual coverage rather than silently treating a short test window as representative.
A reproducible next step
Pick one monthly rebalance date and export four artifacts: the raw market cap response, the optionable universe used for that date, the classification table with its timing assumption, and the final eligible ticker list. Then rerun the same code and confirm that the eligible list is unchanged. Only after that check should you attach next-period returns.
The Historical Market Cap guide covers pagination and common applications in more detail. For the broader joining problem, see merging point-in-time data in pandas and survivorship bias in backtesting. If the single-date audit passes, expand one rebalance at a time and keep each saved universe beside the code that produced it.