fuggers_py.curves¶
Executive Summary¶
fuggers_py.curves provides a toolkit for building interest-rate term
structures from fixed-income quotes. It can bootstrap exact node curves or fit
smooth curves from swap quotes, bond quotes, and repo quotes. The main user
object is YieldCurve: callers give it quotes plus a CurveSpec, then query
rates, discount factors, and forward rates. The fit also returns one
CalibrationReport so users can inspect how closely the curve matched the
input quotes.
Use the root package for the first-layer curve API:
from fuggers_py.curves import CurveSpec, YieldCurve
Most users do not need deeper curve imports. YieldCurve.fit(...) accepts plain
strings and dictionaries for the common path, including global-fit settings.
The deeper calibrators and kernels modules expose small instruction records
for code that wants to store, validate, or pass fit configuration as objects.
Public Surface¶
fuggers_py.curves exports only the first-layer curve objects and helpers:
Export |
What it does |
|---|---|
|
Names one curve snapshot and fixes its date, currency, day-count rule, curve type, and out-of-range rule. |
|
Concrete discounting curve. Build it from quotes with |
|
Base type for rate curves. |
|
Base type for curves that can return discount factors. |
|
Fit-level report attached to |
|
One fitted quote row inside a report. |
|
Built-in key-rate tenor grid. |
The root package does not export kernel classes, calibrator classes, old enum controls, or compatibility aliases. Import advanced objects from their submodules when you need them.
Basic Fit¶
from fuggers_py import Date
from fuggers_py.curves import CurveSpec, YieldCurve
from fuggers_py.rates import SwapQuote
reference_date = Date.from_ymd(2026, 4, 9)
curve = YieldCurve.fit(
quotes=[
SwapQuote("USD-SWAP-1Y", tenor="1Y", rate=0.040, currency="USD", as_of=reference_date),
SwapQuote("USD-SWAP-2Y", tenor="2Y", rate=0.041, currency="USD", as_of=reference_date),
SwapQuote("USD-SWAP-5Y", tenor="5Y", rate=0.043, currency="USD", as_of=reference_date),
],
spec=CurveSpec(
name="USD SOFR",
reference_date=reference_date,
day_count="ACT/365F",
currency="USD",
type="overnight_discount",
extrapolation_policy="hold_last_zero_rate",
),
)
print(curve.rate_at(2.0))
print(curve.discount_factor_at(5.0))
print(curve.forward_rate_between(1.0, 5.0))
rate_at(...) returns the public zero-rate view of the curve. A zero rate is
one rate from the curve date to a future tenor. discount_factor_at(...) turns
a future cash flow into today’s value on the curve date.
CurveSpec¶
CurveSpec is the identity record for one curve snapshot.
from fuggers_py import Date
from fuggers_py.curves import CurveSpec
spec = CurveSpec(
name="USD OIS",
reference_date=Date.from_ymd(2026, 4, 9),
day_count="act/365f",
currency="usd",
type="overnight_discount",
reference="SOFR",
extrapolation_policy="error",
)
Important fields:
Field |
Meaning |
|---|---|
|
Human-readable curve name. Whitespace is stripped. |
|
Curve date. Quote |
|
Day-count label. Strings are normalized. |
|
Curve currency. Strings such as |
|
Plain string such as |
|
Optional benchmark or index label. |
|
Plain string controlling tenors above |
Supported extrapolation policies:
Policy |
Behavior above |
|---|---|
|
Raise |
|
Hold the final public zero rate. |
|
Ask the fitted kernel to hold its own final rate concept. |
|
Hold the terminal forward rate when the kernel supports that rule. |
YieldCurve.fit(...)¶
YieldCurve.fit(
quotes,
*,
spec,
kernel="linear_zero",
method="bootstrap",
bond_target="dirty_price",
regressors=(),
kernel_params=None,
)
Main inputs:
Input |
Meaning |
|---|---|
|
Sequence of |
|
|
|
Curve shape name, such as |
|
Fit route: |
|
For global-fit bond price rows, choose |
|
Optional bond regressor names used by global fit. |
|
Optional shape-specific settings, such as spline knots. |
The object form is optional. This call:
curve = YieldCurve.fit(
quotes,
spec=spec,
kernel="cubic_spline",
method="global_fit",
bond_target="clean_price",
kernel_params={"knots": (1.0, 2.0, 5.0)},
)
is equivalent to passing KernelSpec and CalibrationSpec objects.
Quote Inputs¶
Quote objects stay in the package that owns the instrument:
Quote type |
Import from |
What the fitter reads |
|---|---|---|
|
|
|
|
|
The bond instrument, |
|
|
|
Shared quote rules:
as_ofis required and must equalCurveSpec.reference_date.If quote currency is supplied, it must equal
CurveSpec.currency.Bootstrap requires strictly increasing tenors after sorting.
Global fit allows duplicate tenors but all rows must fit one target type: rates, discount factors, or bond prices.
Fit Methods And Kernels¶
Bootstrap builds local curve nodes one by one. It is the exact-fit path.
Kernel |
Meaning |
|---|---|
|
Zero-rate nodes with linear interpolation. |
|
Discount-factor nodes with log-linear interpolation. |
|
Zero rates stay flat until the next node. |
|
Short forward rates stay flat between nodes. |
|
Smooth zero-rate curve built from positive tenor nodes. |
Global fit estimates all parameters together. It is used when the curve shape has fewer parameters than quote rows, or when bond regressors are included.
Kernel |
Required settings |
|---|---|
|
|
|
Optional |
|
Optional |
|
|
Fit Reports¶
YieldCurve.fit(...) attaches a CalibrationReport to the returned curve.
Common report fields:
Field |
Meaning |
|---|---|
|
Whether the solver reported success. Bootstrap reports |
|
|
|
|
|
Solver iteration count. |
|
Largest absolute fitted-minus-observed difference. |
|
Tuple of |
|
Solver name. |
|
Regressor names used in global fit. |
|
Fitted coefficients in the same order as |
|
Fitted kernel name for global fit. |
|
Raw fitted kernel parameters for global fit. |
|
Final weighted objective value for global fit. |
Each CalibrationPoint contains the quote id, tenor, observed value, fitted
value, residual, observed kind, weight, and solver iterations. Global-fit rows
also carry the curve-only value and optional bond price or yield diagnostics.
Curve Moves¶
DiscountingCurve.shifted(...) and DiscountingCurve.bumped(...) return a
new DiscountingCurve. Use shifted(...) when the whole zero-rate curve should
move by one amount. Use bumped(...) when one or more tenor points should move
and the move should be interpolated across a tenor grid.
from fuggers_py.curves import STANDARD_KEY_RATE_TENORS
shifted = curve.shifted(shift=0.0001)
bumped = curve.bumped(
tenor_grid=STANDARD_KEY_RATE_TENORS,
bumps={
2.0: 0.0001,
5.0: 0.0002,
},
)
print(shifted.zero_rate_at(2.0))
print(bumped.zero_rate_at(2.0))
The returned object keeps the discounting methods, but it is a wrapper rather
than a fitted YieldCurve.
Advanced Submodules¶
The root package is enough for normal curve work: fit a curve, move it, and query rates or discount factors.
The table below is not a dump of every class inside src/fuggers_py/curves.
It lists the deeper imports that are meant to be usable from user code today.
Other classes in these folders are implementation details used by
YieldCurve.fit(...).
Import |
Public names |
Use it when |
|---|---|---|
|
|
You want one object that stores the fit route, objective, bond target, and regressor order. |
|
|
You want one object that stores the kernel family and its parameters. |
|
|
You need rate, discount-factor, or forward-rate conversions without building a curve. |
Example: keep a reusable global-fit setup in one object.
from fuggers_py.curves.calibrators import CalibrationSpec
from fuggers_py.curves.kernels import KernelSpec
fit_method = CalibrationSpec(
method="global_fit",
bond_target="clean_price",
regressors=("liquidity", "specialness"),
)
fit_shape = KernelSpec(
kind="cubic_spline",
parameters={"knots": (1.0, 2.0, 5.0, 10.0)},
)
curve = YieldCurve.fit(
quotes,
spec=spec,
method=fit_method,
kernel=fit_shape,
)
Example: use conversion helpers without building a curve.
from fuggers_py.curves.conversion import ValueConverter
discount_factor = ValueConverter.zero_to_df(0.0425, 5.0)
zero_rate = ValueConverter.df_to_zero(discount_factor, 5.0)
Concrete kernel and calibrator classes live in implementation modules under
fuggers_py.curves.kernels and fuggers_py.curves.calibrators. They are not
the public fitting interface. Most users should not instantiate them directly;
YieldCurve.fit(...) builds them and returns a YieldCurve.
At the moment, the public fitting workflows do not require deeper imports. The main reasons to use them are configuration reuse, checking fit instructions before a run, or writing lower-level extension code.
Work In Progress¶
Some curve code exists, but is not yet a complete user-facing workflow.
Area |
What exists today |
What is not complete yet |
|---|---|---|
|
|
A public workflow for fitting and solving linked curves together. |
Concrete kernel classes |
Internal classes that |
A stable direct-construction API for users. |
Concrete calibrator classes |
Internal classes that turn quotes and specs into fitted kernels. |
A stable direct-calibrator API for users. |
Use these areas for internal or research code only. The supported user path is
still YieldCurve.fit(...), which returns one YieldCurve and one
CalibrationReport.