virattt/ai-hedge-fund · warning · InsufficientData
{ticker} as of {as_of}: only {len(metrics)} filed periods (n
Error message
{ticker} as of {as_of}: only {len(metrics)} filed periods (need {MIN_PERIODS}) What it means
Raised by build_snapshot (hedge_fund/features/snapshot.py:134) when fewer than MIN_PERIODS (=4) filed financial-metrics periods exist for the ticker as of the given date. The point-in-time snapshot needs a multi-period history to compute trends, so thin coverage is a hard stop, not a neutral view. It raises the dedicated InsufficientData (a ValueError subclass) so callers can distinguish 'this stock is too new' from real data failures.
Source
Thrown at hedge_fund/features/snapshot.py:134
def build_snapshot(
ticker: str,
as_of: str,
data_client: DataClient,
periods: int = 20,
) -> FundamentalsSnapshot:
"""Build the point-in-time snapshot for (ticker, as_of).
Raises InsufficientData if fewer than MIN_PERIODS filed periods exist.
Data-layer failures propagate (fail loud) — a broken snapshot must never
silently become a neutral view.
"""
metrics = data_client.get_financial_metrics(
ticker, as_of, period="ttm", limit=periods,
)
if len(metrics) < MIN_PERIODS:
raise InsufficientData(
f"{ticker} as of {as_of}: only {len(metrics)} filed periods "
f"(need {MIN_PERIODS})"
)
# Market cap comes from the most recent FILED metrics row. Deliberately
# NOT data_client.get_market_cap(): that prefers company_facts.market_cap,
# which is latest-only — lookahead in a backtest.
facts = data_client.get_company_facts(ticker)
rows = [
PeriodFundamentals(**m.model_dump(include=set(PeriodFundamentals.model_fields)))
for m in metrics
]
return FundamentalsSnapshot(
ticker=ticker,
as_of=as_of,
# Sector/industry are slow-moving company attributes; using latestView on GitHub (pinned to eff8a7320f)
Solutions
- Catch InsufficientData per ticker in the pipeline and skip that name for that cycle (treat as TickerSkip), rather than letting it kill the whole run.
- Shift the backtest start date to at least 4 quarters after the ticker's first filing.
- Remove the thin-coverage ticker from the universe if it will never have history (delisted before the window).
- Increase the requested periods or verify coverage first with a direct get_financial_metrics call before adding the ticker to the universe.
Example fix
# before
snap = build_snapshot(data_client, ticker, as_of) # IPO'd 3 quarters ago -> crashes the cycle
# after
from hedge_fund.features.snapshot import build_snapshot, InsufficientData
try:
snap = build_snapshot(data_client, ticker, as_of)
except InsufficientData:
skipped.append(TickerSkip(ticker=ticker, reason="insufficient filing history"))
continue Defensive patterns
Strategy: try-catch
Validate before calling
MIN_PERIODS = 4 # keep in sync with hedge_fund.features.snapshot
def has_enough_history(client, ticker: str, as_of: str) -> bool:
try:
rows = client.get_financial_metrics(ticker, as_of, period="ttm", limit=20)
except Exception:
return False # let the real error surface later; this is only a pre-check
return len(rows) >= MIN_PERIODS Type guard
from hedge_fund.features.snapshot import InsufficientData
def is_insufficient_history(e: BaseException) -> bool:
return isinstance(e, InsufficientData) Try / catch
from hedge_fund.features.snapshot import build_snapshot, InsufficientData
try:
snap = build_snapshot(data_client, ticker, as_of)
except InsufficientData:
skips.append(TickerSkip(ticker=ticker, reason="insufficient filing history"))
continue # skip the name for this cycle, keep the run alive
except FDClientError:
raise # data-layer failures are infrastructure: never swallow Prevention
- Catch InsufficientData per ticker — it is the designed skip signal, unlike FDClientError which must crash.
- Filter recently-IPO'd and delisted tickers out of universes for early start dates.
- Keep the local MIN_PERIODS constant in sync with the library's (currently 4).
When it happens
Trigger: Calling data_client.get_financial_metrics(ticker, as_of, period='ttm', limit=periods) for: a recently IPO'd company with <4 quarters filed; a ticker that delisted before as_of; a foreign filer with sparse coverage on the provider; as_of dates earlier than the company's first filings. Note a provider outage would raise FDClientError instead — this error means the API answered with real, but too few, rows.
Common situations: Backtests whose start date predates a company's IPO (e.g. universe includes a 2021 listing but the window starts 2019); SPACs and recent IPOs in the universe; tiny OTC tickers the provider barely covers; survivorship-biased ticker lists containing dead tickers.
Related errors
- {spec.name}: no {spec.benchmark} bars in [{start}, {end}] —
- no {spec.benchmark} bars in [{start}, {end}] — cannot build
AI-assisted analysis of virattt/ai-hedge-fund@eff8a7320f (2026-08-15).
Data as JSON: /api/errors/450d6016c4cee111.
Report an issue: GitHub.