interest_days 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 68382b7fbcf8795d417cef0017b8c77cf3169d0e7b14aad979afc82003f80a31
4
- data.tar.gz: 0e283cb94a33ec8d073ba0c3ea38b95309e8ca95c18a655b0c6d9772bce152bc
3
+ metadata.gz: fd70242df3cc611422eab114a361fa95159a2b38f80c1f36588f65bd42696eae
4
+ data.tar.gz: 1110b831429ac7ec6e544ac7122d020ee2cf0a3e2b815ce028dea04db218b34f
5
5
  SHA512:
6
- metadata.gz: 8b30317b93074457dd25bf20968a533d051d91fdb757a8de6db2a3e1b25c352a2f40ef6e91cc05b42457b58bde54167a408a2e62155d1f569ebb6f751ba17b25
7
- data.tar.gz: 3d4fbecfdd70fc6b051545d3c1cf6dc126ae3278f28ff276d999da7dc37060eefc6387f8df73e31e922121df1cf97207cd3a5410c5e508bfe0e61b0436c112e4
6
+ metadata.gz: b6f267d1f27967ab0e522b6b4e0854ffb4d4b56986ae848adbc535b826282380a20cbe9bde47dae5baa743ea9da4de0e5341d135cb161a53540d3e28325ae35a
7
+ data.tar.gz: 801180a7509c5e751d7a1d91ebfedb335d69c0f7d4d19ad3c05d7cba8c7c7d1d07ba0f4aacee1a87e9ae287b30d4e3f4317eac5a3d9267b2dce7dcbbcc5842f5
data/.rubocop.yml CHANGED
@@ -14,4 +14,7 @@ Layout/LineLength:
14
14
  Max: 120
15
15
 
16
16
  Naming/VariableNumber:
17
- EnforcedStyle: snake_case
17
+ EnforcedStyle: snake_case
18
+
19
+ Metrics/BlockLength:
20
+ Max: 50
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- interest_days (0.1.1)
4
+ interest_days (0.2.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # InterestDays
2
2
 
3
3
  This gem provide interest day factor calculation based on ISDA conventions e.g. Isda Act 360.
4
+ Since version 0.2 interest_day gem support 30/360 US EOM and 30/360 Bond Basis conventions.
4
5
 
5
6
  ## Installation
6
7
 
@@ -22,14 +23,18 @@ Or install it yourself as:
22
23
 
23
24
  You can simple use the InterestDays::Calculator like:
24
25
 
25
- ’’’
26
- InterestDays::Calculator.new(start_date: start, end_date: end, strategy: :isda_act_360)
27
- ’’’
26
+ ```ruby
27
+ calculator = InterestDays::Calculator.new(start_date: start, end_date: end, strategy: :isda_act_360)
28
+
29
+ calculator.interest_day_count_factor
30
+ ```
28
31
 
29
- current there a three supported conventions:
32
+ currently there a three supported conventions:
30
33
  - :isda_act_360
31
34
  - :isda_act_365
32
35
  - :isda_30_e_360
36
+ - :us_eom_30_360
37
+ - :bond_basis_30_360
33
38
 
34
39
 
35
40
  ## Development
@@ -12,7 +12,7 @@ module InterestDays
12
12
  end
13
13
 
14
14
  def day_count_factor
15
- raise NotImplementedError, "#{self.class} has nit implemented method '#{__method__}"
15
+ raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}"
16
16
  end
17
17
 
18
18
  private
@@ -3,25 +3,15 @@
3
3
  module InterestDays
4
4
  module Calculation
5
5
  # ISDA 30 E 360 Convention calculation
6
- class Isda30e360 < Base
7
- RELEVANT_DAYS_IN_YEAR = 360
8
-
9
- def day_count_factor
10
- (year_interval_in_days + month_interval_in_days + day_interval).fdiv(RELEVANT_DAYS_IN_YEAR)
11
- end
12
-
6
+ class Isda30e360 < ThirtyThreesixtyBase
13
7
  private
14
8
 
15
- def year_interval_in_days
16
- 360 * (@end_date.year - @start_date.year)
17
- end
18
-
19
- def month_interval_in_days
20
- 30 * (@end_date.month - @start_date.month)
9
+ def end_date_days
10
+ [@end_date.day, RELEVANT_DAY_IN_MONTH].min
21
11
  end
22
12
 
23
- def day_interval
24
- [@end_date.day, 30].min - [@start_date.day, 30].min
13
+ def start_date_days
14
+ [@start_date.day, RELEVANT_DAY_IN_MONTH].min
25
15
  end
26
16
  end
27
17
  end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module InterestDays
4
+ module Calculation
5
+ # ISDA 30 E 360 Convention calculation
6
+ class ThirtyThreesixtyBase < Base
7
+ RELEVANT_DAYS_IN_YEAR = 360
8
+ RELEVANT_DAY_IN_MONTH = 30
9
+
10
+ def day_count_factor
11
+ (year_interval_in_days + month_interval_in_days + day_interval).fdiv(RELEVANT_DAYS_IN_YEAR)
12
+ end
13
+
14
+ private
15
+
16
+ def year_interval_in_days
17
+ RELEVANT_DAYS_IN_YEAR * (@end_date.year - @start_date.year)
18
+ end
19
+
20
+ def month_interval_in_days
21
+ RELEVANT_DAY_IN_MONTH * (@end_date.month - @start_date.month)
22
+ end
23
+
24
+ def day_interval
25
+ end_date_days - start_date_days
26
+ # [@end_date.day, 30].min - [@start_date.day, 30].min
27
+ end
28
+
29
+ def end_date_days
30
+ raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}"
31
+ end
32
+
33
+ def start_date_days
34
+ raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}"
35
+ end
36
+
37
+ def days_in_month_for(date)
38
+ Date.new(date.year, date.month, -1).day
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module InterestDays
4
+ module Calculation
5
+ # ISDA 30 E 360 Convention calculation
6
+ class UsEom30360 < ThirtyThreesixtyBase
7
+ private
8
+
9
+ # D2 day
10
+ def end_date_days
11
+ if ((@start_date.month == 2 && @start_date.date == days_in_month_for(@start_date)) &&
12
+ (@end_date.month == 2 && @end_date.date == days_in_month_for(@end_date))) ||
13
+ (@end_date.day == 31 && @start_date.day >= 30)
14
+ RELEVANT_DAY_IN_MONTH
15
+ else
16
+ @end_date.day
17
+ end
18
+ end
19
+
20
+ # D1 day
21
+ def start_date_days
22
+ if (@start_date.month == 2 && @start_date.date == days_in_month_for(@start_date)) || @start_date.day == 31
23
+ RELEVANT_DAY_IN_MONTH
24
+ else
25
+ @start_date.day
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -23,7 +23,9 @@ module InterestDays
23
23
  @strategies ||= {
24
24
  isda_act_360: InterestDays::Calculation::IsdaAct360,
25
25
  isda_act_365: InterestDays::Calculation::IsdaAct365,
26
- isda_30_e_360: InterestDays::Calculation::Isda30e360
26
+ isda_30_e_360: InterestDays::Calculation::Isda30e360,
27
+ bond_basis_30_360: InterestDays::Calculation::Isda30e360,
28
+ us_eom_30_360: InterestDays::Calculation::UsEom30360
27
29
  }
28
30
  end
29
31
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module InterestDays
4
- VERSION = "0.1.1"
4
+ VERSION = "0.2.0"
5
5
  end
data/lib/interest_days.rb CHANGED
@@ -3,6 +3,8 @@
3
3
  require_relative "interest_days/version"
4
4
  require "interest_days/calculator"
5
5
  require "interest_days/calculation/base"
6
+ require "interest_days/calculation/thirty_threesixty_base"
7
+ require "interest_days/calculation/us_eom_30_360"
6
8
  require "interest_days/calculation/isda_act_360"
7
9
  require "interest_days/calculation/isda_act_365"
8
10
  require "interest_days/calculation/isda_30_e_360"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: interest_days
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eugen Mueller
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-10-04 00:00:00.000000000 Z
11
+ date: 2021-10-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -77,6 +77,8 @@ files:
77
77
  - lib/interest_days/calculation/isda_30_e_360.rb
78
78
  - lib/interest_days/calculation/isda_act_360.rb
79
79
  - lib/interest_days/calculation/isda_act_365.rb
80
+ - lib/interest_days/calculation/thirty_threesixty_base.rb
81
+ - lib/interest_days/calculation/us_eom_30_360.rb
80
82
  - lib/interest_days/calculator.rb
81
83
  - lib/interest_days/version.rb
82
84
  homepage: https://github.com/eugenmueller/interest_days