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 defined Projection
  • 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:

  1. Define the quotes you want to fit the model to
  2. 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)