Source code for finance_enums.frequency

"""Calendar-frequency enum shared by all finance-* libraries.

This is the canonical location for the ``period`` / ``window`` argument
values used across ``finance-calcs``, ``finance-plots``, ``finance-etl``,
and ``finance-dates``. Any function that takes a calendar-aware
``period=`` or ``window=`` argument should accept either a
:class:`Frequency` member or one of the string aliases below.
"""

from __future__ import annotations

from enum import Enum

__all__ = ["Frequency", "to_frequency"]


[docs] class Frequency(str, Enum): """Canonical calendar frequency. The string value is the lower-case canonical alias; additional aliases are accepted by :func:`to_frequency` (e.g. ``"D"``, ``"daily"``, ``"M"``, ``"monthly"``, ``"yearly"``). """ Day = "day" Week = "week" Month = "month" Quarter = "quarter" Year = "year" @property def periods_per_year(self) -> int: """Approximate number of periods per year for annualisation.""" return { Frequency.Day: 252, Frequency.Week: 52, Frequency.Month: 12, Frequency.Quarter: 4, Frequency.Year: 1, }[self] @property def polars_truncate(self) -> str: """Polars ``dt.truncate`` rule string for bucketing dates.""" return { Frequency.Day: "1d", Frequency.Week: "1w", Frequency.Month: "1mo", Frequency.Quarter: "1q", Frequency.Year: "1y", }[self]
_ALIASES: dict[str, Frequency] = { # Day "d": Frequency.Day, "day": Frequency.Day, "daily": Frequency.Day, "1d": Frequency.Day, # Week "w": Frequency.Week, "week": Frequency.Week, "weekly": Frequency.Week, "1w": Frequency.Week, # Month "m": Frequency.Month, "mo": Frequency.Month, "month": Frequency.Month, "monthly": Frequency.Month, "1mo": Frequency.Month, # Quarter "q": Frequency.Quarter, "quarter": Frequency.Quarter, "quarterly": Frequency.Quarter, "1q": Frequency.Quarter, # Year "y": Frequency.Year, "year": Frequency.Year, "yearly": Frequency.Year, "annual": Frequency.Year, "annually": Frequency.Year, "1y": Frequency.Year, }
[docs] def to_frequency(value: Frequency | str) -> Frequency: """Coerce ``value`` to a :class:`Frequency` member. Accepts a :class:`Frequency` instance directly, the canonical lower-case name, or any of the common aliases listed above. Raises: ValueError: If ``value`` is not a recognised frequency. """ if isinstance(value, Frequency): return value if isinstance(value, str): key = value.strip().lower() if key in _ALIASES: return _ALIASES[key] raise ValueError(f"Unknown frequency: {value!r}")