finance_rb 0.0.2 → 0.1.2

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: 6fa908552e787182999bb782ed6c7f7f624307f0acd77ff969c0171e07dd0179
4
- data.tar.gz: e0492ef3dd7baa271a4d7893ff32c5c94de852d2328d1c49321bb1d78147f08e
3
+ metadata.gz: 3f920db19ed5b406b8e263c09fac4aba9cd203ebdca989c096b44b441753757e
4
+ data.tar.gz: 435cd054975eee4b5027245d0301551b1b0cfd889153879f02929f1885d55f77
5
5
  SHA512:
6
- metadata.gz: ccc866a27aecf49b0f869f9ddf590ac58d7682bc35c30a5abfda526251b800960b143fa19b05063411e30061a96f950963c4f8c38d867da763b1654ec77bfb52
7
- data.tar.gz: 5ca7d064faf5bb38ad5cd70ddb1595d8983833e4ad9b46290f17b9f5ca8eee2abd4e4c99eedf852bbf79790c28d54e4aa4743beeffbf72921ff0dccc95f1cc94
6
+ metadata.gz: 15fa362a606eacc22aeff3c89312bbedbfbe2d78319b66cd3c146a985a6c5a68114fcb1601986facdc823fa14b03a798708faae3adf704aad8c8ee89c59ec07b
7
+ data.tar.gz: c96d0f272ccee5c88cab312981f7795bac101e7bd3b229b88cfb34f05db3334b63bc61d9f41f13404105c6b6ab6bd4d318ecf3ad98ac89dbe443f1cc920a453a
data/CHANGELOG.md CHANGED
@@ -1,4 +1,29 @@
1
- ## [Unreleased]
1
+ ## [0.1.2] - 2021-04-05
2
+
3
+ ### Added
4
+ * Implement `Finance::Loan#ipmt`
5
+
6
+ ## [0.1.1] - 2021-03-30
7
+
8
+ ### Added
9
+ * Implement `Finance::Loan#fv`
10
+
11
+ ## [0.1.0] - 2021-03-28
12
+
13
+ ### Added
14
+ * Create a basic structure for `Finance::Loan`
15
+ * Implement `Finance::Loan#pmt`
16
+
17
+
18
+ ## [0.0.4] - 2021-03-25
19
+
20
+ ### Added
21
+ * Implement `Finance::Calculations#mirr`
22
+
23
+ ## [0.0.3] - 2021-03-23
24
+
25
+ ### Added
26
+ * Implement `Finance::Calculations#irr` using Newton's method
2
27
 
3
28
  ## [0.0.2] - 2021-03-22
4
29
 
data/README.md CHANGED
@@ -2,20 +2,50 @@
2
2
 
3
3
  This package is a ruby native port of the numpy-financial package with some helpful additional functions.
4
4
 
5
- The functions in this package are a scalar version of their vectorised counterparts in the [numpy-financial](https://github.com/numpy/numpy-financial) library.
5
+ The functions in this package are a scalar version of their vectorised counterparts in the [numpy-financial](https://github.com/numpy/numpy-financial) library.
6
+
7
+ [![Release](https://img.shields.io/github/v/release/wowinter13/finance_rb.svg?style=flat-square)](https://github.com/wowinter13/finance_rb/releases) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com) [![Maintainability](https://api.codeclimate.com/v1/badges/bbca82ad7815794c6718/maintainability)](https://codeclimate.com/github/wowinter13/finance_rb/maintainability)
6
8
 
7
9
  Currently, only some functions are ported,
8
10
  which are as follows:
9
11
 
10
12
  | numpy-financial function | ruby native function ported? | info|
11
13
  |:------------------------: |:------------------: | :------------------|
12
- | fv | | Computes the future value|
13
- | ipmt | | Computes interest payment for a loan|
14
- | pmt | | Computes the fixed periodic payment(principal + interest) made against a loan amount|
15
- | ppmt | | Computes principal payment for a loan|
16
- | nper | | Computes the number of periodic payments|
17
- | pv | | Computes the present value of a payment|
18
- | rate | | Computes the rate of interest per period|
19
- | irr | | Computes the internal rate of return|
14
+ | fv | | Computes the future value|
15
+ | ipmt || Computes interest payment for a loan|
16
+ | pmt | | Computes the fixed periodic payment(principal + interest) made against a loan amount|
17
+ | ppmt | | Computes principal payment for a loan|
18
+ | nper | | Computes the number of periodic payments|
19
+ | pv | | Computes the present value of a payment|
20
+ | rate | | Computes the rate of interest per period|
21
+ | irr || Computes the internal rate of return|
20
22
  | npv | ✅ | Computes the net present value of a series of cash flow|
21
- | mirr | | Computes the modified internal rate of return|
23
+ | mirr || Computes the modified internal rate of return|
24
+
25
+ ## Installation
26
+
27
+ finance_rb is available as a gem, to install it just install the gem:
28
+
29
+ gem install finance_rb
30
+
31
+ If you're using Bundler, add the gem to Gemfile.
32
+
33
+ gem 'finance_rb'
34
+
35
+ Run `bundle install`.
36
+
37
+ ## Running tests
38
+
39
+ bundle exec rspec spec/
40
+
41
+ ## Contributing
42
+
43
+ 1. Fork it ( https://github.com/wowinter13/finance_rb/fork )
44
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
45
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
46
+ 4. Push to the branch (`git push origin my-new-feature`)
47
+ 5. Create a new Pull Request
48
+
49
+ ## License
50
+
51
+ MIT License. See LICENSE for details.
@@ -1,9 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'bigdecimal'
4
+ require 'bigdecimal/newton'
5
+
6
+ include Newton
7
+
3
8
  module Finance
4
9
  class Calculations
5
10
  class << self
6
11
  # Npv computes the Net Present Value of a cash flow series.
12
+ #
7
13
  # @return [Numeric] The NPV of the input cash flow series `values` at the discount `rate`.
8
14
  #
9
15
  # @param [Numeric] :rate A discount rate applied once per period.
@@ -24,7 +30,100 @@ module Finance
24
30
  npv_value
25
31
  end
26
32
 
33
+ # IRR computes the Rate of Interest per period.
34
+ #
35
+ # @return [Float] Internal Rate of Return for periodic input values.
36
+ #
37
+ # @param [Array<Numeric>] :values Input cash flows per time period.
38
+ # At least, must contain one positive and one negative value.
39
+ # Otherwise, irr equals zero.
40
+ #
41
+ # @example
42
+ # require 'finance_rb'
43
+ # Finance::Calculations.irr([-100, 0, 0, 74]) #=> 0.14299344106053188
44
+ #
45
+ # @see http://en.wikipedia.org/wiki/Internal_rate_of_return
46
+ # @see L. J. Gitman, "Principles of Managerial Finance, Brief," 3rd ed.,
47
+ # Addison-Wesley, 2003, pg. 348.
48
+ def irr(values)
49
+ return 0.0 unless correct_cashflows?(values)
50
+
51
+ func = BigDecimal.limit(100)
52
+ func = Function.new(values)
53
+ rate = [ func.one ]
54
+ nlsolve(func, rate)
55
+ rate[0].to_f
56
+ end
57
+
58
+ # MIRR computes the modified Rate of Interest.
59
+ #
60
+ # @return [Float] Modified Internal Rate of Return.
61
+ #
62
+ # @param [Array<Numeric>] :values
63
+ # At least, must contain one positive and one negative value.
64
+ # Otherwise, mirr equals zero.
65
+ # @param [Numeric] :rate Interest rate paid on the cash flows
66
+ # @param [Numeric] :reinvest_rate Interest rate received on the cash flows upon reinvestment
67
+ #
68
+ # @example
69
+ # require 'finance_rb'
70
+ # Finance::Calculations.mirr([100, 200, -50, 300, -200], 0.05, 0.06) => 0.2979256979689131
71
+ #
72
+ # @see https://en.wikipedia.org/wiki/Modified_internal_rate_of_return
73
+ def mirr(values, rate, reinvest_rate)
74
+ inflows = [];
75
+ outflows = [];
76
+ # We prefer manual enumeration over the partition
77
+ # because of the need to replace outflows with zeros.
78
+ values.each do |val|
79
+ if val >= 0
80
+ inflows << val
81
+ outflows << 0.0
82
+ else
83
+ outflows << val
84
+ inflows << 0.0
85
+ end
86
+ end
87
+ if outflows.all?(0.0) || inflows.all?(0.0)
88
+ return 0.0
89
+ end
90
+ fv = npv(reinvest_rate, inflows).abs
91
+ pv = npv(rate, outflows).abs
92
+
93
+ return (fv/pv) ** (1.0/(values.size - 1)) * (1 + reinvest_rate) - 1
94
+ end
95
+
27
96
  alias net_present_value npv
97
+ alias internal_return_rate irr
98
+
99
+ private
100
+
101
+ def correct_cashflows?(values)
102
+ inflows, outflows = values.partition{ |i| i >= 0 }
103
+ !(inflows.empty? || outflows.empty?)
104
+ end
105
+
106
+ # Base class for working with Newton's Method.
107
+ # For more details, see Bigdecimal::Newton.
108
+ # @api private
109
+ class Function
110
+ def initialize(values)
111
+ @zero = BigDecimal("0.0")
112
+ @one = BigDecimal("1.0")
113
+ @two = BigDecimal("2.0")
114
+ @ten = BigDecimal("10.0")
115
+ @eps = BigDecimal("1.0e-16")
116
+ @values = values
117
+ end
118
+
119
+ def zero; @zero; end
120
+ def one ; @one; end
121
+ def two ; @two; end
122
+ def ten ; @ten; end
123
+ def eps ; @eps; end
124
+
125
+ def values(x); [Finance::Calculations.npv(x[0], @values)]; end
126
+ end
28
127
  end
29
128
  end
30
129
  end
data/lib/finance/loan.rb CHANGED
@@ -2,12 +2,161 @@
2
2
 
3
3
  module Finance
4
4
  class Loan
5
- def initialize; end
5
+ PAYMENT_TYPE_MAPPING = { end: 0, beginning: 1 }.freeze
6
6
 
7
- def pmt; end
7
+ # @return [Float] The amount of loan request (I.e. a present value)
8
+ # You can use #pv method to calculate value if param is not defined.
9
+ # Defaults to 0.
10
+ attr_accessor :amount
8
11
 
9
- def ipmt; end
12
+ # @return [Integer] Specification of whether payment is made
13
+ # at the beginning (ptype = 1) or the end (ptype = 0) of each period.
14
+ # Defaults to {:end, 0}.
15
+ attr_accessor :ptype
10
16
 
11
- def ppmt; end
17
+ # @return [Float] The nominal annual rate of interest as decimal (not per cent).
18
+ # (e.g., 13% -> 0.13)
19
+ # Defaults to 0.
20
+ attr_accessor :nominal_rate
21
+
22
+ # @return [Float] The monthly rate is the nominal annual rate divided by 12.
23
+ # Defaults to 0.
24
+ attr_reader :monthly_rate
25
+
26
+ # @return [Float] The number of periods to be compounded for. (I.e. Nper())
27
+ # Defaults to 1.
28
+ attr_accessor :duration
29
+
30
+ # @return [Float] Future value.
31
+ # You can use #fv method to calculate value if param is not defined.
32
+ # Defaults to 0.
33
+ attr_accessor :future_value
34
+
35
+ # @return [Float] The (fixed) periodic payment.
36
+ # You can use #pmt method to calculate value if param is not defined.
37
+ attr_accessor :payment
38
+
39
+ # @return [Float] Period under consideration.
40
+ attr_accessor :period
41
+
42
+ # Create a new Loan instance.
43
+ def initialize(**options)
44
+ initialize_payment_type(options[:ptype])
45
+ @nominal_rate = options.fetch(:nominal_rate, 0).to_f
46
+ @duration = options.fetch(:duration, 1).to_f
47
+ @amount = options.fetch(:amount, 0).to_f
48
+ @future_value = options.fetch(:future_value, 0).to_f
49
+ @period = options[:period]
50
+ @payment = options[:payment]
51
+ @monthly_rate = @nominal_rate / 12
52
+ end
53
+
54
+ # Pmt computes the payment against a loan principal plus interest (future_value = 0).
55
+ # It can also be used to calculate the recurring payments needed to achieve
56
+ # a certain future value given an initial deposit,
57
+ # a fixed periodically compounded interest rate, and the total number of periods.
58
+ #
59
+ # Required Loan arguments: nominal_rate, duration, amount, future_value*
60
+ #
61
+ # @return [Numeric] The (fixed) periodic payment.
62
+ #
63
+ # @example
64
+ # require 'finance_rb'
65
+ # Finance::Loan.new(nominal_rate: 0.1, duration: 12, amount: 1000, ptype: :end).pmt
66
+ # #=> 87.9158872300099
67
+ #
68
+ # @see http://www.oasis-open.org/committees/documents.php?wg_abbrev=office-formulaOpenDocument-formula-20090508.odt
69
+ # @see [WRW] Wheeler, D. A., E. Rathke, and R. Weir (Eds.) (2009, May).
70
+ # Open Document Format for Office Applications (OpenDocument)v1.2,
71
+ # Part 2: Recalculated Formula (OpenFormula) Format - Annotated Version,
72
+ # Pre-Draft 12. Organization for the Advancement of Structured Information
73
+ # Standards (OASIS). Billerica, MA, USA. [ODT Document].
74
+ def pmt
75
+ factor = (1.0 + monthly_rate)**duration
76
+ second_factor =
77
+ if monthly_rate.zero?
78
+ duration
79
+ else
80
+ (factor - 1) * (1 + monthly_rate * ptype) / monthly_rate
81
+ end
82
+
83
+ (-future_value + amount * factor) / second_factor
84
+ end
85
+
86
+ # IPmt computes interest payment for a loan under a given period.
87
+ #
88
+ # Required Loan arguments: period, nominal_rate, duration, amount, future_value*
89
+ #
90
+ # @return [Float] Interest payment for a loan.
91
+ #
92
+ # @example
93
+ # require 'finance_rb'
94
+ # Finance::Loan.new(nominal_rate: 0.0824, duration: 12, amount: 2500, period: 1).ipmt
95
+ # #=> -17.166666666666668
96
+ #
97
+ # @see http://www.oasis-open.org/committees/documents.php?wg_abbrev=office-formulaOpenDocument-formula-20090508.odt
98
+ # @see [WRW] Wheeler, D. A., E. Rathke, and R. Weir (Eds.) (2009, May).
99
+ # Open Document Format for Office Applications (OpenDocument)v1.2,
100
+ # Part 2: Recalculated Formula (OpenFormula) Format - Annotated Version,
101
+ # Pre-Draft 12. Organization for the Advancement of Structured Information
102
+ # Standards (OASIS). Billerica, MA, USA. [ODT Document].
103
+ def ipmt
104
+ raise ArgumentError, 'no period given' if period.nil?
105
+
106
+ ipmt_val = remaining_balance * monthly_rate
107
+ if ptype == PAYMENT_TYPE_MAPPING[:beginning]
108
+ period == 1 ? 0.0 : (ipmt_val / 1 + monthly_rate)
109
+ else
110
+ ipmt_val
111
+ end
112
+ end
113
+
114
+ # Fv computes future value at the end of some periods (duration).
115
+ # Required Loan arguments: nominal_rate, duration, payment, amount*
116
+ #
117
+ # @param payment [Float] The (fixed) periodic payment.
118
+ # In case you don't want to modify the original loan, use this parameter to recalculate fv.
119
+ #
120
+ # @return [Float] The value at the end of the `duration` periods.
121
+ #
122
+ # @example
123
+ # require 'finance_rb'
124
+ # Finance::Loan.new(nominal_rate: 0.05, duration: 120, amount: -100, payment: -200).fv
125
+ # #=> 15692.928894335748
126
+ #
127
+ # @see http://www.oasis-open.org/committees/documents.php?wg_abbrev=office-formulaOpenDocument-formula-20090508.odt
128
+ # @see [WRW] Wheeler, D. A., E. Rathke, and R. Weir (Eds.) (2009, May).
129
+ # Open Document Format for Office Applications (OpenDocument)v1.2,
130
+ # Part 2: Recalculated Formula (OpenFormula) Format - Annotated Version,
131
+ # Pre-Draft 12. Organization for the Advancement of Structured Information
132
+ # Standards (OASIS). Billerica, MA, USA. [ODT Document].
133
+ def fv(payment: nil)
134
+ raise ArgumentError, 'no payment given' if self.payment.nil? && payment.nil?
135
+
136
+ final_payment = payment || self.payment
137
+
138
+ factor = (1.0 + monthly_rate)**duration
139
+ second_factor = (factor - 1) * (1 + monthly_rate * ptype) / monthly_rate
140
+
141
+ -((amount * factor) + (final_payment.to_f * second_factor))
142
+ end
143
+
144
+ private
145
+
146
+ def initialize_payment_type(ptype)
147
+ @ptype =
148
+ if ptype.nil? || !PAYMENT_TYPE_MAPPING.keys.include?(ptype)
149
+ PAYMENT_TYPE_MAPPING[:end]
150
+ else
151
+ PAYMENT_TYPE_MAPPING[ptype]
152
+ end
153
+ end
154
+
155
+ def remaining_balance
156
+ self.class.new(
157
+ nominal_rate: nominal_rate.to_f, duration: period - 1.0,
158
+ amount: amount.to_f, ptype: PAYMENT_TYPE_MAPPING.key(ptype)
159
+ ).fv(payment: -pmt)
160
+ end
12
161
  end
13
162
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Finance
4
- VERSION = "0.0.2"
4
+ VERSION = "0.1.2"
5
5
  end
@@ -12,10 +12,72 @@ RSpec.describe Finance::Calculations do
12
12
  ).to eq(-85.07888805409468)
13
13
  end
14
14
 
15
- it 'returns correct npv for zero rates' do
15
+ it 'calculates correct npv for zero rates' do
16
16
  expect(
17
17
  Finance::Calculations.net_present_value(0.0, [-2000, 55, 55, 55])
18
18
  ).to eq(-1835.0)
19
19
  end
20
20
  end
21
+
22
+ describe '#irr' do
23
+ it 'calculates correct irr value' do
24
+ expect(
25
+ Finance::Calculations.irr([-4000,1200,1410,1875,1050])
26
+ ).to eq(0.14299344106053188)
27
+ end
28
+
29
+ it 'calculates zero for cashflows w/o any inflows' do
30
+ expect(
31
+ Finance::Calculations.irr([100,500,200,50])
32
+ ).to eq(0.0)
33
+ end
34
+
35
+ it 'is available through alias name' do
36
+ expect(
37
+ Finance::Calculations.internal_return_rate([-100, 0, 0, 74])
38
+ ).to eq(-0.09549583035161031)
39
+ end
40
+ end
41
+
42
+ describe '#mirr' do
43
+ it 'calculates correct mirr value' do
44
+ expect(
45
+ Finance::Calculations.mirr(
46
+ [-120000.0, 39000.0, 30000.0, 21000.0, 37000.0, 46000.0], 0.10, 0.12
47
+ )
48
+ ).to eq(0.1260941303659051)
49
+ end
50
+
51
+ it 'calculates correct mirr value with integers' do
52
+ expect(
53
+ Finance::Calculations.mirr(
54
+ [-4500, -800, 800, 800, 600, 600, 800, 800, 700, 3000], 0.08, 0.055
55
+ )
56
+ ).to eq(0.06659717503155349)
57
+ end
58
+
59
+ it 'calculates zero for cashflows w/o any outflows' do
60
+ expect(
61
+ Finance::Calculations.mirr(
62
+ [39000, 30000, 21000, 37000, 46000], 0.10, 0.12
63
+ )
64
+ ).to eq(0.0)
65
+ end
66
+
67
+ it 'calculates zero for cashflows w/o any inflows' do
68
+ expect(
69
+ Finance::Calculations.mirr(
70
+ [-1000, -5000, -2000, -100, -50], 0.10, 0.12
71
+ )
72
+ ).to eq(0.0)
73
+ end
74
+
75
+ it 'calculates correct mirr value for a shuffled order' do
76
+ expect(
77
+ Finance::Calculations.mirr(
78
+ [100, 200, -50, 300, -200], 0.05, 0.06
79
+ )
80
+ ).to eq(0.3428233878421769)
81
+ end
82
+ end
21
83
  end
@@ -0,0 +1,102 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Finance::Loan do
4
+ describe '#pmt' do
5
+ context 'w/o a full set of params' do
6
+ it 'calculates correct pmt value w/o :ptype' do
7
+ loan = Finance::Loan.new(nominal_rate: 0.1, duration: 12, amount: 1000)
8
+ expect(loan.pmt).to eq(87.9158872300099)
9
+ end
10
+
11
+ it 'calculates correct pmt value w/o :nominal_rate' do
12
+ loan = Finance::Loan.new(duration: 12, amount: 1200, ptype: :end)
13
+ expect(loan.pmt).to eq(100)
14
+ end
15
+ end
16
+
17
+ context 'with zero rates' do
18
+ it 'calculates correct pmt value for 3 years' do
19
+ loan = Finance::Loan.new(nominal_rate: 0, duration: 36, amount: 10_000, ptype: :end)
20
+ expect(loan.pmt).to eq(277.77777777777777)
21
+ end
22
+
23
+ it 'calculates correct pmt value for 6 months' do
24
+ loan = Finance::Loan.new(nominal_rate: 0, duration: 6, amount: 10_000, ptype: :end)
25
+ expect(loan.pmt).to eq(1666.6666666666667)
26
+ end
27
+ end
28
+
29
+ context 'with :beginning ptype' do
30
+ it 'calculates correct pmt value' do
31
+ loan = Finance::Loan.new(nominal_rate: 0.12, duration: 6, amount: 1000, ptype: :beginning)
32
+ expect(loan.pmt).to eq(170.8399670404763)
33
+ end
34
+ end
35
+
36
+ it 'calculates correct pmt value' do
37
+ loan = Finance::Loan.new(nominal_rate: 0.13, duration: 90, amount: 1_000_000, ptype: :end)
38
+ expect(loan.pmt).to eq(17_449.90775727763)
39
+ end
40
+ end
41
+
42
+ describe '#fv' do
43
+ context 'with loan arguments' do
44
+ it 'calculates correct fv value' do
45
+ loan = Finance::Loan.new(nominal_rate: 0.05, duration: 120, amount: -100, payment: -100)
46
+ expect(loan.fv).to eq(15_692.928894335748)
47
+ end
48
+
49
+ context 'with :ptype' do
50
+ it 'calculates correct fv value' do
51
+ loan = Finance::Loan.new(
52
+ nominal_rate: 0.9, duration: 20, amount: 0, payment: -2000, ptype: :beginning
53
+ )
54
+ expect(loan.fv).to eq(93_105.06487352113)
55
+ end
56
+ end
57
+ end
58
+
59
+ context 'with an optional :payment argument' do
60
+ it 'calculates correct fv value' do
61
+ loan = Finance::Loan.new(nominal_rate: 0.05, duration: 120, amount: -100, payment: -200)
62
+ expect(loan.fv(payment: -100)).to eq(15_692.928894335748)
63
+ end
64
+ end
65
+
66
+ context 'w/o any payments' do
67
+ it 'raises an ArgumentError exception w/o loan arguments' do
68
+ loan = Finance::Loan.new(nominal_rate: 0.05, duration: 120, amount: -100)
69
+ expect { loan.fv }.to raise_error(ArgumentError, "no payment given")
70
+ end
71
+ end
72
+ end
73
+
74
+ describe '#ipmt' do
75
+ context 'when 1 period' do
76
+ it 'calculates correct ipmt value' do
77
+ loan = Finance::Loan.new(
78
+ nominal_rate: 0.0824, duration: 12, amount: 2500, period: 1
79
+ )
80
+ expect(loan.ipmt).to eq(-17.166666666666668)
81
+ end
82
+ end
83
+
84
+ context 'when 2 periods' do
85
+ it 'calculates correct ipmt value' do
86
+ loan = Finance::Loan.new(
87
+ nominal_rate: 0.0824, duration: 12, amount: 2500, period: 2
88
+ )
89
+ expect(loan.ipmt).to eq(-15.789337457350777)
90
+ end
91
+ end
92
+
93
+ context 'when 3 periods' do
94
+ it 'calculates correct ipmt value' do
95
+ loan = Finance::Loan.new(
96
+ nominal_rate: 0.0824, duration: 12.0, amount: 2500.0, period: 3.0, fv: 0.0
97
+ )
98
+ expect(loan.ipmt).to eq(-14.402550587464257)
99
+ end
100
+ end
101
+ end
102
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: finance_rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vlad Dyachenko
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-03-22 00:00:00.000000000 Z
11
+ date: 2021-04-04 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A ruby port of numpy-financial functions. This library provides a Ruby
14
14
  interface for working with interest rates, mortgage amortization, and cashflows
@@ -27,15 +27,16 @@ files:
27
27
  - lib/finance/version.rb
28
28
  - lib/finance_rb.rb
29
29
  - spec/finance/calculations_spec.rb
30
+ - spec/finance/loan_spec.rb
30
31
  - spec/spec_helper.rb
31
32
  homepage: https://github.com/wowinter13/finance_rb
32
33
  licenses:
33
34
  - MIT
34
35
  metadata:
35
36
  bug_tracker_uri: https://github.com/wowinter13/finance_rb/issues
36
- changelog_uri: https://github.com/wowinter13/finance_rb/blob/v0.0.2/CHANGELOG.md
37
- documentation_uri: https://www.rubydoc.info/wowinter13/finance_rb/0.0.2
38
- source_code_uri: https://github.com/wowinter13/finance_rb/tree/v0.0.2
37
+ changelog_uri: https://github.com/wowinter13/finance_rb/blob/master/CHANGELOG.md
38
+ documentation_uri: https://www.rubydoc.info/github/wowinter13/finance_rb
39
+ source_code_uri: https://github.com/wowinter13/finance_rb
39
40
  post_install_message:
40
41
  rdoc_options: []
41
42
  require_paths:
@@ -57,4 +58,5 @@ specification_version: 4
57
58
  summary: A library for finance manipulations in Ruby.
58
59
  test_files:
59
60
  - spec/finance/calculations_spec.rb
61
+ - spec/finance/loan_spec.rb
60
62
  - spec/spec_helper.rb