Skip to content

Commit 4fb16f4

Browse files
Eric ForgyEric Forgy
authored andcommitted
Add Excel module
Add a default yearfrac (Excel.Thirty360)
1 parent 3fefd48 commit 4fb16f4

3 files changed

Lines changed: 91 additions & 17 deletions

File tree

src/excel.jl

Lines changed: 83 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1+
module Excel
2+
3+
using ..DayCounts, ..Dates
4+
15
"""
2-
Thirty360Excel()
6+
Excel.Thirty360()
7+
8+
Excel Basis = 0 or omitted
39
410
**US (NASD) 30/360** day count convention, as computed via Microsoft Excel `YEARFRAC` with the basis option of `0`.
511
@@ -12,9 +18,8 @@ This differs from [`Thirty360`](@ref) when:
1218
- [Microsoft Excel `YEARFRAC` function](https://support.office.com/en-us/article/yearfrac-function-3844141e-c76d-4143-82b6-208454ddc6a8)
1319
- [David A. Wheeler (2008) "YEARFRAC Incompatibilities between Excel 2007 and OOXML (OXML), and the Definitions Actually Used by Excel 2007"](https://dwheeler.com/yearfrac/excel-ooxml-yearfrac.pdf)
1420
"""
15-
struct Thirty360Excel <: DayCount
16-
end
17-
function yearfrac(startdate::Date, enddate::Date, dc::Thirty360Excel)
21+
struct Thirty360 <: DayCounts.DayCount end
22+
function DayCounts.yearfrac(startdate::Date, enddate::Date, dc::Thirty360)
1823
if startdate > enddate
1924
return -yearfrac(enddate, startdate, dc)
2025
end
@@ -36,11 +41,14 @@ function yearfrac(startdate::Date, enddate::Date, dc::Thirty360Excel)
3641
d2 = 30
3742
end
3843
end
39-
return thirty360(y2-y1,m2-m1,d2-d1)
44+
return DayCounts.thirty360(y2-y1,m2-m1,d2-d1)
4045
end
46+
DayCounts.yearfrac(startdate::Date, enddate::Date) = DayCounts.yearfrac(startdate::Date, enddate::Date, Thirty360())
4147

4248
"""
43-
ActualActualExcel()
49+
Excel.ActualActual()
50+
51+
Excel Basis = 1
4452
4553
**Actual/Actual** day count convention, as computed via Microsoft Excel `YEARFRAC` with the basis option of `1`.
4654
@@ -59,9 +67,8 @@ where:
5967
- [Microsoft Excel `YEARFRAC` function](https://support.office.com/en-us/article/yearfrac-function-3844141e-c76d-4143-82b6-208454ddc6a8)
6068
- [David A. Wheeler (2008) "YEARFRAC Incompatibilities between Excel 2007 and OOXML (OXML), and the Definitions Actually Used by Excel 2007"](https://dwheeler.com/yearfrac/excel-ooxml-yearfrac.pdf)
6169
"""
62-
struct ActualActualExcel <: DayCount
63-
end
64-
function yearfrac(startdate::Date, enddate::Date, dc::ActualActualExcel)
70+
struct ActualActual <: DayCounts.DayCount end
71+
function DayCounts.yearfrac(startdate::Date, enddate::Date, dc::ActualActual)
6572
if startdate > enddate
6673
return -yearfrac(enddate, startdate, dc)
6774
end
@@ -81,3 +88,70 @@ function yearfrac(startdate::Date, enddate::Date, dc::ActualActualExcel)
8188
return Dates.value(enddate-startdate) / (sum(daysinyear, yrange) / length(yrange))
8289
end
8390
end
91+
92+
"""
93+
Excel.Actual360()
94+
95+
Excel Basis = 2
96+
97+
Same as DayCounts.Actual360.
98+
99+
**Actual/360** day count convention.
100+
101+
The year fraction is computed as:
102+
```math
103+
\\frac{\\text{# of days}}{360}
104+
```
105+
106+
# Reference
107+
- 2006 ISDA definitions, §4.16 (e)
108+
109+
"""
110+
const Actual360 = DayCounts.Actual360
111+
112+
"""
113+
Excel.Actual365()
114+
115+
Excel Basis = 3
116+
117+
Same as DayCounts.Actual365Fixed.
118+
119+
**Actual/365 (Fixed)** day count convention.
120+
121+
The year fraction is computed as:
122+
```math
123+
\\frac{\\text{# of days}}{365}
124+
```
125+
126+
# Reference
127+
- 2006 ISDA definitions, §4.16 (d)
128+
"""
129+
const Actual365 = DayCounts.Actual365Fixed
130+
131+
"""
132+
Excel.ThirtyE360()
133+
134+
Excel Basis = 4
135+
136+
Same as DayCounts.ThirtyE360.
137+
138+
**30E/360** or **Eurobond Basis** day count convention.
139+
140+
The year fraction is computed as:
141+
```math
142+
\\frac{360 \\times (y_2 - y_1) + 30 \\times (m_2 - m_1) + (d_2 - d_1)}{360}
143+
```
144+
where
145+
- ``y_1`` and ``y_2`` are the years of the start and end date, respectively.
146+
- ``m_1`` and ``m_2`` are the months of the start and end date, respectively.
147+
- ``d_1`` is the day of the month at the start date, unless it is 31st day of the month,
148+
in which case it is 30.
149+
- ``d_2`` is the day of the month at the end date, unless it is 31st day of the month,
150+
in which case it is 30.
151+
152+
# Reference
153+
- 2006 ISDA definitions, §4.16 (g)
154+
"""
155+
const ThirtyE360 = DayCounts.ThirtyE360
156+
157+
end

test/excel.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,31 @@ using Test, DayCounts, Dates, ExcelFiles
22

33
@testset "Excel basis 0" begin
44
table = load("yearfrac.xlsx","basis0")
5-
dc = DayCounts.Thirty360Excel()
5+
dc = DayCounts.Excel.Thirty360()
66
for r in ExcelFiles.getiterator(table)
77
@test yearfrac(Date(r.startdate), Date(r.enddate), dc) == r.yearfrac
88
end
99
end
1010

1111
@testset "Excel basis 1" begin
1212
table = load("yearfrac.xlsx","basis1")
13-
dc = DayCounts.ActualActualExcel()
13+
dc = DayCounts.Excel.ActualActual()
1414
for r in ExcelFiles.getiterator(table)
1515
@test yearfrac(Date(r.startdate), Date(r.enddate), dc) == r.yearfrac
1616
end
1717
end
1818

1919
@testset "Excel basis 2" begin
2020
table = load("yearfrac.xlsx","basis2")
21-
dc = DayCounts.Actual360()
21+
dc = DayCounts.Excel.Actual360()
2222
for r in ExcelFiles.getiterator(table)
2323
@test yearfrac(Date(r.startdate), Date(r.enddate), dc) == r.yearfrac
2424
end
2525
end
2626

2727
@testset "Excel basis 3" begin
2828
table = load("yearfrac.xlsx","basis3")
29-
dc = DayCounts.Actual365Fixed()
29+
dc = DayCounts.Excel.Actual365()
3030
for r in ExcelFiles.getiterator(table)
3131
@test yearfrac(Date(r.startdate), Date(r.enddate), dc) == r.yearfrac
3232
end

test/runtests.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -289,8 +289,8 @@ end
289289
end
290290

291291

292-
@testset "Thirty360Excel" begin
293-
dc = DayCounts.Thirty360Excel()
292+
@testset "Excel.Thirty360" begin
293+
dc = DayCounts.Excel.Thirty360()
294294
# usual rule: ((d2-d1) + (m2-m1)*30 + (y2-y1)*360)/360
295295
@test yearfrac(Date(2011,12,28), Date(2012, 2,28), dc) == ((28-28) + (2-12)*30 + (2012-2011)*360)/360
296296
@test yearfrac(Date(2011,12,28), Date(2012, 2,29), dc) == ((29-28) + (2-12)*30 + (2012-2011)*360)/360
@@ -325,8 +325,8 @@ end
325325

326326

327327

328-
@testset "ActualActualExcel" begin
329-
dc = DayCounts.ActualActualExcel()
328+
@testset "Excel.ActualActual" begin
329+
dc = DayCounts.Excel.ActualActual()
330330
# calculated from Excel sheet
331331
@test yearfrac(Date(2011,12,28), Date(2012, 2,28), dc) == 62/365
332332
@test yearfrac(Date(2011,12,28), Date(2012, 2,29), dc) == 63/366

0 commit comments

Comments
 (0)