FinanceModels.Yield API Reference

Exported API

Base.zero — Method
zero(curve,time)

Return the zero rate for the curve at the given time.

source
FinanceCore.discount — Method
discount(yc, to)
discount(yc, from,to)

The discount factor for the yield curve yc for times from through to.

source
FinanceCore.forward — Method
forward(yc, from, to)

The forward Rate implied by the yield curve yc between times from and to.

source
FinanceModels.Yield.implied_quote — Method
implied_quote(curve, family, maturity; guess = 0.0, bracket = (-0.5, 1.0))

Return the quote x for which family(x, maturity) reprices on curve, so that present_value(curve, q.instrument) == q.price for q = family(x, maturity).

family is a quote constructor taking (quote, maturity), such as CMTYield, OISYield, ZCBYield, ZCBPrice, or a closure like (r, t) -> ParYield(r, t; frequency = 1). The result is expressed in the family's own convention: for example an annual-effective rate for ZCBYield, a semiannual par yield for CMTYield beyond one year, or a price for ZCBPrice.

The solve starts from guess and falls back to a bracketed search on bracket. First-order ForwardDiff derivatives with respect to curve parameters are exact: they come from the implicit function theorem at the solution, not from solver iterations. Nested dual numbers, or a family that closes over dual numbers, throw an ArgumentError.

Examples

julia> curve = Yield.Constant(0.04);

julia> implied_quote(curve, ZCBYield, 5.0) ≈ 0.04
true

julia> implied_quote(curve, (r, t) -> ParYield(r, t; frequency = 1), 5.0) ≈ 0.04
true

See also par.

source
FinanceModels.Yield.instantaneous_forward — Method
instantaneous_forward(mc::MonotoneConvex, t)

The instantaneous (continuously-compounded) forward rate of the Hagan-West interpolant at time t. Beyond the last knot it follows mc.extrapolation. The default :flat_forward holds the boundary forward constant. :flat_zero holds the forward at the last zero rate, :linear derives it from the linearly extended zero rate, and FlatForwardAt(f) holds it at f. At the last knot itself this method returns the interior (left) forward.

Note this is distinct from forward(curve, from, to), which is the discrete forward Rate between two times and is defined for every yield model.

source
FinanceModels.Yield.par — Method
par(curve,time;frequency=2)

Calculate the par yield for maturity time for the given curve and frequency. Returns a Rate object with periodicity corresponding to the frequency.

If time is shorter than one regular coupon period (e.g. time=0.5 with frequency=1), the single stub payment implies a compounding frequency of 1/time: the result is quoted as Periodic(1/time) when 1/time is a (near-)integer, and otherwise an ArgumentError is thrown because the implied frequency cannot be represented as a Periodic rate.

If time is longer than one coupon period but not a whole number of periods, the schedule has a short first stub which accrues its actual length (see Bond.coupon_times); the result is the internal rate of return of the par-priced true-accrual schedule, quoted as Periodic(frequency) — so par of a flat curve recovers the curve's rate at any maturity. On such stub schedules this yield quote differs from the annualized par couponc solving c·Σᵢ δᵢ·DF(tᵢ) + DF(T) = 1, which is what InterestRateSwap uses for its fixed leg.

Examples

julia> c = Yield.Constant(0.04);

julia> par(c,4)
Periodic(0.03960780543711406, 2)

julia> par(c,4;frequency=1)
Periodic(0.040000000000000036, 1)

julia> par(c,0.6;frequency=4)
Periodic(0.039413626195875295, 4)

julia> par(c,0.2;frequency=4)
Periodic(0.039374942589460726, 5)

julia> par(c,2.5)
Periodic(0.03960780543711406, 2)
source
FinanceModels.Yield.reconstruct — Method
reconstruct(curve::Yield.AbstractInterpolatedZeroCurve;
    rates = knot_rates(curve), tenors = knot_tenors(curve),
    spline = <curve's method>, extrapolation = <curve's policy>)

Build a new curve from curve with any of its knot rates, knot tenors, interpolation method (spline), or extrapolation policy replaced; omitted arguments keep the curve's own. The result goes through the same validation as ZeroRateCurve and is built once. Replacing spline can change the concrete type, for example to Yield.MonotoneConvex.

reconstruct(curve) is equal to curve and prices identically. rates may hold ForwardDiff dual numbers, so this is how to differentiate a valuation with respect to a curve's knot rates:

curve = ZeroRateCurve([0.03, 0.035, 0.04], [1.0, 5.0, 10.0])
ForwardDiff.gradient(z -> pv(reconstruct(curve; rates = z), cfs), collect(knot_rates(curve)))

The derivatives are first order. At a kink of Spline.MonotoneConvex() (for example a flat stretch of the curve), each partial is the centered response to a bump of that knot, and on a flat stretch these need not add up to the parallel-shift derivative. Spline.PCHIP() and Spline.Akima() throw at their kinks. See Sensitivities Through Calibration.

source

Unexported API

FinanceModels.Yield.AbstractInterpolatedZeroCurve — Type
Yield.AbstractInterpolatedZeroCurve <: Yield.AbstractYieldModel

Supertype of the yield curves that interpolate continuously compounded zero rates over a knot grid: Yield.Spline (the DataInterpolations-backed methods) and Yield.MonotoneConvex. ZeroRateCurve, reconstruct, and spline fits return one of these.

Every such curve:

  • owns validated copies of its knots, read with knot_rates and knot_tenors (read-only vectors);
  • changes only by building a new curve with reconstruct (or Accessors.@set on its rates, tenors, spline, or extrapolation properties, which calls reconstruct);
  • follows its extrapolation policy beyond the last knot;
  • throws a DomainError for negative times; and
  • compares structurally: two curves are == (and isequal, with equal hashes) when their knot rates, knot tenors, interpolation method, and extrapolation policy are.

Before the first knot, the DataInterpolations-backed curves hold the zero rate flat at the first knot's rate. Yield.MonotoneConvex instead interpolates from t = 0 as part of the Hagan-West construction. Other fields of the concrete types are internal.

source
FinanceModels.Yield.AbstractYieldShift — Type
AbstractYieldShift <: AbstractYieldModel

Supertype for lazy zero-rate shift models: a curve produced by transforming a base yield curve's zero rate via a user-supplied rule.

Two concrete subtypes:

  • TenorShift — shift depends only on the tenor t. Use for parallel bumps, twists, butterflies — static curve transformations.
  • ProjectedShift — shift depends on the tenor tand on a second time axis τ (projection / as-of / valuation-date time). Use for phase-in profiles (BMA SBA, IFRS17 macro scenarios) and any shift whose shape evolves across a projection horizon.

Both subtypes implement the standard AbstractYieldModel interface (zero, discount, forward, pv).

source
FinanceModels.Yield.CairnsPritchard — Type
CairnsPritchard(c₁, c₂, b₀, b₁, b₂)
CairnsPritchard(c₁=0.5, c₂=3.0) # used in fitting

A spot-rate curve with 2 exponential components, retained under the historical CairnsPritchard API name.

The continuous zero rate at time t is:

$r(t) = b₀ + b₁ \exp(-c₁ t) + b₂ \exp(-c₂ t)$

This implementation fits spot rates and optimizes the decay rates along with the coefficients. Cairns (1998), Sections 1.4 and 3, instead proposes a forward-rate model with four exponential components and fixed decay constants. This type does not reproduce that model or its parameter-stability properties.

Parameters and default fitting bounds:

  • c₁ decay rate for first component: 0.001 .. 10.0
  • c₂ decay rate for second component: 0.001 .. 10.0
  • b₀ long-term rate level: -1.0 .. 1.0
  • b₁ first exponential coefficient: -10.0 .. 10.0
  • b₂ second exponential coefficient: -10.0 .. 10.0

See also CairnsPritchardExtended for a 3-component variant.

Background reference

  • Cairns, A.J.G. (1998). "Descriptive Bond-Yield and Forward-Rate Models for the British Government Securities Market". British Actuarial Journal, 4(2), 265-321. Author PDF.
source
FinanceModels.Yield.CairnsPritchardExtended — Type
CairnsPritchardExtended(c₁, c₂, c₃, b₀, b₁, b₂, b₃)
CairnsPritchardExtended(c₁=0.5, c₂=2.0, c₃=5.0) # used in fitting

A spot-rate curve with 3 exponential components, retained under the historical CairnsPritchardExtended API name.

Like CairnsPritchard, this implementation optimizes decay rates and models spot rates. It does not implement the fixed-decay forward-rate model proposed by Cairns (1998).

The continuous zero rate at time t is:

$r(t) = b₀ + b₁ \exp(-c₁ t) + b₂ \exp(-c₂ t) + b₃ \exp(-c₃ t)$

Parameters and default fitting bounds:

  • c₁ decay rate for first component: 0.001 .. 10.0
  • c₂ decay rate for second component: 0.001 .. 10.0
  • c₃ decay rate for third component: 0.001 .. 10.0
  • b₀ long-term rate level: -1.0 .. 1.0
  • b₁ first exponential coefficient: -10.0 .. 10.0
  • b₂ second exponential coefficient: -10.0 .. 10.0
  • b₃ third exponential coefficient: -10.0 .. 10.0

See also CairnsPritchard for a 2-component variant.

Background reference

  • Cairns, A.J.G. (1998). "Descriptive Bond-Yield and Forward-Rate Models for the British Government Securities Market". British Actuarial Journal, 4(2), 265-321. Author PDF.
source
FinanceModels.Yield.CompositeYield — Type
CompositeYield(curve1, curve2, op)

Combines two yield curves by adding (op = +) or subtracting (op = -) their continuous zero rates. Created via + and - on AbstractYieldModel objects; for scalar multiplication or division, see ScaledYield.

Given discount factors DF₁(t) and DF₂(t) with continuous zero rates z₁ and z₂, the composite discount factor is exp(-(z₁ ± z₂) t):

  • + gives DF(t) = DF₁(t) × DF₂(t), the product of the two discount factors (for example a base curve and a spread);
  • - gives DF(t) = DF₁(t) / DF₂(t), their quotient.

These are the operations that compose the curves' factors: every interval factor of the result is the product (or quotient) of the components' interval factors, so, for example, ForwardStarting(a + b, τ) prices like ForwardStarting(a, τ) + ForwardStarting(b, τ). Other operations on the zero rates (max, *, …) are not accepted: they would build a new curve from zero rates measured from time 0, not a composition of the two curves. For a pointwise transformation of a curve's zero rates, use a TenorShift, curve + ((z, t) -> ...), or define a curve type with its own zero.

Composition is performed in continuous-zero-rate space: a +/- composite reads each component's zero rate, combines them, and applies a single exp to form the discount factor — it no longer pays the log/exp round-trip that earlier versions did. Composing many curves in a hot loop is still marginally slower than pre-fitting a single combined curve, but the gap is small.

Curves can be added or subtracted together, but note that this is not always the same thing as adding or subtracting spreads with rates. If spreads and base rates are expressed as zero rates, then the curve addition/subtraction has the same effect as re-fitting the yield model with the rate+spread inputs added together first. Non-zero rates (e.g. par rates) do not have this same property.

Examples

rates = [0.01, 0.01, 0.03, 0.05, 0.07, 0.16, 0.35, 0.92, 1.40, 1.74, 2.31, 2.41] ./ 100
spreads = [0.01, 0.01, 0.03, 0.05, 0.07, 0.16, 0.35, 0.92, 1.40, 1.74, 2.31, 2.41] ./ 100
mats = [1 / 12, 2 / 12, 3 / 12, 6 / 12, 1, 2, 3, 5, 7, 10, 20, 30]


### Zero coupon rates/spreads

q_rf_z = ZCBYield.(rates,mats)
q_s_z = ZCBYield.(spreads,mats)
q_y_z = ZCBYield.(rates + spreads,mats)

c_rf_z = fit(Spline.Linear(),q_rf_z,Fit.Bootstrap())
c_s_z = fit(Spline.Linear(),q_s_z,Fit.Bootstrap())
c_y_z = fit(Spline.Linear(),q_y_z,Fit.Bootstrap())

# adding curves when the spreads were zero spreads works
@test discount(c_rf_z+c_s_z,20) ≈ discount(c_y_z,20)


### Par coupon rates/spreads

q_rf = CMTYield.(rates,mats)
q_s = CMTYield.(spreads,mats)
q_y = CMTYield.(rates + spreads,mats)

c_rf = fit(Spline.Linear(),q_rf,Fit.Bootstrap())
c_s = fit(Spline.Linear(),q_s,Fit.Bootstrap())
c_y = fit(Spline.Linear(),q_y,Fit.Bootstrap())

# adding curves when the spreads were par spreads does not work
@test !(discount(c_rf+c_s,20) ≈ discount(c_y,20))
source
FinanceModels.Yield.Constant — Type
Constant(rate)

A yield curve representing a flat term structure. rate can be a Rate object or a Real object.

If fiting with the default FinanceModels.jl settings, the solver will attempt to fit a discount rate with the range of: -1.0 .. 1.0

source
FinanceModels.Yield.FlatForwardAt — Type
Yield.FlatForwardAt(forward::FinanceCore.Rate)

Hold the instantaneous forward at the supplied rate beyond the last knot. Pass this object as extrapolation to ZeroRateCurve, Yield.Spline, Yield.MonotoneConvex, reconstruct, or a spline fit call.

forward must be a FinanceCore.Rate, such as Continuous(0.035) or Periodic(0.035, 1), so that its compounding convention is explicit; it is converted to and stored as a continuously compounded rate in the forward field. There is no method for a bare number, because packages read bare numbers differently (Yield.Constant(0.035) is annual effective).

The last-knot discount factor and all interpolation through that knot are preserved. The forward usually jumps at the boundary. Unlike :flat_forward, the supplied forward is an independent assumption: changing or fitting knot rates keeps it fixed. The value must be finite; negative rates and automatic differentiation are supported. On a single knot at t = 0, which leaves every positive time to the tail, the forward must equal the knot's rate: otherwise the zero rate would jump at the origin.

curve = ZeroRateCurve([0.02, 0.03, 0.04], [1.0, 10.0, 30.0];
    extrapolation=Yield.FlatForwardAt(Continuous(0.035)))
forward(curve, 40.0, 60.0)  # Continuous(0.035), up to rounding
source
FinanceModels.Yield.ForwardStarting — Type
ForwardStarting(curve,forwardstart)

Rebase a curve so that discount/accumulation/etc. are re-based so that time zero from the new curves perspective is the given forwardstart time.

Examples

julia> zero = [5.0, 5.8, 6.4, 6.8] ./ 100
julia> maturity = [0.5, 1.0, 1.5, 2.0]
julia> curve = ZeroRateCurve(zero, maturity)
julia> fwd = Yield.ForwardStarting(curve, 1.0)

julia> discount(curve,1,2)
0.9275624570410582

julia> discount(fwd,1) # `curve` has effectively been reindexed to `1.0`
0.9275624570410582

Extended Help

While ForwardStarting could be nested so that, e.g. the third period's curve is the one-period forward of the second period's curve, it will be more efficient to reuse the initial curve from a runtime and compiler perspective.

ForwardStarting is not used to construct a curve based on forward rates.

source
FinanceModels.Yield.KnotGrid — Type
KnotGrid(rates, tenors, spline::Spline.SplineCurve; who = "KnotGrid")

Internal. The owned, validated knot data behind every AbstractInterpolatedZeroCurve (Yield.Spline, Yield.MonotoneConvex). rates and tenors are each copied from any iterable of reals (a Vector is copied too, so no curve aliases caller-owned memory) and promoted independently to one concrete floating-point element type (Int → Float64, Float32 + BigFloat → BigFloat, Float64 + ForwardDiff.Dual → Dual, never narrowed).

Throws an ArgumentError (prefixed with who, the public constructor's name) when:

  • rates and tenors differ in length, or either is empty;
  • any rate or tenor is not finite (NaN, ±Inf);
  • any tenor is negative, or the tenors are not strictly increasing (unsorted or duplicated);
  • there are fewer knots than spline needs (__min_knots).

Inputs that are not real numbers fail where they are converted to floats (a MethodError such as float(::Type{String})).

A curve built from a grid takes ownership of the grid's vectors. The grid is a construction input, not a container to keep and modify.

KnotGrid(Yield.Unchecked(), rates, tenors) is internal: it neither copies nor validates. It exists only for optimizer trial curves (fit, bootstrap) whose grid was validated up front and whose candidate rates may be non-finite mid-search. Fitted results are always rebuilt through the validating form.

source
FinanceModels.Yield.MonotoneConvex — Type
MonotoneConvex(rates, tenors; extrapolation=:flat_forward)

A Monotone Convex yield curve model implementing the Hagan-West interpolation method. ZeroRateCurve(rates, tenors) (whose default method is Spline.MonotoneConvex()) returns the same curve, and loss-fitting Spline.MonotoneConvex() returns one.

With the default extrapolation, this interpolation method guarantees:

  • Continuous forward rates (including at and beyond the last knot, where the forward is extrapolated flat at the boundary instantaneous forward f(t_n); unlike the DataInterpolations-backed curves, which anchor :flat_forward on the last discrete forward, MonotoneConvex keeps its own boundary forward)
  • Positive forward rates (when input rates imply positive discrete forwards)
  • Monotone convex forward curves that match discrete forward rates at knot points

The first interval runs from t = 0, with the instantaneous forward at the origin set by the Hagan-West boundary condition, so the short end is part of the construction.

The extrapolation keyword also accepts :flat_zero, :linear, and FlatForwardAt. These change only the tail strictly beyond the last knot; :flat_zero and a supplied forward usually introduce a forward jump there. :extension is unavailable because this model has no DataInterpolations polynomial piece to continue.

Negative input rates are supported: the Hagan-West positivity collar is applied symmetrically (bounding node forwards between 0 and twice the adjacent discrete forwards), though the positivity guarantee is only meaningful when the discrete forwards themselves are positive.

The implementation follows the Hagan-West method as described in WILMOTT magazine.

Examples

prices = [0.98, 0.955, 0.92, 0.88, 0.830]
tenors = [1, 2, 3, 4, 5]
rates = @. -log(prices) / tenors

c = Yield.MonotoneConvex(rates, tenors)
zero(c, 2.5)  # Get the zero rate at t=2.5
discount(c, 2.5)  # Get the discount factor at t=2.5

Yield.MonotoneConvex is a Yield.AbstractInterpolatedZeroCurve: it copies and validates its inputs like every knot curve (a single knot is allowed and gives a flat curve), its knots are read with knot_rates/knot_tenors, and it changes only through reconstruct, which recomputes the node forwards. Yield.instantaneous_forward gives the interpolated instantaneous forward.

Derivatives with respect to the knot rates

The interpolant switches formula where two adjacent discrete forwards are equal (every flat stretch of the curve) and where a node forward meets its positivity bound, so it is only piecewise smooth in its knot rates. With ForwardDiff dual knot rates, derivatives are exact away from those points; at them, each partial is the limit of a centered bump in its direction. See "Sensitivities Through Calibration" in the documentation.

References

  • Hagan & West, "Interpolation Methods for Curve Construction", WILMOTT magazine
  • Dehlbom, "Interpolation of the yield curve" (http://uu.diva-portal.org/smash/get/diva2:1477828/FULLTEXT01.pdf)
source
FinanceModels.Yield.NelsonSiegel — Type
NelsonSiegel(τ₁, β₀, β₁, β₂)
NelsonSiegel(τ₁=1.0) # used in fitting

A Nelson-Siegel yield curve model Parameters of Nelson and Siegel (1987) parametric model, along with default parameter ranges used in the fitting:

  • τ₁ controls the location of the hump: 0.0 .. 100.0
  • β₀ represents a long-term interest rate: -10.0 .. 10.0
  • β₁ represents a time-decay component: -10.0 .. 10.0
  • β₂ represents a hump: -10.0 .. 10.0

Examples

julia> τ₁, β₀, β₁, β₂ = 3.0, 0.6, -1.2, -1.9;

julia> nsm = Yield.NelsonSiegel(τ₁, β₀, β₁, β₂);

Extended Help

NelsonSiegel has generally been replaced by NelsonSiegelSvensson, which is a more flexible model.

References

  • https://onriskandreturn.com/2019/12/01/nelson-siegel-yield-curve-model/
  • https://www.bis.org/publ/bppdf/bispap25.pdf
source
FinanceModels.Yield.NelsonSiegelSvensson — Type
NelsonSiegelSvensson(τ₁, τ₂, β₀, β₁, β₂, β₃)
NelsonSiegelSvensson(τ₁=1.0, τ₂=1.0)

Return the NelsonSiegelSvensson yield curve.

Parameters of Svensson (1994) parametric model, along with the default parameter bounds used in the fit routine:

  • τ₁ controls the location of the hump: 0.0 .. 100.0
  • τ₂ controls the location of the second hump: 0.0 .. 100.0
  • β₀ represents a long-term interest rate: -10.0 .. 10.0
  • β₁ represents a time-decay component: -10.0 .. 10.0
  • β₂ represents a hump: -10.0 .. 10.0
  • β₃ represents a second hump: -10.0 .. 10.0

Examples

julia> τ₁, τ₂, β₀, β₁, β₂, β₃ = 1.5, 3.0, 0.6, -1.2, -2.1, 3.0;

julia> nssm = Yield.NelsonSiegelSvensson(τ₁, τ₂, β₀, β₁, β₂, β₃);

Extended Help

Nelson-Siegel-Svensson Pros:

  • Simplicity: With only six parameters, the model is quite parsimonious and easy to estimate. It's also easier to interpret and communicate than more complex models.
  • Economic Interpretability: Each of the model's components can be given an economic interpretation, with parameters representing long term rate, short term rate, the rates of decay towards the long term rate, and humps in the yield curve.

Nelson-Siegel-Svensson Cons:

  • Unusual Curves: NSS makes some assumptions about the shape of the yield curve (e.g. generally has a hump in short to medium term maturities). It might not be the best choice for fitting unusual curves.
  • Arbitrage Opportunities: The NSS model does not guarantee absence of arbitrage opportunities. More sophisticated models, like the ones based on no-arbitrage conditions, might provide better pricing accuracy in some contexts.
  • Sensitivity: Similar inputs may produce different parameters due to the highly convex, non-linear region to solve for the parameters. Entities like the ECB will partially mitigate this by using the prior business day's parameters as the starting point for the current day's yield curve.

References

  • https://onriskandreturn.com/2019/12/01/nelson-siegel-yield-curve-model/
  • https://www.bis.org/publ/bppdf/bispap25.pdf
source
FinanceModels.Yield.ProjectedShift — Type
ProjectedShift(base, rule, time)

Lazy zero-rate transformation that depends on the tenor tand a second time axis τ:

z_new(t) = rule(τ, z_base(t), t)

τ (stored as the .time field) is the projection time — the as-of or valuation-date offset at which this curve is being evaluated. It is distinct from the tenor t, which is time-to-maturity from τ.

The rule function must have the signature (τ, z::Rate, t) -> Rate. The return value is type-asserted as Rate so that compounding convention is always carried explicitly; rules returning a plain Real will raise a TypeError at call time.

Use this for shifts whose shape evolves across a projection horizon — phase-in profiles (BMA SBA, IFRS17 macro scenarios), runoff schedules, calendar-rolling shocks. For static, tenor-only shifts, see TenorShift.

Constructing

There is no + operator sugar — ProjectedShift needs an explicit τ, which fixing at composition time would defeat the purpose of storing the rule as a year-independent first-class value. Always use the direct constructor:

base = Yield.Constant(0.05)

# −150 bp parallel shift, phased in linearly over 10 projection years.
phase_in = (τ, z, _) -> z + Continuous(-0.015 * min(τ, 10) / 10)

# Curve as seen at projection year 3 (30% phased in → -45 bp).
c3 = ProjectedShift(base, phase_in, 3.0)

# Curve as seen at projection year 10 (fully phased in → -150 bp).
c10 = ProjectedShift(base, phase_in, 10.0)

The intended pattern: store rule once as a first-class value, then call ProjectedShift(base, rule, τ) at each τ in a projection loop.

See also: TenorShift, AbstractYieldShift.

source
FinanceModels.Yield.ScaledYield — Type
ScaledYield(curve, factor)

A yield model that scales the continuous zero rates of curve by a Real scalar factor.

Created via curve * scalar or curve / scalar. For example, curve * 0.79 scales all continuous zero rates by 0.79, which is useful for after-tax yield calculations.

source
FinanceModels.Yield.SmithWilson — Type
Yield.SmithWilson(u, qb; ufr=ufr, α=α)
Yield.SmithWilson(;ufr=ufr, α=α)

Create a yield curve object that implements the Smith-Wilson interpolation/extrapolation scheme.

To calibrate a curve, you generally want to construct the object without the u and qb arguments and call fit in conjunction with Quotes (fit requires no third parameter for SmithWilson curves). See Examples for what this looks like. Positional arguments to construct a curve:

  • A curve can be with u is the timepoints coming from the calibration, and qb is the internal parameterization of the curve that ensures that the calibration is correct. Users may prefer the other constructors but this mathematical constructor is also available.

Required keyword arguments:

  • ufr is the Ultimate Forward Rate, the forward interest rate to which the yield curve tends, in continuous compounding convention.
  • α is the parameter that governs the speed of convergence towards the Ultimate Forward Rate. It can be typed with \alpha[TAB]

Examples

times = [1.0, 2.5, 5.6]
prices = [0.9, 0.7, 0.5]
qs = ZCBPrice.(prices, times)

ufr = 0.03
α = 0.1

model = fit(Yield.SmithWilson(ufr=ufr, α=α), qs)

Extended Help

References

source
FinanceModels.Yield.Spline — Type
Yield.Spline(spline::Spline.SplineCurve, tenors, rates; extrapolation=:flat_forward)

A yield curve that interpolates continuously-compounded zero rates over a knot grid with a DataInterpolations interpolant chosen by the spline descriptor (Spline.Linear(), Spline.Cubic(), Spline.PCHIP(), Spline.BSpline(3), …). Polynomial and B-spline orders are reduced to length(tenors) - 1 when the grid is short, so a single knot gives a flat curve. Spline.MonotoneConvex() is not a DataInterpolations method: build it with ZeroRateCurve or Yield.MonotoneConvex. Note the argument order (spline, tenors, rates), unlike ZeroRateCurve(rates, tenors, spline), which returns the same curve.

Before the first knot the zero rate is held flat at the first knot's rate.

The default extrapolation=:flat_forward holds the instantaneous forward rate constant beyond the last knot at the last discrete forward, the average continuously compounded forward over the last knot interval. For the last two knots (tₙ₋₁, zₙ₋₁) and (tₙ, zₙ),

fₙ = (zₙtₙ - zₙ₋₁tₙ₋₁) / (tₙ - tₙ₋₁),    z(t) = fₙ + (zₙ - fₙ)tₙ/t  for t > tₙ.

This preserves the last-knot discount factor (discount factors are continuous at tₙ) and does not depend on the interpolant, so a quadratic or cubic end piece cannot drive the tail. The instantaneous forward generally jumps at tₙ, from the interpolant's endpoint forward to fₙ. Set extrapolation to :flat_zero, :linear, or :extension to instead hold the zero rate constant, extend the zero rate at its left-hand boundary slope, or continue the final interpolation piece, respectively. FlatForwardAt holds a supplied forward rate fixed beyond the last knot.

Inputs are copied (later mutation of the vectors you passed in does not affect the curve) and promoted to one concrete float element type each. An ArgumentError is raised for a length mismatch, empty or non-finite inputs, negative/unsorted/duplicate tenors, or fewer knots than the interpolant needs. Yield.Spline is a Yield.AbstractInterpolatedZeroCurve: read its knots with knot_rates/knot_tenors and change it with reconstruct.

source
FinanceModels.Yield.TenorShift — Type
TenorShift(base, rule)

Lazy zero-rate transformation depending only on the tenor: z_new(t) = rule(z_base(t), t).

The rule function receives the base curve's Continuous zero rate and the tenor, and returns a new rate. It is evaluated on demand — no discretization or refitting. The base curve's analytic structure is fully preserved.

The rule function must have the signature (z::Rate, t) -> Rate. The return value is type-asserted as Rate so that compounding convention is always carried explicitly; rules returning a plain Real will raise a TypeError at call time. Use z + Continuous(0.01), Periodic(0.04, 2), etc., and let Rate arithmetic handle conversion to the curve's continuous representation.

Use this for static shifts — parallel bumps, twists, butterflies — that don't depend on where you are in projection time. For shifts whose shape evolves across a projection horizon, see ProjectedShift.

Constructing

The most ergonomic way to create a TenorShift is via the + operator with an AbstractYieldModel and a two-argument function:

base = Yield.Constant(0.05)

# Parallel shift (+100 bp)
base + (z, t) -> z + Periodic(0.01, 1)

# Tenor-dependent twist (steepener that fades at 30y)
base + (z, t) -> z + Continuous(0.02 * max(0.0, 1.0 - t/30.0))

You can also construct directly:

TenorShift(base, (z, t) -> z + Continuous(0.01))

Note: The + operator dispatches on Function. For callable objects that are not Function subtypes (e.g. custom structs with call syntax), use the direct constructor: TenorShift(base, my_callable).

TenorShift is a post-processing wrapper — it is not a fitting target. ForwardDiff propagates correctly through the transform for sensitivity analysis, but the rule function itself should be differentiable if used in an AD context.

TransformedYield is retained as a deprecated alias for TenorShift.

See also: ProjectedShift, AbstractYieldShift, CompositeYield, ScaledYield.

source
Base.:* — Method
curve * scalar
scalar * curve

Scale the continuous zero rates of curve by a Real scalar. Returns a ScaledYield.

This is useful for after-tax yield calculations. For example, curve * 0.79 produces a curve whose continuous zero rate at every point is 79% of the original.

Examples

julia> m = Yield.Constant(Continuous(0.05)) * 0.79;

julia> discount(m, 1) ≈ exp(-0.05 * 0.79)
true
source
Base.:+ — Method
Yield.AbstractYieldModel + Yield.AbstractYieldModel

The addition of two yields will create a CompositeYield. For rate, discount, and accumulation purposes the spot rates of the two curves will be added together.

source
Base.:- — Method
Yield.AbstractYieldModel - Yield.AbstractYieldModel

The subtraction of two yields will create a CompositeYield. For rate, discount, and accumulation purposes the spot rates of the second curves will be subtracted from the first.

source
Base.:/ — Method
curve / scalar

Scale the continuous zero rates of curve by 1/scalar. Returns a ScaledYield.

This is useful for grossing-up a yield to a pre-tax equivalent.

Examples

julia> m = Yield.Constant(Continuous(0.05)) / 0.79;

julia> discount(m, 1) ≈ exp(-0.05 / 0.79)
true
source
FinanceModels.Yield.ZeroRateCurve — Function
ZeroRateCurve(rates, tenors, spline=Spline.MonotoneConvex(); extrapolation=:flat_forward)
ZeroRateCurve(curve::AbstractYieldModel, tenors;
    spline=Spline.MonotoneConvex(), extrapolation=:flat_forward)

Build a yield curve that interpolates continuously-compounded zero rates at tenors with the interpolation method spline: Spline.MonotoneConvex() (the default), Spline.PCHIP(), Spline.Akima(), Spline.Linear(), Spline.Quadratic(), Spline.Cubic(), or Spline.BSpline(n).

The result is a Yield.AbstractInterpolatedZeroCurve: a Yield.MonotoneConvex for Spline.MonotoneConvex(), and a Yield.Spline otherwise. ZeroRateCurve is a construction function, not a type. Dispatch on Yield.AbstractInterpolatedZeroCurve when code needs a curve's knots, or on Yield.AbstractYieldModel when it only discounts. Read the knots with knot_rates and knot_tenors, and build a changed curve with reconstruct.

Before the first tenor, the DataInterpolations-backed methods hold the zero rate flat at the first rate; Spline.MonotoneConvex() interpolates from t = 0 as part of its construction. The default extrapolation=:flat_forward holds the instantaneous forward rate constant beyond the last tenor while preserving the last-tenor discount factor. With Spline.MonotoneConvex() the constant is its boundary instantaneous forward, so the forward curve stays continuous. With the DataInterpolations-backed splines it is the last discrete forward, (zₙtₙ - zₙ₋₁tₙ₋₁)/(tₙ - tₙ₋₁), and the forward can jump at the last tenor (see Yield.Spline). :flat_zero instead holds the last zero rate; :linear extends the zero rate at its boundary slope; and :extension continues the final DataInterpolations polynomial piece (unavailable with Spline.MonotoneConvex()). FlatForwardAt holds a user-specified forward rate fixed, including when knot rates are fitted or changed.

Constructing from another yield model

The third form samples zero rates from any AbstractYieldModel (e.g. Yield.Constant, Yield.NelsonSiegel, a fitted curve) at the given tenors. The tenors are sorted before sampling and the sampled grid is validated like any other. A tenor of 0 takes the source curve's zero-rate limit at t = 0; a curve with no such limit gives a non-finite rate, which is an error.

Examples

using FinanceModels

rates = [0.02, 0.03, 0.035, 0.04]
tenors = [1.0, 2.0, 5.0, 10.0]

zrc = ZeroRateCurve(rates, tenors)                              # Yield.MonotoneConvex
zrc_pchip = ZeroRateCurve(rates, tenors, Spline.PCHIP())        # Yield.Spline (PCHIP)
zrc_lin = ZeroRateCurve(rates, tenors, Spline.Linear())         # Yield.Spline (linear)
zrc_flat_zero = ZeroRateCurve(rates, tenors, Spline.Cubic(); extrapolation=:flat_zero)

discount(zrc, 1.0)   # exp(-0.02 * 1.0)
zero(zrc, 5.0)       # Continuous(0.035)
knot_rates(zrc)      # the rates, read-only
reconstruct(zrc; rates = rates .+ 0.001)   # a new curve, 10bp higher at every knot

# From a NelsonSiegel model:
ns = Yield.NelsonSiegel(1.0, 0.04, -0.02, 0.01)
zrc_ns = ZeroRateCurve(ns, [1.0, 2.0, 5.0, 10.0, 20.0])

Validation

rates and tenors are copied (later mutation of the vectors you passed in does not affect the curve) and each promoted to a single concrete floating-point element type (Int → Float64, Float32 + BigFloat → BigFloat, Float64 + ForwardDiff.Dual → Dual), so ZeroRateCurve(dual_rates, tenors, spline) inside an AD closure propagates derivatives. Ranges and tuples are accepted. Construction throws an ArgumentError when:

  • rates and tenors differ in length, or either is empty;
  • any rate or tenor is not finite (NaN, ±Inf);
  • any tenor is negative, or the tenors are not strictly increasing (unsorted or duplicated);
  • extrapolation is a Symbol other than :flat_forward, :flat_zero, :linear, or :extension, or :extension is requested with Spline.MonotoneConvex() (a policy of another type, other than FlatForwardAt(forward), is a MethodError);
  • there are fewer knots than the interpolant needs: Spline.PCHIP() and Spline.Akima() need 3; the other methods accept a single knot, which gives a flat curve.

Polynomial and B-spline orders reduce on short grids: with k knots, an order-n spline interpolates at order min(n, k - 1), so Spline.Cubic() through two knots is linear.

A tenor of 0 is allowed in the direct form (you supply the instantaneous rate r(0) explicitly); negative rates are allowed.

Forward curve smoothness

With the default extrapolation and inputs implying positive discrete forwards, Spline.MonotoneConvex() guarantees positive continuous forward rates (Hagan & West, 2006). For C2 zero-rate smoothness between knots, use Spline.Cubic(). Spline.Linear() produces kinks in the forward curve at tenor points. At the last tenor, the default :flat_forward policy keeps the instantaneous forward continuous for Spline.MonotoneConvex(); for the other interpolants, and under the other policies, the forward can jump there.

source
FinanceModels.Yield.g — Function
g(x, f⁻, f, fᵈ)

Compute the deviation of the instantaneous forward rate from the discrete forward rate at normalized position x ∈ [0, 1] within an interval. Following Hagan-West, g(x) = f(x) - fᵈ with boundary conditions g₀ = f⁻ - fᵈ and g₁ = f - fᵈ that determine the sector-specific polynomial used for interpolation.

source
FinanceModels.Yield.g_rate — Function
g_rate(x, f⁻, f, fᵈ)

Compute the integrated deviation G(x) = ∫₀ˣ g(u) du, which captures how the instantaneous forward curve deviates from the discrete forward across an interval. This quantity feeds into the zero-rate relation r(t) = fᵈ + (Δt / t) ⋅ G(x) used by the Hagan-West construction.

source

Please open an issue if you encounter any issues or confusion with the package.