Source code for orion_finance_sdk_py.stats.rfr

"""Protocol risk-free rate helpers and excess-return construction."""

from __future__ import annotations

import pandas as pd

from orion_finance_sdk_py.stats.constants import (
    BPS_PER_UNIT,
    DEFAULT_PERIODS_PER_YEAR,
)


[docs] def rfr_decimal(bps: float | int) -> float: """Convert an annualized protocol rate in basis points to a decimal. ``OrionConfig.risk_free_rate`` is annualized basis points (``410`` → ``0.041``). """ return float(bps) / BPS_PER_UNIT
def daily_rfr( rfr: float, *, periods_per_year: int = DEFAULT_PERIODS_PER_YEAR, ) -> float: """Compounded per-period risk-free rate from an annualized decimal ``rfr``. ``(1 + rfr) ** (1 / periods_per_year) - 1``. """ if periods_per_year <= 0: raise ValueError("periods_per_year must be positive") return (1.0 + float(rfr)) ** (1.0 / float(periods_per_year)) - 1.0 def excess_returns( returns: pd.DataFrame | pd.Series, rfr: float, *, periods_per_year: int = DEFAULT_PERIODS_PER_YEAR, ) -> pd.DataFrame: """Subtract the compounded per-period risk-free rate from simple returns.""" rf = daily_rfr(rfr, periods_per_year=periods_per_year) frame = returns.to_frame() if isinstance(returns, pd.Series) else returns return frame - rf