HKUDS/Vibe-Trading · error · ValuationError

comps.FlowMetricPeriods: fiscal_year_end_month must be 1-12,

Error message

comps.FlowMetricPeriods: fiscal_year_end_month must be 1-12, got {self.fiscal_year_end_month!r}

What it means

FlowMetricPeriods validates that fiscal_year_end_month is an integer-like value between 1 and 12 (January..December). Out-of-range values (0, 13, 'FY') raise a ValuationError because calendarisation weights depend on a real month.

Source

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

            `last_full_fiscal_year` (ending one calendar year later).
            Required for the `"calendar_year"` policy whenever
            `fiscal_year_end_month != 12` -- a December fiscal year end needs
            no second year, because month-weighting already resolves to 100%
            of `last_full_fiscal_year`.

    Raises:
        ValuationError: If `fiscal_year_end_month` is not in 1..12.
    """

    fiscal_year_end_month: int
    last_full_fiscal_year: float
    current_year_to_date: float | None = None
    prior_year_to_date: float | None = None
    next_full_fiscal_year: float | None = None

    def __post_init__(self) -> None:
        if not 1 <= int(self.fiscal_year_end_month) <= 12:
            raise ValuationError(
                "comps.FlowMetricPeriods: fiscal_year_end_month must be 1-12, "
                f"got {self.fiscal_year_end_month!r}"
            )


@dataclass(frozen=True)
class CalendarisedMetric:
    """One flow metric after fiscal-calendar alignment.

    Attributes:
        policy: Which convention produced `value` -- `"ltm"` or
            `"calendar_year"`.
        value: The aligned metric value.
        fiscal_year_end_month: Carried through from the input, for audit.
        weights: For `"calendar_year"`, the `(early_fy_weight,
            late_fy_weight)` used to blend the two fiscal years. `None` for
            `"ltm"`, which has no month-weighting step.
    """

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Use the numeric month 1-12 (March = 3, December = 12).
  2. Map month names via a lookup (e.g. datetime.strptime(s, '%B').month) before constructing.
  3. Reject 0-based month values at config load.

Example fix

# before
FlowMetricPeriods(fiscal_year_end_month=0, ...)  # 0-based bug
# after
FlowMetricPeriods(fiscal_year_end_month=1, ...)  # January in 1-based
Defensive patterns

Strategy: validation

Validate before calling

if not 1 <= int(fiscal_year_end_month) <= 12:
    raise ValueError(f"fiscal_year_end_month must be 1-12, got {fiscal_year_end_month!r}")

Type guard

def is_valid_month(m) -> bool:
    try:
        return 1 <= int(m) <= 12
    except (TypeError, ValueError):
        return False

Prevention

When it happens

Trigger: FlowMetricPeriods(fiscal_year_end_month=0 or 13); a typo like month=12 but off-by-one code yielding 0; strings like 'Dec' that fail int() or compare out of range.

Common situations: Parsing fiscal year end from filings ('FYE: March') without month-name mapping; config files with 0-based months; user input of month names instead of numbers.

Related errors


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