HKUDS/Vibe-Trading · error · ValuationError

comps.run_comps: unknown calendarisation_policy {calendarisa

Error message

comps.run_comps: unknown calendarisation_policy {calendarisation_policy!r}, must be one of {CALENDARISATION_POLICIES}

What it means

run_comps validates calendarisation_policy against CALENDARISATION_POLICIES (e.g. 'ltm', 'ntm'/calendar-year styles). An unknown policy string is rejected because choosing the fiscal-alignment rule silently changes every multiple.

Source

Thrown at agent/src/quantlib/valuation/comps.py:1169

            input (see :mod:`.contracts`). This is distinct from the
            boundary case where peers were supplied but every one of them
            was later excluded from a given multiple by its own non-positive
            denominator -- that case returns a normal `CompsResult` whose
            `distributions[name]` is empty and carries a warning, because
            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"
        )

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Import CALENDARISATION_POLICIES and validate/select from it directly.
  2. Check the module constant to see the exact accepted strings in your installed version.
  3. Normalize config input (strip/lower) and fail loudly at config-load time.

Example fix

# before
result = run_comps(target, peers, calendarisation_policy='ttm')

# after
from quantlib.valuation.comps import CALENDARISATION_POLICIES
policy = policy.strip().lower()
assert policy in CALENDARISATION_POLICIES, CALENDARISATION_POLICIES
result = run_comps(target, peers, calendarisation_policy=policy)
Defensive patterns

Strategy: type-guard

Validate before calling

from quantlib.valuation.comps import CALENDARISATION_POLICIES
policy = policy.strip().lower()
if policy not in CALENDARISATION_POLICIES:
    raise ValueError(f'policy must be one of {CALENDARISATION_POLICIES}')

Type guard

def valid_policy(p):
    from quantlib.valuation.comps import CALENDARISATION_POLICIES
    return p in CALENDARISATION_POLICIES

Prevention

When it happens

Trigger: Calling run_comps(calendarisation_policy='LTM') (case mismatch), 'fy', 'ttm', or a typo, or passing None when the argument became required.

Common situations: Config-driven policy strings drifting from the library's vocabulary after a version upgrade renames/adds policies; copy-pasted examples with outdated policy names.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/69a04348e2565f64. Report an issue: GitHub.