Skip to content

Commit 49b5cb3

Browse files
Merge pull request #8 from JuliaActuary/Step
2 parents 36257ad + c1bf02d commit 49b5cb3

File tree

5 files changed

+90
-6
lines changed

5 files changed

+90
-6
lines changed

.github/workflows/ci.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99
strategy:
1010
matrix:
1111
version:
12-
- '1.0'
12+
- '1.1'
1313
- '1.5'
1414
- 'nightly'
1515
os:

Project.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Dierckx = "39dd38d3-220a-591b-8e3c-4c3a8c710a94"
88

99
[compat]
1010
Dierckx = "0.4, 0.5"
11-
julia = "1"
11+
julia = "^1.1"
1212

1313
[extras]
1414
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ There are a few ways to construct a yield curve object:
4040
- `Zero(rates)` or `Zero(rates,maturities)` using a vector of zero, or spot, rates
4141
- `Forward(rates)` or `Forward(rates,periods)` using a vector of one-period (or `periods`-long) forward rates
4242
- `Constant(rate)` takes a single constant rate for all times
43+
- `Step(rates)` or `Step(rates,times)` doesn't interpolate - the rate is flat up to the corresponding time in `times`
4344
- `Par(rates)` or `Par(rates,maturities)` takes a series of yields for securities priced at par and paying one coupon per period
4445
- `USTreasury(rates)` takes the most commonly presented rate data (e.g. [Treasury.gov](https://www.treasury.gov/resource-center/data-chart-center/interest-rates/Pages/TextView.aspx?data=yield)) and bootstraps the curve given the combination of bills and bonds.
4546

src/Yields.jl

+62-4
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ export rate, discount, forward
88
# USTreasury, AbstractYield
99
# Zero,Constant, Forward
1010
"""
11-
An AbstractInterestCurve is an object which can be called with:
11+
An AbstractYield is an object which can be called with:
1212
13-
- `rate` for the spot rate at a given time
14-
- `discount` for the spot discount rate at a given time
13+
- `rate(yield,time)` for the spot rate at a given time
14+
- `discount(yield,time)` for the spot discount rate at a given time
1515
1616
"""
1717
abstract type AbstractYield end
@@ -20,7 +20,7 @@ abstract type AbstractYield end
2020
Base.Broadcast.broadcastable(ic::AbstractYield) = Ref(ic)
2121

2222
struct YieldCurve <: AbstractYield
23-
rates
23+
rates # spot rates
2424
maturities
2525
spline
2626
end
@@ -34,6 +34,64 @@ end
3434
rate(c::Constant,time) = c.rate
3535
discount(c::Constant,time) = 1/ (1 + rate(c,time)) ^ time
3636

37+
"""
38+
Step(rates,times)
39+
40+
Create a yield curve object where the applicable rate is the effective rate of interest applicable until corresponding time.
41+
42+
# Examples
43+
44+
```julia-repl
45+
julia>y = Yields.Step([0.02,0.05], [1,2])
46+
47+
julia>rate(y,0.5)
48+
0.02
49+
50+
julia>rate(y,1.5)
51+
0.05
52+
53+
julia>rate(y,2.5)
54+
0.05
55+
```
56+
"""
57+
struct Step <: AbstractYield
58+
rates
59+
times
60+
end
61+
62+
Step(rates) = Step(rates,collect(1:length(rates)))
63+
64+
function rate(y::Step,time)
65+
i = findfirst(t-> time <= t,y.times)
66+
if isnothing(i)
67+
return y.rates[end]
68+
else
69+
return y.rates[i]
70+
end
71+
end
72+
73+
function discount(y::Step,time)
74+
v = 1 / (1+y.rates[1]) ^ min(y.times[1],time)
75+
76+
if y.times[1] >= time
77+
return v
78+
end
79+
80+
for i in 2:length(y.times)
81+
82+
if y.times[i] >= time
83+
# take partial discount and break
84+
v /= (1+y.rates[i]) ^ (time - y.times[i-1])
85+
break
86+
else
87+
# take full discount and continue
88+
v /= (1+y.rates[i]) ^ (y.times[i] - y.times[i-1])
89+
end
90+
91+
end
92+
93+
return v
94+
end
3795

3896
function Zero(rates,maturities)
3997
# bump to a constant yield if only given one rate

test/runtests.jl

+25
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,31 @@ using Test
3636
@test rate(z,2) 0.05
3737
end
3838

39+
@testset "Step curve" begin
40+
y = Yields.Step([0.02,0.05],[1,2])
41+
42+
@test rate(y,0.5) == 0.02
43+
44+
@test discount(y,0.5) 1 / (1.02) ^ (0.5)
45+
@test discount(y,1) 1 / (1.02) ^ (1)
46+
@test rate(y,1) 0.02
47+
48+
@test discount(y,2) 1 / (1.02) / 1.05
49+
@test rate(y,2) 0.05
50+
@test rate(y,2.5) 0.05
51+
52+
@test discount(y,2) 1 / (1.02) / 1.05
53+
54+
@test discount(y,1.5) 1 / (1.02) / 1.05 ^ (0.5)
55+
56+
57+
y = Yields.Step([0.02,0.07])
58+
@test rate(y,0.5) 0.02
59+
@test rate(y,1) 0.02
60+
@test rate(y,1.5) 0.07
61+
62+
end
63+
3964
@testset "Salomon Understanding the Yield Curve Pt 1 Figure 9" begin
4065
maturity = collect(1:10)
4166

0 commit comments

Comments
 (0)