Skip to content

Commit d3146e5

Browse files
committed
Fix interpolated curves
1 parent 90a7511 commit d3146e5

27 files changed

Lines changed: 344 additions & 222 deletions

app/api/docs/yield_curve.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
Fit a yield curve model to a set of (time-to-maturity, rate) pairs and return
22
the calibrated curve plus interpolated rates.
33

4-
Four curve types are supported:
4+
Six curve types are supported:
55

6-
- **nelson_siegel**: the Nelson-Siegel parametric model, well suited for smooth
7-
yield curves with a single hump. Good default choice.
6+
- **nelson_siegel_curve**: the Nelson-Siegel parametric model, well suited for
7+
smooth yield curves with a single hump. Good default choice.
88
- **cir_curve**: Cox-Ingersoll-Ross model, a mean-reverting short-rate model.
99
- **vasicek_curve**: Vasicek model, a Gaussian mean-reverting short-rate model.
10-
- **no_discount**: flat discount curve (no discounting), useful as a baseline.
10+
- **interpolated_linear_curve**: piecewise linear interpolation of the zero rate
11+
through the input maturities.
12+
- **interpolated_monotonic_cubic_curve**: shape-preserving monotone cubic (PCHIP)
13+
interpolation of the zero rate.
14+
- **no_discount_curve**: flat discount curve (no discounting), useful as a baseline.
1115

1216
Rates should be continuously compounded and expressed as decimals (e.g. 0.045 for 4.5%).
1317
Time to maturity is in years (e.g. 0.25 for 3 months, 2.0 for 2 years).

app/api/rates.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ async def yield_curve(
3131
..., description="List of rates to fit the Nelson-Siegel model"
3232
),
3333
curve_type: str = Query(
34-
"nelson_siegel",
34+
"nelson_siegel_curve",
3535
description="Type of curve to fit",
3636
enum=list(YieldCurve.curve_types()),
3737
),

app/api/volatility.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from quantflow.options.inputs import VolSurfaceInputs
1212
from quantflow.options.surface import OptionInfo, VolSurfaceLoader
1313
from quantflow.rates.cir import CIRCurve
14-
from quantflow.rates.nelson_siegel import NelsonSiegel
14+
from quantflow.rates.nelson_siegel import NelsonSiegelCurve
1515

1616
from .deps import RedisCache, RedisDep
1717
from .rates import YieldCurveResponse
@@ -86,13 +86,13 @@ async def _load_surface(asset: str) -> VolSurfaceLoader:
8686
if asset in DERIBIT_ASSETS:
8787
async with Deribit() as cli:
8888
loader = await cli.volatility_surface_loader(asset.lower(), inverse=True)
89-
loader.calibrate_curves(quote_curve=CIRCurve, asset_curve=NelsonSiegel)
89+
loader.calibrate_curves(quote_curve=CIRCurve, asset_curve=NelsonSiegelCurve)
9090
return loader
9191
else:
9292
async with Yahoo() as cli:
9393
loader = await cli.volatility_surface_loader(asset)
9494
loader.calibrate_spot()
95-
loader.calibrate_curves(quote_curve=CIRCurve, asset_curve=NelsonSiegel)
95+
loader.calibrate_curves(quote_curve=CIRCurve, asset_curve=NelsonSiegelCurve)
9696
return loader
9797

9898

docs/api/rates/index.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@ The central concept is the [discount factor](../../glossary.md#discount-factor)
1212
f(\tau) = -\frac{\partial \ln D_\tau}{\partial \tau}
1313
\end{equation}
1414

15+
**[Interpolated Curves](interpolated.md)** build the term structure directly from observed zero rates at a set of anchor dates. [InterpolatedLinearCurve][quantflow.rates.interpolated.InterpolatedLinearCurve] interpolates the zero rate piecewise linearly, while [InterpolatedMonotonicCubicCurve][quantflow.rates.interpolated.InterpolatedMonotonicCubicCurve] uses a shape-preserving cubic spline.
16+
1517
**[CIRCurve](cir.md)** is a short-rate term-structure model derived from the Cox-Ingersoll-Ross process, with positive-rate dynamics and closed-form discount factors.
1618

17-
**[NelsonSiegel](nelson_siegel.md)** is a concrete `YieldCurve` implementation that fits a smooth parametric curve to observed zero-coupon rates using the Nelson-Siegel functional form.
19+
**[NelsonSiegelCurve](nelson_siegel.md)** is a concrete `YieldCurve` implementation that fits a smooth parametric curve to observed zero-coupon rates using the Nelson-Siegel functional form.
1820

1921
**[VasicekCurve](vasicek.md)** is a Gaussian mean-reverting short-rate model with analytical formulas for discount factors and instantaneous forward rates.
2022

docs/api/rates/interpolated.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Interpolated Curves
2+
3+
Interpolated curves build the term structure directly from observed continuously compounded zero rates at a set of anchor dates, interpolating between them rather than fitting a parametric form.
4+
5+
The [InterpolatedYieldCurve][quantflow.rates.interpolated.InterpolatedYieldCurve] base class holds the interpolation nodes and derives the discount factor and instantaneous forward rate from the interpolated zero rate. Subclasses choose how the zero rate is interpolated between nodes.
6+
7+
[InterpolatedLinearCurve][quantflow.rates.interpolated.InterpolatedLinearCurve] interpolates the zero rate piecewise linearly, giving a forward rate that is linear on each segment.
8+
9+
[InterpolatedMonotonicCubicCurve][quantflow.rates.interpolated.InterpolatedMonotonicCubicCurve] uses a shape-preserving PCHIP cubic spline, giving a smooth zero rate and forward rate that introduces no spurious local extrema between nodes.
10+
11+
::: quantflow.rates.interpolated.InterpolatedYieldCurve
12+
13+
::: quantflow.rates.interpolated.InterpolatedLinearCurve
14+
15+
::: quantflow.rates.interpolated.InterpolatedMonotonicCubicCurve
16+
17+
::: quantflow.rates.interpolated.InterpolatedYieldCurveCalibration

docs/api/rates/nelson_siegel.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Nelson Siegel Curve
22

3-
::: quantflow.rates.nelson_siegel.NelsonSiegel
3+
::: quantflow.rates.nelson_siegel.NelsonSiegelCurve
44

55
::: quantflow.rates.nelson_siegel.NelsonSiegelCalibration

docs/api/rates/yield_curve.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44
::: quantflow.rates.yield_curve.YieldCurve
55

66

7-
::: quantflow.rates.no_discount.NoDiscount
7+
::: quantflow.rates.no_discount.NoDiscountCurve

docs/examples/fixtures/volsurface_btc.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
"asset": "btc",
33
"asset_curve": {
44
"ref_date": "2026-05-21T10:04:10.269985Z",
5-
"curve_type": "no_discount"
5+
"curve_type": "no_discount_curve"
66
},
77
"quote_curve": {
88
"ref_date": "2026-05-21T10:04:10.269985Z",
9-
"curve_type": "nelson_siegel",
9+
"curve_type": "nelson_siegel_curve",
1010
"beta1": "-1.3242608183",
1111
"beta2": "1.3324170039",
1212
"beta3": "1.6559934427",

docs/examples/fixtures/volsurface_eth.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
"asset": "eth",
33
"asset_curve": {
44
"ref_date": "2026-05-21T10:08:42.397057Z",
5-
"curve_type": "no_discount"
5+
"curve_type": "no_discount_curve"
66
},
77
"quote_curve": {
88
"ref_date": "2026-05-21T10:08:42.397057Z",
9-
"curve_type": "nelson_siegel",
9+
"curve_type": "nelson_siegel_curve",
1010
"beta1": "0.0430852145",
1111
"beta2": "-0.0189909065",
1212
"beta3": "-0.0679762918",

docs/theory/forwards.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ one unit of currency delivered at time $\tau$.
88
In quantflow, discount factors are provided by a
99
[YieldCurve][quantflow.rates.yield_curve.YieldCurve]. Different implementations capture
1010
different term structures: a flat zero-rate curve, a fitted
11-
[Nelson-Siegel][quantflow.rates.nelson_siegel.NelsonSiegel] curve, or any custom term
11+
[Nelson-Siegel][quantflow.rates.nelson_siegel.NelsonSiegelCurve] curve, or any custom term
1212
structure.
1313

1414
## Forward Price

0 commit comments

Comments
 (0)