[docs]defdiscount_to_rate(discount_rate,*,t=None,days=None,days_per_year=365):""" Convert a discount factor into a continuously compounded annualized rate. Exactly one of ``t`` or ``days`` must be provided to specify the time horizon. Parameters ---------- discount_rate : float Discount factor. Must be finite and strictly positive (> 0). t : float, optional Time horizon in years. Mutually exclusive with ``days``. days : int or float, optional Time horizon in days. Mutually exclusive with ``t``. days_per_year : int or float, default=365 Number of days per year used to convert ``days`` into years. Returns ------- float Continuously compounded annualized rate corresponding to the discount factor. Raises ------ ValueError If neither or both of ``t`` and ``days`` are provided. If ``discount_rate`` is not finite or not strictly positive. If the resulting time horizon (years) is not strictly positive. Examples -------- >>> discount_to_rate(0.95, t=0.5) # roughly half a year 0.102586... >>> discount_to_rate(0.95, days=90) # 90 trading days with 365/yr 0.20802... >>> discount_to_rate(1.0, t=1.0) 0.0 """# Exactly one of t or days must be providedifnot((tisNone)^(daysisNone)):raiseValueError("Exactly one of `t` or `days` must be provided.")# Validate discount_rateifnotnp.isfinite(discount_rate)ordiscount_rate<=0:raiseValueError("`discount_rate` must be finite and strictly positive (> 0).")# Determine t in yearsifdaysisnotNone:t_years=float(days)/float(days_per_year)else:t_years=float(t)ift_years<=0:raiseValueError("Time horizon must be strictly positive (t > 0 or days > 0).")returnfloat(-np.log(discount_rate)/t_years)
[docs]defrate_to_discount(rate,*,t=None,days=None,days_per_year=365):""" Convert a continuously compounded annualized rate into a discount factor. Exactly one of ``t`` or ``days`` must be provided to specify the time horizon. Parameters ---------- rate : float Continuously compounded annualized rate. May be negative or positive, but must be finite (no NaN/Inf). t : float, optional Time horizon in years. Mutually exclusive with ``days``. days : int or float, optional Time horizon in days. Mutually exclusive with ``t``. days_per_year : int or float, default=365 Number of days per year used to convert ``days`` into years. Returns ------- float Discount factor in (0, +inf) given by ``exp(-rate * t_years)``. Raises ------ ValueError If neither or both of ``t`` and ``days`` are provided. If ``rate`` is not finite. If the resulting time horizon (years) is not strictly positive. Examples -------- >>> rate_to_discount(0.1, t=0.5) 0.9512... >>> rate_to_discount(0.1, days=90) 0.9756... >>> rate_to_discount(0.0, t=1.0) 1.0 """# Exactly one of t or days must be providedifnot((tisNone)^(daysisNone)):raiseValueError("Exactly one of `t` or `days` must be provided.")# Validate rateifnotnp.isfinite(rate):raiseValueError("`rate` must be finite (no NaN/Inf).")# Determine t in yearsifdaysisnotNone:t_years=float(days)/float(days_per_year)else:t_years=float(t)ift_years<=0:raiseValueError("Time horizon must be strictly positive (t > 0 or days > 0).")returnfloat(np.exp(-rate*t_years))