using FinanceModels
using Plots
Given rates and maturities, we can fit the yield curves with different techniques.
Below, we specify that the rates should be interpreted as Continuous
ly compounded zero rates:
rates = Continuous.([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]
12-element Vector{Float64}:
0.08333333333333333
0.16666666666666666
0.25
0.5
1.0
2.0
3.0
5.0
7.0
10.0
20.0
30.0
The above rates and associated maturities represent prices of zero coupon bonds, which we use as the financial instrument that we will fit the curve to:
quotes = ZCBYield.(rates, mats)
12-element Vector{Quote{Float64, Cashflow{Float64, Float64}}}:
Quote{Float64, Cashflow{Float64, Float64}}(0.9999916667013888, Cashflow{Float64, Float64}(1.0, 0.08333333333333333))
Quote{Float64, Cashflow{Float64, Float64}}(0.9999833334722215, Cashflow{Float64, Float64}(1.0, 0.16666666666666666))
Quote{Float64, Cashflow{Float64, Float64}}(0.9999250028124297, Cashflow{Float64, Float64}(1.0, 0.25))
Quote{Float64, Cashflow{Float64, Float64}}(0.999750031247396, Cashflow{Float64, Float64}(1.0, 0.5))
Quote{Float64, Cashflow{Float64, Float64}}(0.9993002449428433, Cashflow{Float64, Float64}(1.0, 1.0))
Quote{Float64, Cashflow{Float64, Float64}}(0.9968051145430329, Cashflow{Float64, Float64}(1.0, 2.0))
Quote{Float64, Cashflow{Float64, Float64}}(0.9895549325678993, Cashflow{Float64, Float64}(1.0, 3.0))
Quote{Float64, Cashflow{Float64, Float64}}(0.9550419621907147, Cashflow{Float64, Float64}(1.0, 5.0))
Quote{Float64, Cashflow{Float64, Float64}}(0.9066489037539209, Cashflow{Float64, Float64}(1.0, 7.0))
Quote{Float64, Cashflow{Float64, Float64}}(0.8402968976584314, Cashflow{Float64, Float64}(1.0, 10.0))
Quote{Float64, Cashflow{Float64, Float64}}(0.6300223399419124, Cashflow{Float64, Float64}(1.0, 20.0))
Quote{Float64, Cashflow{Float64, Float64}}(0.4852941873885002, Cashflow{Float64, Float64}(1.0, 30.0))
Fitting is then calling fit
along with the desired curve construction technique. Here are several variants:
ns = fit(Yield.NelsonSiegel(), quotes);
nss = fit(Yield.NelsonSiegelSvensson(), quotes);
sw = fit(Yield.SmithWilson(ufr=0.05, α=0.1), quotes);
bl = fit(Spline.Linear(), quotes, Fit.Bootstrap());
bq = fit(Spline.Quadratic(), quotes, Fit.Bootstrap());
bc = fit(Spline.Cubic(), quotes, Fit.Bootstrap());
That’s it! We’ve fit the rates using six different techniques. These can now be used in a variety of ways, such as calculating the present_value
, duration
, or convexity
of different cashflows if you imported ActuaryUtilities.jl”
Visualizing the results
"""
A helper function to plot the given curve onto the given plot figure
"""
function curveplot!(plot_fig, curve; label="", alpha=alpha)
maturities = 0.25:0.25:40
f(x) = rate(zero(curve, x))
plot!(plot_fig, maturities, f, label=label, line=3, alpha=alpha)
end
"""
a function to plot the curves, given different alpha transparency for each of the lines (used when creating animiation)
"""
function p(alpha=[1, 1, 1, 1, 1, 1])
theme(:wong2)
p = plot(legend=:topleft, xlabel="Tenor", ylabel="Continuous yield", grid=false)
scatter!(
mats,
rate.(Continuous().(rates)),
label="Given zero rates"
)
curveplot!(p, bc, label="Bootstrap (Cubic)", alpha=alpha[1])
curveplot!(p, bq, label="Bootstrap (Quadratic)", alpha=alpha[2])
curveplot!(p, bl, label="Bootstrap (Linear)", alpha=alpha[3])
curveplot!(p, ns, label="NelsonSiegel", alpha=alpha[4])
curveplot!(p, nss, label="NelsonSiegelSvensson", alpha=alpha[5])
curveplot!(p, sw, label="SmithWilson", alpha=alpha[6])
lens!([0, 3.5], [0.0, 0.0045], inset=(1, bbox(0.5, 0.5, 0.4, 0.4)))
end
p()
And an animated version:
anim = let
a = [1, 0.25, 0.25, 0.25, 0.25, 0.25]
anim = @animate for i in 1:6
a = circshift(a, 1) # shift the transparency
p(a)
end
anim
end
gif(anim, "anim_fps2.gif", fps=2)