Migration Guide
v3 to v4
Yields.jl is now FinanceModels.jl
This re-write accomplishes three primary things:
- Provide a composable set of contracts and
Quotes
- Those contracts, when combined with a model produce a
Cashflow
via a flexibly definedProjection
- models can be
fit
with a new unified API:fit(model_type,quotes,fit_method)
Migrating Code
Update Dependencies
You should remove Yields
from your project's dependencies and add FinanceModels
instead. (link to Pkg documentation on how to do this)
API Changes
Previously, the API pattern was, e.g.:
model = Yields.Par(SmitWilson(...), rates,timepoints)
Now, follow the pattern of:
- Define the quotes you want to fit the model to
fit
the model to those quotes
Example:
quotes = ParYield.(rates,timepoints)
model = fit(SmithWilson(),quotes)
Details of changes
Previously the kind of contract, the implied quotes, the type of model, and how the fitting process worked were all combined into a single call (Yields.Par
). This minimized the amount of code needed to construct a yield curve, but left it fairly cumbersome to extend the package. For example, for every new yield curve model, methods for Par
, CMT
, OIS
, Zero
, ... had to be defined. Additionally, all of the inputs needed to be yields - specifying a price was not available as an argument to fit.
With the new design of the package, creating a completely new model is much easier, as only the model itself and the valuation primitives need to be defined. For example, defining a new yield curve type that works to value contracts instrument quotes only requires defining the discount
method. To allow the model to be fit
requires only defining a default set of parameters to optimize with __default_optic
:
using FinanceModels, FinanceCore
using AccessibleOptimization
using IntervalSets
struct ABDiscountLine{A} <: FinanceModels.Yield.AbstractYieldModel
a::A
b::A
end
# define the default constructor for convenience
ABDiscountLine() = ABDiscountLine(0.,0.)
function FinanceCore.discount(m::ABDiscountLine,t)
#discount rate is approximated by a straight lined, floored at 0.0 and capped at 1.0
clamp(m.a*t + m.b, 0.0,1.0)
end
# `@optic` indicates what in our model variables needs to be updated (from AccessibleOptimization.jl)
# `-1.0 .. 1.0` says to bound the search from negative to positive one (from IntervalSets.jl)
FinanceModels.__default_optic(m::ABDiscountLine) = OptArgs([
@optic(_.a) => -1.0 .. 1.0,
@optic(_.b) => -1.0 .. 1.0,
]...)
quotes = ZCBPrice([0.9, 0.8, 0.7,0.6])
m = fit(ABDiscountLine(),quotes)