Skip to content

markowitz.data.providers

markowitz.data.providers

Price providers.

The :class:PriceProvider protocol defines the minimal interface every price source must implement. :class:YFinanceProvider is the default implementation; :class:CachedProvider wraps any provider with the on-disk Parquet cache; :class:FallbackProvider tries a list of providers in order, falling back on rate-limit / unavailable errors.

CachedProvider(inner: PriceProvider, root: str | os.PathLike[str])

Wrap a :class:PriceProvider with on-disk Parquet caching.

Source code in src/markowitz/data/providers.py
def __init__(self, inner: PriceProvider, root: str | os.PathLike[str]) -> None:
    self._inner = inner
    self._root = Path(root)
    self.name = f"cached({inner.name})"

FallbackProvider(providers: list[PriceProvider])

Try each provider in order, advancing past rate-limit / unavailable.

Source code in src/markowitz/data/providers.py
def __init__(self, providers: list[PriceProvider]) -> None:
    if not providers:
        raise ValueError("FallbackProvider requires at least one inner provider")
    self._providers = providers

PriceProvider

Bases: Protocol

Protocol every price source must satisfy.

fetch(ticker: str, start: DateLike, end: DateLike, *, frequency: str = '1d') -> pd.DataFrame

Return a frame indexed by tz-naive midnight, single close column.

Source code in src/markowitz/data/providers.py
def fetch(
    self,
    ticker: str,
    start: DateLike,
    end: DateLike,
    *,
    frequency: str = "1d",
) -> pd.DataFrame:
    """Return a frame indexed by tz-naive midnight, single ``close`` column."""
    ...

YFinanceProvider()

Provider backed by yfinance.download.

Source code in src/markowitz/data/providers.py
def __init__(self) -> None:
    try:
        import yfinance as _yf  # noqa: F401, PLC0415
    except ImportError as exc:
        raise ProviderUnavailableError(
            "yfinance is not installed; install with `pip install yfinance`"
        ) from exc