Rates API¶
asrquant.interest_rates ¶
Interest-rate and fixed-income derivatives research toolkit.
The module is intentionally dependency-light and transparent. It provides the building blocks required by a quant researcher to move from curve construction to instrument pricing, risk, volatility modelling, short-rate models and research diagnostics without hiding conventions behind opaque objects.
All rates are decimals (0.03 means 3%) and all maturities/accruals are year
fractions unless dates are explicitly supplied.
DiscountCurve
dataclass
¶
Arbitrage-aware discount curve with transparent interpolation.
log_linear interpolation is the default because interpolation in log
discount factors produces piecewise-constant instantaneous forward rates
and preserves positivity.
Source code in src/asrquant/interest_rates.py
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 | |
ForwardCurve
dataclass
¶
Piecewise-simple forward curve for a single floating-rate tenor.
Source code in src/asrquant/interest_rates.py
MultiCurve
dataclass
¶
OIS discount curve plus tenor-specific projection curves.
Source code in src/asrquant/interest_rates.py
HedgeSolution
dataclass
¶
BermudanLSMResult
dataclass
¶
Generic least-squares Monte Carlo early-exercise result.
Source code in src/asrquant/interest_rates.py
YieldCurveCalibration
dataclass
¶
Result of a parametric yield-curve fit.
Source code in src/asrquant/interest_rates.py
RateQuantLab
dataclass
¶
Simple high-level facade for Fixed Income / Interest Rate Derivatives work.
Source code in src/asrquant/interest_rates.py
1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 | |
from_ecb
classmethod
¶
from_ecb(maturities: Sequence[str] = ('3M', '6M', '1Y', '2Y', '3Y', '5Y', '7Y', '10Y', '15Y', '20Y', '30Y'), *, interpolation: str = 'log_linear', provider: Any | None = None) -> 'RateQuantLab'
Build a lab from the latest common ECB euro-area AAA spot-curve row.
Network access is explicit because this constructor calls the ECB Data Portal. Pass a compatible provider in tests or controlled environments.
Source code in src/asrquant/interest_rates.py
bond_cashflows ¶
Return deterministic fixed-coupon cash flows indexed by year fraction.
Source code in src/asrquant/fixed_income.py
bond_price ¶
bond_price(face: float, coupon_rate: float, maturity: float, yield_rate: float, frequency: int = 2) -> float
Price a fixed-coupon bond from its yield to maturity.
Source code in src/asrquant/fixed_income.py
bootstrap_zero_curve ¶
Bootstrap periodically compounded zero rates from par coupon instruments.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
instruments
|
DataFrame
|
Table containing |
required |
frequency
|
int | None
|
Coupon payments per year. When omitted, a constant |
None
|
Notes
A simple par bootstrap requires an instrument at every coupon date needed by later instruments. The function therefore rejects incomplete coupon grids instead of silently omitting unavailable discount factors.
Source code in src/asrquant/fixed_income.py
convexity ¶
convexity(face: float, coupon_rate: float, maturity: float, yield_rate: float, frequency: int = 2) -> float
Standard discrete-compounding bond convexity.
Source code in src/asrquant/fixed_income.py
macaulay_duration ¶
macaulay_duration(face: float, coupon_rate: float, maturity: float, yield_rate: float, frequency: int = 2) -> float
Macaulay duration in years.
Source code in src/asrquant/fixed_income.py
modified_duration ¶
modified_duration(face: float, coupon_rate: float, maturity: float, yield_rate: float, frequency: int = 2) -> float
Modified duration in years.
Source code in src/asrquant/fixed_income.py
yield_to_maturity ¶
yield_to_maturity(price: float, face: float, coupon_rate: float, maturity: float, frequency: int = 2) -> float
Solve the yield to maturity by robust scalar bracketing.
Source code in src/asrquant/fixed_income.py
zero_coupon_price ¶
zero_coupon_price(face: float, rate: float, maturity: float, compounding: int | None = None) -> float
Price a zero-coupon bond under continuous or periodic compounding.
Source code in src/asrquant/fixed_income.py
year_fraction ¶
year_fraction(start: date | datetime | str, end: date | datetime | str, convention: str = 'ACT/365F') -> float
Return a year fraction for common money-market/bond day-count bases.
Supported conventions: ACT/360, ACT/365F, 30/360, 30E/360.
Source code in src/asrquant/interest_rates.py
maturity_to_years ¶
Convert a compact money-market maturity such as 3M or 10Y to years.
Source code in src/asrquant/interest_rates.py
payment_schedule ¶
Generate a regular year-fraction payment schedule including end.
Source code in src/asrquant/interest_rates.py
discount_factor ¶
Convert zero rates to discount factors under common compounding rules.
Source code in src/asrquant/interest_rates.py
zero_rate_from_discount ¶
zero_rate_from_discount(discount: ArrayLike, maturity: ArrayLike, compounding: str | int = 'continuous')
Convert discount factors to zero rates.
Source code in src/asrquant/interest_rates.py
forward_discount_factor ¶
Return P(0,T2)/P(0,T1).
Source code in src/asrquant/interest_rates.py
forward_rate_from_discounts ¶
forward_rate_from_discounts(p_start: ArrayLike, p_end: ArrayLike, start: ArrayLike, end: ArrayLike, compounding: str = 'simple')
Return a forward rate implied by two discount factors.
Source code in src/asrquant/interest_rates.py
bootstrap_discount_curve ¶
bootstrap_discount_curve(*, deposits: DataFrame | None = None, fras: DataFrame | None = None, swaps: DataFrame | None = None, swap_frequency: int = 2, interpolation: str = 'log_linear', name: str = 'bootstrapped') -> DiscountCurve
Bootstrap a single-curve term structure from deposits, FRAs and par swaps.
Deposit columns: maturity, rate. FRA columns: start, end, rate.
Swap columns: maturity, rate. Quotes use simple money-market forwards and
fixed-leg accrual 1/swap_frequency. The function deliberately requires
the coupon/FRA grid to be fully determined rather than silently interpolating
missing bootstrap nodes.
Source code in src/asrquant/interest_rates.py
projection_curve_from_discount ¶
projection_curve_from_discount(discount: DiscountCurve, tenor: float, *, name: str | None = None) -> ForwardCurve
Create a tenor forward curve implied by one discount curve.
Source code in src/asrquant/interest_rates.py
bootstrap_projection_curve_from_swaps ¶
bootstrap_projection_curve_from_swaps(discount: DiscountCurve, swaps: DataFrame, *, tenor: float = 0.5, fixed_frequency: int = 2, name: str = 'projection') -> ForwardCurve
Sequentially bootstrap tenor forwards from par swaps under OIS discounting.
The floating leg is represented by sum(alpha_i P_d(0,T_i) F_i).
Quotes must cover consecutive maturities on the chosen tenor grid.
Source code in src/asrquant/interest_rates.py
bond_price_from_curve ¶
bond_price_from_curve(curve: DiscountCurve, face: float, coupon_rate: float, maturity: float, frequency: int = 2) -> float
Dirty price of a deterministic fixed-coupon bond from a discount curve.
Source code in src/asrquant/interest_rates.py
accrued_interest ¶
accrued_interest(face: float, coupon_rate: float, frequency: int, fraction_since_coupon: float) -> float
Linear accrued interest inside a coupon period.
Source code in src/asrquant/interest_rates.py
dv01 ¶
Dollar value of a one-basis-point decrease in rates (central difference).
dollar_convexity ¶
Second derivative of PV with respect to a parallel zero-rate shift.
Source code in src/asrquant/interest_rates.py
key_rate_dv01 ¶
key_rate_dv01(pricer, curve: DiscountCurve, key_maturities: Sequence[float], bump: float = 0.0001) -> pd.Series
Bucketed key-rate DV01 using symmetric triangular node bumps.
Source code in src/asrquant/interest_rates.py
compounded_overnight_rate ¶
Geometrically compound realized overnight/RFR fixings over accrual periods.
Market-specific lookback, observation shift, lockout and publication-lag conventions must be applied to the fixing schedule before this core identity.
Source code in src/asrquant/interest_rates.py
ois_par_rate ¶
ois_par_rate(discount: DiscountCurve, start: float, end: float, *, fixed_frequency: int = 1) -> float
Par fixed rate of a standard OIS under single-curve discounting.
Source code in src/asrquant/interest_rates.py
ois_pv ¶
ois_pv(discount: DiscountCurve, start: float, end: float, fixed_rate: float, *, notional: float = 1.0, fixed_frequency: int = 1, position: str = 'payer') -> float
PV of a standard fixed-versus-compounded-overnight OIS.
Source code in src/asrquant/interest_rates.py
bond_forward_price ¶
bond_forward_price(discount: DiscountCurve, spot_dirty_price: float, delivery: float, coupon_times: ArrayLike = (), coupon_cashflows: ArrayLike = ()) -> float
No-arbitrage dirty forward price of a coupon bond at delivery.
Source code in src/asrquant/interest_rates.py
fx_forward_rate ¶
fx_forward_rate(spot_fx: float, domestic_discount: DiscountCurve, foreign_discount: DiscountCurve, maturity: float) -> float
Covered-interest-parity FX forward, quoted domestic currency per foreign.
Source code in src/asrquant/interest_rates.py
cross_currency_zero_coupon_pv ¶
cross_currency_zero_coupon_pv(spot_fx: float, domestic_discount: DiscountCurve, foreign_discount: DiscountCurve, maturity: float, *, domestic_notional: float, foreign_notional: float, receive_foreign: bool = True) -> float
PV in domestic currency of exchanging two notionals at maturity.
Source code in src/asrquant/interest_rates.py
zero_coupon_inflation_rate ¶
Annualized inflation rate implied by a terminal index ratio.
Source code in src/asrquant/interest_rates.py
zero_coupon_inflation_swap_pv ¶
zero_coupon_inflation_swap_pv(discount: DiscountCurve, maturity: float, fixed_rate: float, index_ratio: float, *, notional: float = 1.0, receive_inflation: bool = True) -> float
PV of a zero-coupon inflation swap for a supplied terminal index ratio.
Source code in src/asrquant/interest_rates.py
curve_scenario ¶
curve_scenario(curve: DiscountCurve, *, parallel_bp: float = 0.0, slope_bp: float = 0.0, curvature_bp: float = 0.0) -> DiscountCurve
Apply transparent parallel/slope/curvature shocks to node zero rates.
Source code in src/asrquant/interest_rates.py
key_rate_hedge ¶
key_rate_hedge(target_exposure: ArrayLike, hedge_exposures: ArrayLike, *, ridge: float = 0.0) -> HedgeSolution
Solve hedge weights so hedge key-rate exposures offset a target vector.
Source code in src/asrquant/interest_rates.py
bermudan_lsm ¶
bermudan_lsm(immediate_values: ndarray, state_paths: ndarray, interval_discounts: ArrayLike, *, polynomial_degree: int = 2, valuation_discount: float = 1.0) -> BermudanLSMResult
Generic Longstaff-Schwartz engine for Bermudan-style exercise.
Source code in src/asrquant/interest_rates.py
fra_pv ¶
fra_pv(curve: DiscountCurve, start: float, end: float, strike: float, *, notional: float = 1.0, position: str = 'receive_float', settlement: str = 'end', projection: ForwardCurve | None = None) -> float
Present value of a FRA.
settlement='end' uses the standard end-payment representation
N*tau*(F-K) P(0,T2). settlement='start' uses the FRA cash
settlement denominator 1 + tau F and discounts to T1.
Source code in src/asrquant/interest_rates.py
swap_par_rate ¶
swap_par_rate(discount: DiscountCurve, start: float, end: float, *, fixed_frequency: int = 2, projection: ForwardCurve | None = None) -> float
Par IRS rate under single- or multi-curve valuation.
Source code in src/asrquant/interest_rates.py
swap_pv ¶
swap_pv(discount: DiscountCurve, start: float, end: float, fixed_rate: float, *, notional: float = 1.0, fixed_frequency: int = 2, position: str = 'payer', projection: ForwardCurve | None = None) -> float
PV of a vanilla fixed-for-floating interest-rate swap.
Source code in src/asrquant/interest_rates.py
basis_swap_pv ¶
basis_swap_pv(discount: DiscountCurve, leg_a: ForwardCurve, leg_b: ForwardCurve, start: float, end: float, *, spread_a: float = 0.0, notional: float = 1.0) -> float
PV of receiving projection leg A plus spread and paying leg B.
Source code in src/asrquant/interest_rates.py
rate_future_price ¶
caplet_price ¶
caplet_price(discount: DiscountCurve, start: float, end: float, strike: float, volatility: float, *, notional: float = 1.0, option: str = 'caplet', model: str = 'black76', projection: ForwardCurve | None = None, shift: float = 0.0) -> float
Price one caplet/floorlet under Black-76, shifted Black or Bachelier.
Source code in src/asrquant/interest_rates.py
cap_floor_price ¶
cap_floor_price(discount: DiscountCurve, periods: Sequence[tuple[float, float]], strike: float, volatilities: float | Sequence[float], *, notional: float = 1.0, option: str = 'cap', model: str = 'black76', projection: ForwardCurve | None = None, shift: float = 0.0) -> float
Price a cap/floor as a portfolio of caplets/floorlets.
Source code in src/asrquant/interest_rates.py
swaption_price ¶
swaption_price(discount: DiscountCurve, expiry: float, swap_end: float, strike: float, volatility: float, *, notional: float = 1.0, fixed_frequency: int = 2, option: str = 'payer', model: str = 'black76', projection: ForwardCurve | None = None, shift: float = 0.0) -> float
European physical/cash-annuity-equivalent swaption price.
Source code in src/asrquant/interest_rates.py
implied_rate_volatility ¶
Generic scalar implied-volatility inversion for a rate-option pricer.
Source code in src/asrquant/interest_rates.py
strip_caplet_volatilities ¶
strip_caplet_volatilities(discount: DiscountCurve, periods: Sequence[tuple[float, float]], strike: float, cap_prices: Sequence[float], *, notional: float = 1.0, model: str = 'black76', projection: ForwardCurve | None = None, shift: float = 0.0) -> pd.Series
Bootstrap caplet vols from a sequence of cumulative cap prices.
Source code in src/asrquant/interest_rates.py
hagan_sabr_volatility ¶
hagan_sabr_volatility(forward: float, strike: float, expiry: float, alpha: float, beta: float, rho: float, nu: float, *, shift: float = 0.0) -> float
Hagan et al. lognormal SABR implied-volatility approximation.
Source code in src/asrquant/interest_rates.py
calibrate_sabr ¶
calibrate_sabr(strikes: ArrayLike, market_vols: ArrayLike, forward: float, expiry: float, *, beta: float = 0.5, shift: float = 0.0, initial: tuple[float, float, float] = (0.02, 0.0, 0.5)) -> SABRCalibration
Least-squares SABR calibration with fixed beta.
Source code in src/asrquant/interest_rates.py
vasicek_zero_coupon_bond ¶
vasicek_zero_coupon_bond(r_t: float, t: float, maturity: float, kappa: float, theta: float, sigma: float) -> float
Vasicek zero-coupon bond price A(t,T) exp(-B(t,T) r_t).
Source code in src/asrquant/interest_rates.py
cir_zero_coupon_bond ¶
cir_zero_coupon_bond(r_t: float, t: float, maturity: float, kappa: float, theta: float, sigma: float) -> float
CIR zero-coupon bond price in affine closed form.
Source code in src/asrquant/interest_rates.py
hull_white_paths ¶
hull_white_paths(r0: float, mean_reversion: float, theta: float, sigma: float, maturity: float, *, steps: int = 252, paths: int = 10000, random_state: int | None = 0) -> pd.DataFrame
Simulate the one-factor Hull-White/Vasicek SDE with constant theta.
dr = a(theta-r)dt + sigma dW. A time-dependent theta can be supplied by
users through the generic Monte-Carlo/SDE engine; this helper is the compact
constant-theta laboratory version.
Source code in src/asrquant/interest_rates.py
ho_lee_paths ¶
ho_lee_paths(r0: float, theta: float, sigma: float, maturity: float, *, steps: int = 252, paths: int = 10000, random_state: int | None = 0) -> pd.DataFrame
Euler simulation of dr = theta dt + sigma dW.
Source code in src/asrquant/interest_rates.py
black_karasinski_paths ¶
black_karasinski_paths(r0: float, mean_reversion: float, theta_log: float, sigma: float, maturity: float, *, steps: int = 252, paths: int = 10000, random_state: int | None = 0) -> pd.DataFrame
Simulate Black-Karasinski through an OU process for log r.
Source code in src/asrquant/interest_rates.py
hjm_one_factor_paths ¶
hjm_one_factor_paths(maturities: ArrayLike, initial_forwards: ArrayLike, volatilities: ArrayLike, horizon: float, *, steps: int = 100, paths: int = 1000, random_state: int | None = 0) -> np.ndarray
Discrete one-factor HJM forward-curve simulation under the risk-neutral measure.
For deterministic maturity-dependent volatility sigma(T), the drift at
time t is approximated as sigma(T) * integral_t^T sigma(u) du over the
supplied maturity grid. Output shape is (steps+1, paths, n_maturities).
Source code in src/asrquant/interest_rates.py
lmm_terminal_measure_paths ¶
lmm_terminal_measure_paths(initial_forwards: ArrayLike, accruals: ArrayLike, volatilities: ArrayLike, correlation: ndarray, horizon: float, *, steps: int = 100, paths: int = 1000, random_state: int | None = 0) -> np.ndarray
Euler-log simulation of a lognormal LIBOR Market Model under terminal measure.
Output shape is (steps+1, paths, n_forwards). The terminal-measure drift
uses the standard negative sum over later forwards. This function is for
research/education; production calibration should use a dedicated numerical
implementation with tenor-date fixing and measure bookkeeping.
Source code in src/asrquant/interest_rates.py
calibrate_vasicek ¶
Estimate Vasicek parameters from an equally spaced short-rate series via AR(1).
Source code in src/asrquant/interest_rates.py
yield_curve_pca ¶
yield_curve_pca(yields: DataFrame, n_components: int = 3, *, differences: bool = True) -> dict[str, Any]
PCA of yield-curve changes returning level/slope/curvature-style loadings.
Source code in src/asrquant/interest_rates.py
level_slope_curvature ¶
Simple interpretable level/slope/curvature factors from ordered maturities.
Source code in src/asrquant/interest_rates.py
no_arbitrage_curve_diagnostics ¶
Basic curve sanity checks useful before pricing or research.
Source code in src/asrquant/interest_rates.py
curve_interpolation_risk ¶
curve_interpolation_risk(times: ArrayLike, zero_rates: ArrayLike, evaluation_grid: ArrayLike | None = None) -> pd.DataFrame
Compare forward rates induced by three transparent interpolation choices.
Source code in src/asrquant/interest_rates.py
carry_roll_down ¶
carry_roll_down(curve_today: DiscountCurve, maturity: float, horizon: float, *, face: float = 1.0) -> pd.Series
Static-curve carry/roll decomposition for a zero-coupon bond.
Source code in src/asrquant/interest_rates.py
nelson_siegel_yield ¶
Evaluate a Nelson-Siegel continuously-compounded zero-yield curve.
Source code in src/asrquant/interest_rates.py
svensson_yield ¶
svensson_yield(maturity: ArrayLike, beta0: float, beta1: float, beta2: float, beta3: float, tau1: float, tau2: float)
Evaluate the Nelson-Siegel-Svensson zero-yield curve.
Source code in src/asrquant/interest_rates.py
calibrate_nelson_siegel ¶
calibrate_nelson_siegel(maturities: ArrayLike, zero_rates: ArrayLike, *, initial: Sequence[float] | None = None) -> YieldCurveCalibration
Least-squares Nelson-Siegel calibration with positive decay parameter.
Source code in src/asrquant/interest_rates.py
calibrate_svensson ¶
calibrate_svensson(maturities: ArrayLike, zero_rates: ArrayLike, *, initial: Sequence[float] | None = None) -> YieldCurveCalibration
Least-squares Nelson-Siegel-Svensson calibration.
Source code in src/asrquant/interest_rates.py
rates_curriculum ¶
rates_exercises ¶
Return the built-in exercise bank for Interest Rate Derivatives Quant training.