HKUDS/Vibe-Trading · error · MissingInputError
peers
Error message
peers
What it means
run_comps raises MissingInputError(('peers',), 'comps.run_comps') when the peers sequence is empty — a comp analysis with no comparables has no statistics to compute, which is treated as a missing input rather than a numeric error.
Source
Thrown at agent/src/quantlib/valuation/comps.py:1174
the peers themselves were not missing, only their multiples were
not computable.
ValuationError: If `calendarisation_policy` is not recognised, if
two peers share a name, or if peers/target do not all declare
the same `eps_basis` (mixing GAAP and adjusted EPS across the
comp set would skew the P/E distribution by whatever one-time
items the adjustment removes, the same kind of silent distortion
the calendarisation-policy rule exists to prevent).
MissingInputError: (propagated from `calendarise_metric`) if any
peer's or the target's fiscal-period data lacks a field
`calendarisation_policy` needs.
"""
if calendarisation_policy not in CALENDARISATION_POLICIES:
raise ValuationError(
f"comps.run_comps: unknown calendarisation_policy {calendarisation_policy!r}, "
f"must be one of {CALENDARISATION_POLICIES}"
)
if len(peers) == 0:
raise MissingInputError(("peers",), "comps.run_comps")
names = [peer.name for peer in peers]
if len(set(names)) != len(names):
raise ValuationError(f"comps.run_comps: duplicate peer names in {names}")
all_bases = {peer.eps_basis for peer in peers} | {target.eps_basis}
if len(all_bases) > 1:
raise ValuationError(
"comps.run_comps: mixed eps_basis across the comp set "
f"{sorted(all_bases)} -- every peer and the target must declare the "
"same EPS basis, or the P/E distribution mixes GAAP and adjusted "
"earnings"
)
peer_multiples = tuple(peer_multiple_set(peer, calendarisation_policy) for peer in peers)
distributions = {
name: multiple_distribution(name, peer_multiples) for name in MULTIPLE_NAMES
}View on GitHub (pinned to 80ffdda44c)
Solutions
- Check len(peers) before calling and surface a domain-level 'no comparables matched' message.
- Loosen or review the screening filters that produced the empty set.
- Fetch/validate peer data earlier so an empty universe is caught at data-load time.
Example fix
# before
result = run_comps(target, peers=filtered_peers)
# after
if not filtered_peers:
raise ValueError('no peers survived screening; widen filters')
result = run_comps(target, peers=filtered_peers) Defensive patterns
Strategy: validation
Validate before calling
if not peers:
raise ValueError('no comparable peers available after screening') Type guard
def has_peers(peers):
return len(peers) > 0 Try / catch
from quantlib.valuation.contracts import MissingInputError
try:
run_comps(target, peers)
except MissingInputError as e:
if 'peers' in e.missing:
return build_empty_report(reason='no peers') Prevention
- Check peer-set size after screening steps
- Surface 'no comparables matched' as a domain message, not a crash
When it happens
Trigger: Calling run_comps(target, peers=[]) or peers=() — e.g. a screening filter excluded every candidate peer before the call.
Common situations: Over-aggressive peer filters (liquidity, listing exchange, negative-EBITDA exclusion) emptying the peer set; upstream data fetch returning zero rows; empty watchlist in config.
Related errors
- {model}: {name} must be a finite number, got {val!r}
- comps.run_comps: duplicate peer names in {names}
- comps.run_comps: mixed eps_basis across the comp set {sorted
- MissingInputError(missing, model)
- wacc
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/3c82a5cab352fd7e.
Report an issue: GitHub.