finance_engine 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +46 -0
- data/LICENSE.txt +22 -0
- data/README.md +67 -0
- data/README.md~ +65 -0
- data/Rakefile +2 -0
- data/finance_engine.gemspec +26 -0
- data/lib/finance_engine/annuity.rb +11 -0
- data/lib/finance_engine/eareay.rb +66 -0
- data/lib/finance_engine/gordon_growth_model.rb +27 -0
- data/lib/finance_engine/optionpricing.rb +51 -0
- data/lib/finance_engine/tvm.rb +101 -0
- data/lib/finance_engine/version.rb +3 -0
- data/lib/finance_engine.rb +15 -0
- data/spec/entities/annuity_spec.rb +17 -0
- data/spec/entities/eareay_spec.rb +74 -0
- data/spec/entities/gordon_growth_model_spec.rb +42 -0
- data/spec/entities/optionpricing_spec.rb +31 -0
- data/spec/entities/tvm_spec.rb +121 -0
- data/spec/spec_helper.rb +3 -0
- metadata +142 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a461095fc7ba2a9fe186d3e9ad0d97b17578cc2f
|
4
|
+
data.tar.gz: 58b5fc4581f833b153a1c1a0b71c2bc38d6f99b4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 478421efb129d5123c87911e6f76cc6253aa77b8b1c76e5ed7aeaef5b227ae766d70fb9115b3895d3b2799fc068072224f45e54808052fbf224bc7c6afa475e6
|
7
|
+
data.tar.gz: 7480b5610dbb0d07d28266e3b5dc50855282c6a36e0186a29290734dc340d78fc224e422fd208a0deb1fa58f29bf3823b4bbd42f5b0e0822f93a27939763c164
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
finance_engine (0.0.1)
|
5
|
+
distribution
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
byebug (3.5.1)
|
11
|
+
columnize (~> 0.8)
|
12
|
+
debugger-linecache (~> 1.2)
|
13
|
+
slop (~> 3.6)
|
14
|
+
coderay (1.1.0)
|
15
|
+
columnize (0.8.9)
|
16
|
+
debugger-linecache (1.2.0)
|
17
|
+
diff-lcs (1.2.5)
|
18
|
+
distribution (0.7.1)
|
19
|
+
method_source (0.8.2)
|
20
|
+
pry (0.10.1)
|
21
|
+
coderay (~> 1.1.0)
|
22
|
+
method_source (~> 0.8.1)
|
23
|
+
slop (~> 3.4)
|
24
|
+
pry-byebug (2.0.0)
|
25
|
+
byebug (~> 3.4)
|
26
|
+
pry (~> 0.10)
|
27
|
+
rake (10.3.2)
|
28
|
+
rspec (2.14.1)
|
29
|
+
rspec-core (~> 2.14.0)
|
30
|
+
rspec-expectations (~> 2.14.0)
|
31
|
+
rspec-mocks (~> 2.14.0)
|
32
|
+
rspec-core (2.14.8)
|
33
|
+
rspec-expectations (2.14.5)
|
34
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
35
|
+
rspec-mocks (2.14.6)
|
36
|
+
slop (3.6.0)
|
37
|
+
|
38
|
+
PLATFORMS
|
39
|
+
ruby
|
40
|
+
|
41
|
+
DEPENDENCIES
|
42
|
+
bundler (~> 1.7)
|
43
|
+
finance_engine!
|
44
|
+
pry-byebug
|
45
|
+
rake (~> 10.0)
|
46
|
+
rspec
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 TODO: Write your name
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
# FinanceEngine
|
2
|
+
|
3
|
+
Finance Engine (Fe) is a hopefully growing open source library to assist in financial calculations and demonstrations.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'finance_engine'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install finance_engine
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
At the moment there are only five limited modules. Here we will try to demonstrate the basic argument inputs, it is advisable to check the tests for further details.
|
24
|
+
|
25
|
+
1) FA = FinanceEngine::Annuity
|
26
|
+
|
27
|
+
FA.present_value_perpetuity(annuity payment in dollars, rate of return, growth rate) - Will return the present value of a perpetuity.
|
28
|
+
|
29
|
+
FA.present_value_annuity(annuity payment in dollars, rate of return, n periods in payment, growth rate) - Will return the present value of an annuity with n periods remaining.
|
30
|
+
|
31
|
+
2) FEE = FinanceEngine::EAY_EAR
|
32
|
+
|
33
|
+
FEE.calculate_effective_annual_yield(annual interest rate, compounding periods) - returns the effective annual yield given the effective annual rate and compounding periods.
|
34
|
+
|
35
|
+
FEE.calculate_effective_annual_rate(effective annual yield, compounding periods) - returns the annual rate of return given the effective annual yeld and compounding periods.
|
36
|
+
|
37
|
+
FEE.calculate_EAY_payment(payment amount, effecive annual rate, periods compounded, periods per year) - Calculates the dollar value of a payment in the future with compounding.
|
38
|
+
|
39
|
+
FEE.calculate_EAR_payment(payment amount, effecive annual rate, periods compounded, periods per year) - Calculates the dollar value of a payment in the future without compounding.
|
40
|
+
|
41
|
+
FEE.compare_EAR_EAY(payment amount, effecive annual rate, periods compounded, periods per year) - Calculates the dollar value difference between a payment calculated with effective yield and without.
|
42
|
+
|
43
|
+
3) FE = FinanceEngine::Equity
|
44
|
+
|
45
|
+
FE.gordon_growth_model({ :rate => 0.05, :dividend => 100, :growth => 0.02, :value => 3333.33 }) - Using 3 of the 4 input values the Gordon Growth Model method will calculate the 4th input.
|
46
|
+
|
47
|
+
4) FBS = FinanceEngine::Black_Scholes
|
48
|
+
|
49
|
+
FBS.new({ :current_stock_price => 100, :time => 5, :strike_price => 95, :risk_free_rate => 0.05, :volatility => 0.25 }) - After initializing a new instance of Black_Scholes run the build options method. This will create and store the put call and price data on the instance of Black Scholes. This is different from the other modules in that it will store the variables in the instance.
|
50
|
+
|
51
|
+
5) FTVM = FinanceEngine::Time_Value_Money
|
52
|
+
|
53
|
+
FTVM.present_value_cash_flows(years, cashflows, rates) - Years, cashflows and rates are all arrays matching in length. This method will return the present value of a series of cash flows when given the time, amount and effective interest rates.
|
54
|
+
|
55
|
+
FTVM.future_value_cash_flows(years, cashflows, rates) - Years, cashflows and rates are all arrays matching in length. This method will return the future value of a series of cash flows when given the time, amount and effective interest rates.
|
56
|
+
|
57
|
+
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
## Contributing
|
62
|
+
|
63
|
+
1. Fork it ( https://github.com/[my-github-username]/finance_engine/fork )
|
64
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
65
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
66
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
67
|
+
5. Create a new Pull Request
|
data/README.md~
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
# FinanceEngine
|
2
|
+
|
3
|
+
Finance Engine (Fe) is a hopefully growing open source library to assist in financial calculations and demonstrations.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'finance_engine'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install finance_engine
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
At the moment there are only five limited modules. Here we will try to demonstrate the basic argument inputs, it is advisable to check the tests for further details.
|
24
|
+
|
25
|
+
1) FA = FinanceEngine::Annuity
|
26
|
+
|
27
|
+
FA.present_value_perpetuity(annuity payment in dollars, rate of return, growth rate) - Will return the present value of a perpetuity.
|
28
|
+
|
29
|
+
FA.present_value_annuity(annuity payment in dollars, rate of return, n periods in payment, growth rate) - Will return the present value of an annuity with n periods remaining.
|
30
|
+
|
31
|
+
2) FEE = FinanceEngine::EAY_EAR
|
32
|
+
|
33
|
+
FEE.calculate_effective_annual_yield(annual interest rate, compounding periods) - returns the effective annual yield given the effective annual rate and compounding periods.
|
34
|
+
|
35
|
+
FEE.calculate_effective_annual_rate(effective annual yield, compounding periods) - returns the annual rate of return given the effective annual yeld and compounding periods.
|
36
|
+
|
37
|
+
FEE.calculate_EAY_payment(payment amount, effecive annual rate, periods compounded, periods per year) - Calculates the dollar value of a payment in the future with compounding.
|
38
|
+
|
39
|
+
FEE.calculate_EAR_payment(payment amount, effecive annual rate, periods compounded, periods per year) - Calculates the dollar value of a payment in the future without compounding.
|
40
|
+
|
41
|
+
FEE.compare_EAR_EAY(payment amount, effecive annual rate, periods compounded, periods per year) - Calculates the dollar value difference between a payment calculated with effective yield and without.
|
42
|
+
|
43
|
+
3) FE = FinanceEngine::Equity
|
44
|
+
|
45
|
+
FE.gordon_growth_model({ :rate => 0.05, :dividend => 100, :growth => 0.02, :value => 3333.33 }) - Using 3 of the 4 input values the Gordon Growth Model method will calculate the 4th input.
|
46
|
+
|
47
|
+
4) FBS = FinanceEngine::Black_Scholes
|
48
|
+
|
49
|
+
FBS.new({ :current_stock_price => 100, :time => 5, :strike_price => 95, :risk_free_rate => 0.05, :volatility => 0.25 })
|
50
|
+
|
51
|
+
5) FTVM = FinanceEngine::Time_Value_Money
|
52
|
+
|
53
|
+
FTVM.
|
54
|
+
|
55
|
+
|
56
|
+
|
57
|
+
|
58
|
+
|
59
|
+
## Contributing
|
60
|
+
|
61
|
+
1. Fork it ( https://github.com/[my-github-username]/finance_engine/fork )
|
62
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
63
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
64
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
65
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'finance_engine/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "finance_engine"
|
8
|
+
spec.version = FinanceEngine::VERSION
|
9
|
+
spec.authors = ["Jeffrey Penkar"]
|
10
|
+
spec.email = ["jspenkar@gmail.com"]
|
11
|
+
spec.summary = %q{Financial Engine Gem. Financial methods and tools.}
|
12
|
+
spec.description = %q{Financial Engine Gem. Functionality for put/call pricing, annuity valuation, Gordon Growht Model valuation, time value of money module, and hopefully more to come.}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
22
|
+
spec.add_development_dependency "rspec"
|
23
|
+
spec.add_development_dependency 'pry-byebug'
|
24
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
25
|
+
spec.add_runtime_dependency "distribution"
|
26
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module FinanceEngine
|
2
|
+
class Annuity
|
3
|
+
def self.present_value_perpetuity(annuity, rate, growth=0)
|
4
|
+
annuity*(1+growth)/(rate-growth)
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.present_value_annuity(annuity, rate, periods, growth=0)
|
8
|
+
annuity /(rate - growth) *( 1 - ((1+growth)/(1+rate))**periods )
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module FinanceEngine
|
2
|
+
class EAY_EAR
|
3
|
+
def self.calculate_effective_annual_yield(annual_rate, periods)
|
4
|
+
(1+annual_rate/periods)**(periods)-1
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.calculate_effective_annual_rate(annual_yield, periods)
|
8
|
+
((annual_yield + 1)**(1/periods)-1)*periods
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.calculate_EAY_payment(amt, rate, time, periods)
|
12
|
+
amt * ((1+rate/periods)**(time))
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.calculate_EAR_payment(amt, rate, time, periods)
|
16
|
+
amt * ((1+rate)**(time.to_f/periods))
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.continuous_compounding(amt,rate,time)
|
20
|
+
amt * (Math::E**(rate*time))
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.compare_EAR_EAY_single_payment(amt,rate,time,periods)
|
24
|
+
calculate_EAY_payment(amt, rate, time, periods) - calculate_EAR_payment(amt, rate, time, periods)
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.compare_EAR_Continuous_single_payment(amt,rate,time,periods)
|
28
|
+
continuous_compounding(amt,rate,time/periods) - calculate_EAR_payment(amt, rate, time, periods)
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.compare_EAY_Continuous_single_payment(amt,rate,time,periods)
|
32
|
+
continuous_compounding(amt,rate,time/periods) - calculate_EAY_payment(amt, rate, time, periods)
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.calculate_EAR_series(amt, rate, time, periods)
|
36
|
+
sum = 0
|
37
|
+
1.upto(time) {|x| sum += calculate_EAR_payment(amt, rate, x, periods)}
|
38
|
+
sum
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.calculate_EAY_series(amt, rate, time, periods)
|
42
|
+
sum = 0
|
43
|
+
1.upto(time) {|x| sum += calculate_EAY_payment(amt, rate, x, periods)}
|
44
|
+
sum
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.calculate_CC_series(amt, rate, time, periods)
|
48
|
+
sum = 0
|
49
|
+
1.upto(time) {|x| sum += calculate_EAY_payment(amt, rate, time, periods)}
|
50
|
+
sum
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.compare_EAR_EAY_series_payment(amt,rate,time,periods)
|
54
|
+
calculate_EAY_series(amt, rate, time, periods) - calculate_EAR_series(amt, rate, time, periods)
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.compare_EAR_Continuous_series_payment(amt,rate,time,periods)
|
58
|
+
calculate_CC_series(amt, rate, time, periods) - calculate_EAR_series(amt, rate, time, periods)
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.compare_EAY_Continuous_series_payment(amt,rate,time,periods)
|
62
|
+
calculate_CC_series(amt, rate, time, periods) - calculate_EAY_series(amt, rate, time, periods)
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module FinanceEngine
|
2
|
+
class Equity
|
3
|
+
def self.gordon_growth_model(hash)
|
4
|
+
return ggm_value(hash) if hash[:value].nil?
|
5
|
+
return ggm_dividend(hash) if hash[:dividend].nil?
|
6
|
+
return ggm_rate(hash) if hash[:rate].nil?
|
7
|
+
return ggm_growth(hash) if hash[:growth].nil?
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.ggm_value(hash)
|
11
|
+
hash[:dividend] / (hash[:rate] - hash[:growth])
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.ggm_dividend(hash)
|
15
|
+
hash[:value] * (hash[:rate] - hash[:growth])
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.ggm_rate(hash)
|
19
|
+
hash[:growth] + (hash[:dividend] / hash[:value])
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.ggm_growth(hash)
|
23
|
+
hash[:rate] - (hash[:dividend] / hash[:value])
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'distribution'
|
2
|
+
module FinanceEngine
|
3
|
+
class Black_Scholes
|
4
|
+
attr_accessor :current_stock_price, :time, :strike_price, :risk_free_rate, :volatility, :d1, :d2, :call_price, :put_price
|
5
|
+
def initialize(hash)
|
6
|
+
@current_stock_price = hash[:price]
|
7
|
+
@strike_price = hash[:strike]
|
8
|
+
@time = hash[:time]
|
9
|
+
@risk_free_rate = hash[:riskfree]
|
10
|
+
@volatility = hash[:volatility]
|
11
|
+
@distr_normal = Distribution::Normal::Ruby_
|
12
|
+
end
|
13
|
+
|
14
|
+
def check_attr
|
15
|
+
msg = ''
|
16
|
+
msg += "Stock price is missing. " if @current_stock_price.nil?
|
17
|
+
msg += "Time period is missing. " if @time.nil?
|
18
|
+
msg += "Strike Price is missing. " if @strike_price.nil?
|
19
|
+
msg += "Risk free rate is missing. " if @risk_free_rate.nil?
|
20
|
+
msg += "Volatility rate is missing. " if @volatility.nil?
|
21
|
+
inputs = "{price: (Dollar Value), strike: (Dollar Value), time: (In Years), riskfree: (RF rate in decimal form (0.05)), volatility: (Volatility Percentage in decimal form (0.20))}"
|
22
|
+
# puts inputs if msg.length > 0
|
23
|
+
puts msg if msg.length > 0
|
24
|
+
end
|
25
|
+
|
26
|
+
def build_options
|
27
|
+
build_call_premium
|
28
|
+
build_put_premium
|
29
|
+
end
|
30
|
+
|
31
|
+
def build_call_premium
|
32
|
+
@d1 = (Math.log(@current_stock_price / @strike_price.to_f) + @time * (@risk_free_rate + ((@volatility ** 2) / 2))/ (@volatility * (@time**0.5)))
|
33
|
+
@d2 = (@d1 - (@volatility*(@time**0.5)))
|
34
|
+
@call_price = ( @current_stock_price * @distr_normal.cdf(@d1) ) - (@strike_price * Math::E**(@time * -@risk_free_rate) * @distr_normal.cdf(@d2) )
|
35
|
+
end
|
36
|
+
|
37
|
+
def build_put_premium
|
38
|
+
@put_price = ( @call_price + ( @strike_price * (Math::E**(@time * -@risk_free_rate)) ) - @current_stock_price )
|
39
|
+
end
|
40
|
+
|
41
|
+
def output
|
42
|
+
puts "Stock Call Price #{@call_price.round(4)}"
|
43
|
+
puts "Stock Put Price #{@put_price.round(4)}"
|
44
|
+
puts "Stock Price #{@current_stock_price}"
|
45
|
+
puts "Time #{@time}"
|
46
|
+
puts "Stock Strike Price #{@strike_price}"
|
47
|
+
puts "Stock Risk Free Rate #{@risk_free_rate}"
|
48
|
+
puts "Stock Volatility #{@volatility}"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
module FinanceEngine
|
2
|
+
class Time_Value_Money
|
3
|
+
def self.find_missing_variable(hash)
|
4
|
+
# attributes = {pv: present value, r: internal rate of return, fv: future value, n: number of payment periods, pmt: payment amount}
|
5
|
+
return find_fv(hash) if hash[:fv].nil?
|
6
|
+
return find_pv(hash) if hash[:pv].nil?
|
7
|
+
return find_r(hash) if hash[:r].nil?
|
8
|
+
return find_n(hash) if hash[:n].nil?
|
9
|
+
return find_pmt(hash) if hash[:pmt].nil?
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.find_fv(hash)
|
13
|
+
pv = future_value_cash_flow({cash_flow: hash[:pv], time: hash[:n], rate: hash[:r]})
|
14
|
+
pmt = fv_annuity(hash[:pmt], hash[:n], hash[:r])
|
15
|
+
fv = pv.to_f + pmt.to_f
|
16
|
+
return fv
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.find_pv(hash)
|
20
|
+
fv = present_value_cash_flow({cash_flow: hash[:fv], time: hash[:n], rate: hash[:r]})
|
21
|
+
pmt = pv_annuity(hash[:pmt], hash[:n], hash[:r])
|
22
|
+
pv = pmt + fv
|
23
|
+
return pv
|
24
|
+
end
|
25
|
+
|
26
|
+
# def self.find_r(hash)
|
27
|
+
# r = (hash[:fv]/hash[:pv])**((1/hash[:n])-1).to_f
|
28
|
+
# return r/100
|
29
|
+
# end
|
30
|
+
|
31
|
+
# def self.find_n(hash)
|
32
|
+
# # n = Math.log(1 - (hash[:fv]*hash[:r]/ hash[:pmt])) / Math.log(1+ hash[:r])
|
33
|
+
# # n += Math.log(hash[:fv]/hash[:pv]) / Math.log(1+ hash[:r])
|
34
|
+
# n = ((( hash[:pmt] *(1+hash[:r]) + -hash[:fv]/hash[:r]) / (hash[:pv] * hash[:r] + hash[:pmt]*(1+ hash[:r])))**(0.5))/((1+hash[:r])**(0.5))*100
|
35
|
+
|
36
|
+
# return n.round(4)
|
37
|
+
# end
|
38
|
+
|
39
|
+
#Calculates the annuity payment amount given the present value, future value, interest rate and amount of periods.
|
40
|
+
def self.find_pmt(hash)
|
41
|
+
# r[(PV - FV)/((1 + r)^n - 1) + PV]
|
42
|
+
# binding.pry
|
43
|
+
pmt = hash[:r] * ((hash[:pv] - hash[:fv])/((1+hash[:r])**(hash[:n])-1) + hash[:pv])
|
44
|
+
return pmt
|
45
|
+
end
|
46
|
+
|
47
|
+
#Calculates the present value of an annuity. Both formulas below, non-loop in use.
|
48
|
+
def self.pv_annuity(pmt,time,rate)
|
49
|
+
pv = pmt*(1-(1+rate)**-time)/rate
|
50
|
+
# pv = 0
|
51
|
+
# 1.upto(time) do |x|
|
52
|
+
# pv += pmt / ((1+rate)**x)
|
53
|
+
# end
|
54
|
+
return pv
|
55
|
+
end
|
56
|
+
|
57
|
+
#Calculates the future value of an annuity. Both formulas below, non-loop in use.
|
58
|
+
def self.fv_annuity(pmt,time,rate)
|
59
|
+
fv = pmt*((1+rate)**time -1)/rate
|
60
|
+
# fv = 0
|
61
|
+
# 1.upto(time) do |x|
|
62
|
+
# fv += pmt * ((1+rate)**(time-x))
|
63
|
+
# end
|
64
|
+
return fv
|
65
|
+
end
|
66
|
+
|
67
|
+
#Future value of a single cash flow taking in amount, rate and time as factors.
|
68
|
+
def self.future_value_cash_flow(hash)
|
69
|
+
cf = hash[:cash_flow]
|
70
|
+
rate = hash[:rate]
|
71
|
+
time = hash[:time]
|
72
|
+
return (cf * ((1 + rate)**time))
|
73
|
+
end
|
74
|
+
|
75
|
+
#Future value of a series of cash flows. Assumes payment occur at the end of period (inarrears).
|
76
|
+
def self.future_value_cash_flows(years, cashflows, rates, n)
|
77
|
+
future_value = 0
|
78
|
+
years.each_index do |x|
|
79
|
+
future_value += future_value_cash_flow({cash_flow: cashflows[x].to_f, rate: rates[x].to_f, time: n - years[x].to_f})
|
80
|
+
end
|
81
|
+
return future_value
|
82
|
+
end
|
83
|
+
|
84
|
+
#Present value of a single cash flow with hash input of amount, rate and time.
|
85
|
+
def self.present_value_cash_flow(hash)
|
86
|
+
cf = hash[:cash_flow]
|
87
|
+
rate = hash[:rate]
|
88
|
+
time = hash[:time]
|
89
|
+
return (cf / ((1 + rate)**time))
|
90
|
+
end
|
91
|
+
|
92
|
+
#Present value of a series of cash flows assuming varying interest rates.
|
93
|
+
def self.present_value_cash_flows(years, cashflows, rates)
|
94
|
+
present_value = 0
|
95
|
+
years.each_index do |x|
|
96
|
+
present_value += present_value_cash_flow({cash_flow: cashflows[x].to_f, rate: rates[x].to_f, time: years[x].to_f})
|
97
|
+
end
|
98
|
+
return present_value
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require "finance_engine/version"
|
2
|
+
require_relative 'finance_engine/optionpricing.rb'
|
3
|
+
require_relative 'finance_engine/tvm.rb'
|
4
|
+
require_relative 'finance_engine/eareay.rb'
|
5
|
+
require_relative 'finance_engine/annuity.rb'
|
6
|
+
require_relative 'finance_engine/gordon_growth_model.rb'
|
7
|
+
|
8
|
+
module FinanceEngine
|
9
|
+
def self.record=(x)
|
10
|
+
@record = x
|
11
|
+
end
|
12
|
+
def self.record
|
13
|
+
@record
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative '../spec_helper.rb'
|
2
|
+
|
3
|
+
describe FinanceEngine::Annuity do
|
4
|
+
it 'Should be able to find the present value of a growing or frozen perpetuity.' do
|
5
|
+
a = FinanceEngine::Annuity.present_value_perpetuity(100,0.05,0.02)
|
6
|
+
expect(a).to be_within(0.05).of(3400)
|
7
|
+
b = FinanceEngine::Annuity.present_value_perpetuity(100,0.05)
|
8
|
+
expect(b).to be_within(0.05).of(2000)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'Should be able to find the present value of a growing or frozen annuity.' do
|
12
|
+
a = FinanceEngine::Annuity.present_value_annuity(100, 0.05, 20, 0.02)
|
13
|
+
expect(a).to be_within(0.05).of(1466.55)
|
14
|
+
b = FinanceEngine::Annuity.present_value_annuity(100, 0.05, 20)
|
15
|
+
expect(b).to be_within(0.05).of(1246.20)
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require_relative '../spec_helper.rb'
|
2
|
+
|
3
|
+
describe FinanceEngine::EAY_EAR do
|
4
|
+
it 'Should be able to calculate Effective Annual Yield' do
|
5
|
+
a = FinanceEngine::EAY_EAR.calculate_effective_annual_yield(0.05, 12)
|
6
|
+
expect(a).to be_within(0.005).of(0.0511)
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'Should be able to calculate Effective Annual Rate' do
|
10
|
+
a = FinanceEngine::EAY_EAR.calculate_effective_annual_yield(0.0511, 12)
|
11
|
+
expect(a).to be_within(0.005).of(0.05)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should be able to calculate a payment using EAR. $1000, 5%, over 2 years compounded monthly.' do
|
15
|
+
a = FinanceEngine::EAY_EAR.calculate_EAR_payment(1000,0.05,24,12)
|
16
|
+
expect(a).to be_within(0.05).of(1102.50)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should be able to calculate a payment using EAY. $1000, 5%, over 2 years compounded monthly.' do
|
20
|
+
a = FinanceEngine::EAY_EAR.calculate_EAY_payment(1000,0.05,24,12)
|
21
|
+
expect(a).to be_within(0.05).of(1104.94)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'Should be able to calculate a payment assuming continuous compounding.' do
|
25
|
+
a = FinanceEngine::EAY_EAR.continuous_compounding(1000,0.05,2)
|
26
|
+
expect(a).to be_within(0.05).of(1105.17)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'Should be able to calculate the difference between EAR and EAY in dollar amounts.' do
|
30
|
+
a = FinanceEngine::EAY_EAR.compare_EAR_EAY_single_payment(1000,0.05,24,12)
|
31
|
+
expect(a).to be_within(0.05).of(2.44)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'Should be able to calculate the difference between EAY and continuous in dollar amounts.' do
|
35
|
+
a = FinanceEngine::EAY_EAR.compare_EAY_Continuous_single_payment(1000,0.05,24,12)
|
36
|
+
expect(a).to be_within(0.05).of(0.23)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'Should be able to calculate the difference between EAR and continuous in dollar amounts.' do
|
40
|
+
a = FinanceEngine::EAY_EAR.compare_EAR_Continuous_single_payment(1000,0.05,24,12)
|
41
|
+
expect(a).to be_within(0.05).of(2.67)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'Should be able to calculate the pv of a series of payments using EAR.' do
|
45
|
+
a = FinanceEngine::EAY_EAR.calculate_EAR_series(1000,0.05,24,12)
|
46
|
+
expect(a).to be_within(0.05).of(25261.28)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'Should be able to calculate the pv of a series of payments using EAR.' do
|
50
|
+
a = FinanceEngine::EAY_EAR.calculate_EAY_series(1000,0.05,24,12)
|
51
|
+
expect(a).to be_within(0.05).of(25290.86)
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'Should be able to calculate the pv of a series of payments using Continuous Compounding.' do
|
55
|
+
a = FinanceEngine::EAY_EAR.calculate_CC_series(1000,0.05,24,12)
|
56
|
+
expect(a).to be_within(0.05).of(26518.59)
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'Should be able to calculate the difference between EAR and EAY series of payment in dollar amounts.' do
|
60
|
+
a = FinanceEngine::EAY_EAR.compare_EAR_EAY_series_payment(1000,0.05,24,12)
|
61
|
+
expect(a).to be_within(0.05).of(29.58)
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'Should be able to calculate the difference between EAY and continuous series of payment in dollar amounts.' do
|
65
|
+
a = FinanceEngine::EAY_EAR.compare_EAR_Continuous_series_payment(1000,0.05,24,12)
|
66
|
+
expect(a).to be_within(0.05).of(1257.31)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'Should be able to calculate the difference between EAY and continuous series of payment in dollar amounts.' do
|
70
|
+
a = FinanceEngine::EAY_EAR.compare_EAY_Continuous_series_payment(1000,0.05,24,12)
|
71
|
+
expect(a).to be_within(0.05).of(1227.73)
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require_relative '../spec_helper.rb'
|
2
|
+
|
3
|
+
describe FinanceEngine::Equity do
|
4
|
+
it 'Should be able to calculate value given dividend, growth and rate of return.' do
|
5
|
+
hash = {dividend: 100, rate: 0.05, growth: 0.02}
|
6
|
+
a = FinanceEngine::Equity.ggm_value(hash)
|
7
|
+
expect(a).to be_within(0.005).of(3333.333)
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'Should be able to calculate dividend given value, growth and rate of return.' do
|
11
|
+
hash = {value: 3333.33, rate: 0.05, growth: 0.02}
|
12
|
+
a = FinanceEngine::Equity.ggm_dividend(hash)
|
13
|
+
expect(a).to be_within(0.005).of(100)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'Should be able to calculate rate given value, growth and dividend of return.' do
|
17
|
+
hash = {value: 3333.33, dividend: 100, growth: 0.02}
|
18
|
+
a = FinanceEngine::Equity.ggm_rate(hash)
|
19
|
+
expect(a).to be_within(0.005).of(0.05)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'Should be able to calculate growth given value, rate and dividend of return.' do
|
23
|
+
hash = {value: 3333.33, dividend: 100, rate: 0.05}
|
24
|
+
a = FinanceEngine::Equity.ggm_growth(hash)
|
25
|
+
expect(a).to be_within(0.005).of(0.02)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'Should be able to calculate value, rate, div or growth depending on what is missing.' do
|
29
|
+
hash = {dividend: 100, rate: 0.05, growth: 0.02}
|
30
|
+
a = FinanceEngine::Equity.gordon_growth_model(hash)
|
31
|
+
expect(a).to be_within(0.005).of(3333.333)
|
32
|
+
hash = {value: 3333.33, rate: 0.05, growth: 0.02}
|
33
|
+
b = FinanceEngine::Equity.gordon_growth_model(hash)
|
34
|
+
expect(b).to be_within(0.005).of(100)
|
35
|
+
hash = {value: 3333.33, dividend: 100, growth: 0.02}
|
36
|
+
c = FinanceEngine::Equity.gordon_growth_model(hash)
|
37
|
+
expect(c).to be_within(0.005).of(0.05)
|
38
|
+
hash = {value: 3333.33, dividend: 100, rate: 0.05}
|
39
|
+
d = FinanceEngine::Equity.gordon_growth_model(hash)
|
40
|
+
expect(d).to be_within(0.005).of(0.02)
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require_relative '../spec_helper.rb'
|
2
|
+
|
3
|
+
describe FinanceEngine::Black_Scholes do
|
4
|
+
it 'It should be able to accept variable for the Black Scholes model.' do
|
5
|
+
hash = {price: 25, strike: 30, time: 5, riskfree:0.05, volatility: 0.2}
|
6
|
+
a = FinanceEngine::Black_Scholes.new(hash)
|
7
|
+
expect(a.current_stock_price).to eq(25)
|
8
|
+
expect(a.time).to eq(5)
|
9
|
+
expect(a.strike_price).to eq(30)
|
10
|
+
expect(a.risk_free_rate).to eq(0.05)
|
11
|
+
expect(a.volatility).to eq(0.2)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'It should be able to calculate put and call prices.' do
|
15
|
+
hash = {price: 25, strike: 30, time: 5, riskfree:0.05, volatility: 0.2}
|
16
|
+
a = FinanceEngine::Black_Scholes.new(hash)
|
17
|
+
a.build_options
|
18
|
+
expect(a.put_price.round(4)).to eq(3.4068)
|
19
|
+
expect(a.call_price.round(4)).to eq(5.0428)
|
20
|
+
expect(a.d1.round(4)).to eq(0.6003)
|
21
|
+
expect(a.d2.round(4)).to eq(0.1531)
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
it 'It should be able to tell you what is missing.' do
|
26
|
+
hash = {strike: 30, time: 5, riskfree:0.05, volatility: 0.2}
|
27
|
+
a = FinanceEngine::Black_Scholes.new(hash)
|
28
|
+
STDOUT.should_receive(:puts).with("Stock price is missing. ")
|
29
|
+
a.check_attr
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require_relative '../spec_helper.rb'
|
2
|
+
|
3
|
+
describe FinanceEngine::Time_Value_Money do
|
4
|
+
it 'Should be able to calculate a single cash flow\'s present value.' do
|
5
|
+
hash = {cash_flow: 100, time: 1, rate: 0.10}
|
6
|
+
a = FinanceEngine::Time_Value_Money.present_value_cash_flow(hash)
|
7
|
+
expect(a.round(4)).to eq(90.9091)
|
8
|
+
hash = {cash_flow: 1000, time: 2, rate: 0.05}
|
9
|
+
a = FinanceEngine::Time_Value_Money.present_value_cash_flow(hash)
|
10
|
+
expect(a.round(4)).to eq(907.0295)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "Should be able to calculate the present value of a series of cash flows." do
|
14
|
+
years = [0,1,2,3,4]
|
15
|
+
cashflows = [-1000,250,250,250,250]
|
16
|
+
rates = [0.01,0.01,0.01,0.01,0.01]
|
17
|
+
a = FinanceEngine::Time_Value_Money.present_value_cash_flows(years, cashflows, rates)
|
18
|
+
expect(a.round(4)).to be_within(1).of(-24)
|
19
|
+
year1 = [1]; cashflow1 = [100]; rate1 = [0.1]
|
20
|
+
b = FinanceEngine::Time_Value_Money.present_value_cash_flows(year1, cashflow1, rate1)
|
21
|
+
expect(b.round(4)).to be_within(1).of(90)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'It should be able to calculate a single cash flow\'s future value.' do
|
25
|
+
hash = {cash_flow: 100, time: 2, rate: 0.10}
|
26
|
+
a = FinanceEngine::Time_Value_Money.future_value_cash_flow(hash)
|
27
|
+
expect(a.round(4)).to be_within(1).of(121.0)
|
28
|
+
hash = {cash_flow: 1000, time: 5, rate: 0.1}
|
29
|
+
a = FinanceEngine::Time_Value_Money.future_value_cash_flow(hash)
|
30
|
+
expect(a).to be_within(1).of(1610.0)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "Should be able to calculate the future value of a series of cash flows." do
|
34
|
+
years = [0,1,2,3,4]; cashflows = [-1000,250,250,250,250]; rates = [0.01,0.01,0.01,0.01,0.01]
|
35
|
+
a = FinanceEngine::Time_Value_Money.future_value_cash_flows(years, cashflows, rates,4)
|
36
|
+
expect(a.round(4)).to be_within(1).of(-25)
|
37
|
+
year1 = [0]; cashflow1 = [100]; rate1 = [0.1]
|
38
|
+
b = FinanceEngine::Time_Value_Money.future_value_cash_flows(year1, cashflow1, rate1,1)
|
39
|
+
expect(b.round(4)).to be_within(1).of(110)
|
40
|
+
year1 = [1]; cashflow1 = [100]; rate1 = [0.1]
|
41
|
+
b = FinanceEngine::Time_Value_Money.future_value_cash_flows(year1, cashflow1, rate1,2)
|
42
|
+
expect(b.round(4)).to be_within(1).of(110)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "Should be able to calculate the PV of an Annuity." do
|
46
|
+
a = FinanceEngine::Time_Value_Money.pv_annuity(100, 1, 0.1)
|
47
|
+
expect(a).to be_within(1).of(90)
|
48
|
+
a = FinanceEngine::Time_Value_Money.pv_annuity(100, 5, 0.1)
|
49
|
+
expect(a).to be_within(1).of(379)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "Should be able to calculate the FV of an Annuity." do
|
53
|
+
a = FinanceEngine::Time_Value_Money.fv_annuity(100, 1, 0.1)
|
54
|
+
expect(a).to be_within(1).of(100)
|
55
|
+
a = FinanceEngine::Time_Value_Money.fv_annuity(100, 2, 0.1)
|
56
|
+
expect(a).to be_within(1).of(210)
|
57
|
+
a = FinanceEngine::Time_Value_Money.fv_annuity(100, 5, 0.1)
|
58
|
+
expect(a).to be_within(1).of(610)
|
59
|
+
end
|
60
|
+
|
61
|
+
it "Should be able to calculate the FV given n, t, r, and pv." do
|
62
|
+
hash = {pv: 1000,r: 0.10, n:5, pmt: 100}
|
63
|
+
a = FinanceEngine::Time_Value_Money.find_fv(hash)
|
64
|
+
expect(a).to be_within(1).of(2221)
|
65
|
+
hash = {pv: 0,r: 0.10, n:5, pmt: 100}
|
66
|
+
a = FinanceEngine::Time_Value_Money.find_fv(hash)
|
67
|
+
expect(a).to be_within(1).of(610)
|
68
|
+
hash = {pv: 1000,r: 0.10, n:5, pmt: 0}
|
69
|
+
a = FinanceEngine::Time_Value_Money.find_fv(hash)
|
70
|
+
expect(a).to be_within(1).of(1610)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "Should be able to calculate the PV given n, t, r, and fv." do
|
74
|
+
hash = {fv: 1000, r: 0.10, n:5, pmt: 0}
|
75
|
+
a = FinanceEngine::Time_Value_Money.find_pv(hash)
|
76
|
+
expect(a).to be_within(1).of(620)
|
77
|
+
hash = {fv: 0, r: 0.10, n:5, pmt: 100}
|
78
|
+
a = FinanceEngine::Time_Value_Money.find_pv(hash)
|
79
|
+
expect(a).to be_within(1).of(380)
|
80
|
+
hash = {fv: 1000, r: 0.10, n:5, pmt: 100}
|
81
|
+
a = FinanceEngine::Time_Value_Money.find_pv(hash)
|
82
|
+
expect(a).to be_within(1).of(1000)
|
83
|
+
end
|
84
|
+
|
85
|
+
it "Should be able to calculate the payment given all else." do
|
86
|
+
hash = {fv: 0, n: 4, pv:-100, r: 0.1}
|
87
|
+
a = FinanceEngine::Time_Value_Money.find_pmt(hash)
|
88
|
+
expect(a).to be_within(1).of(-31)
|
89
|
+
hash = {fv: 1000, n: 10, pv:0, r: 0.1}
|
90
|
+
a = FinanceEngine::Time_Value_Money.find_pmt(hash)
|
91
|
+
expect(a).to be_within(1).of(-62.75)
|
92
|
+
hash = {fv: -1000, n: 10, pv:1000, r: 0.1}
|
93
|
+
a = FinanceEngine::Time_Value_Money.find_pmt(hash)
|
94
|
+
expect(a).to be_within(1).of(225.75)
|
95
|
+
end
|
96
|
+
|
97
|
+
xit "Should be able to calculate the rate given all else." do
|
98
|
+
hash = {fv: 200, n: 5, pv:-200, pmt: 10}
|
99
|
+
a = FinanceEngine::Time_Value_Money.find_r(hash)
|
100
|
+
expect(a).to eq(0.05)
|
101
|
+
end
|
102
|
+
|
103
|
+
xit "Should be able to calculate the N given pv, pmt, r, and fv." do
|
104
|
+
hash = {fv: 200, r: 0.10, pv:-50, pmt: 100}
|
105
|
+
a = FinanceEngine::Time_Value_Money.find_n(hash)
|
106
|
+
expect(a).to eq(1)
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'Should be able to figure out what is missing from a set of parameters and start calc to figure out missing value.' do
|
110
|
+
a = FinanceEngine::Time_Value_Money.find_missing_variable({fv: 1000, r: 0.10, n:5, pmt: 0})
|
111
|
+
expect(a).to be_within(1).of(620)
|
112
|
+
b = FinanceEngine::Time_Value_Money.find_missing_variable({pv: 1000,r: 0.10, n:5, pmt: 100})
|
113
|
+
expect(b).to be_within(1).of(2221)
|
114
|
+
c = FinanceEngine::Time_Value_Money.find_missing_variable({fv: -1000, n: 10, pv:1000, r: 0.1})
|
115
|
+
expect(c).to be_within(1).of(225.75)
|
116
|
+
# d = FinanceEngine::Time_Value_Money.find_missing_variable({})
|
117
|
+
|
118
|
+
# e = FinanceEngine::Time_Value_Money.find_missing_variable({})
|
119
|
+
|
120
|
+
end
|
121
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: finance_engine
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jeffrey Penkar
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-11-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pry-byebug
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: distribution
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: Financial Engine Gem. Functionality for put/call pricing, annuity valuation,
|
84
|
+
Gordon Growht Model valuation, time value of money module, and hopefully more to
|
85
|
+
come.
|
86
|
+
email:
|
87
|
+
- jspenkar@gmail.com
|
88
|
+
executables: []
|
89
|
+
extensions: []
|
90
|
+
extra_rdoc_files: []
|
91
|
+
files:
|
92
|
+
- Gemfile
|
93
|
+
- Gemfile.lock
|
94
|
+
- LICENSE.txt
|
95
|
+
- README.md
|
96
|
+
- README.md~
|
97
|
+
- Rakefile
|
98
|
+
- finance_engine.gemspec
|
99
|
+
- lib/finance_engine.rb
|
100
|
+
- lib/finance_engine/annuity.rb
|
101
|
+
- lib/finance_engine/eareay.rb
|
102
|
+
- lib/finance_engine/gordon_growth_model.rb
|
103
|
+
- lib/finance_engine/optionpricing.rb
|
104
|
+
- lib/finance_engine/tvm.rb
|
105
|
+
- lib/finance_engine/version.rb
|
106
|
+
- spec/entities/annuity_spec.rb
|
107
|
+
- spec/entities/eareay_spec.rb
|
108
|
+
- spec/entities/gordon_growth_model_spec.rb
|
109
|
+
- spec/entities/optionpricing_spec.rb
|
110
|
+
- spec/entities/tvm_spec.rb
|
111
|
+
- spec/spec_helper.rb
|
112
|
+
homepage: ''
|
113
|
+
licenses:
|
114
|
+
- MIT
|
115
|
+
metadata: {}
|
116
|
+
post_install_message:
|
117
|
+
rdoc_options: []
|
118
|
+
require_paths:
|
119
|
+
- lib
|
120
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - '>='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
126
|
+
requirements:
|
127
|
+
- - '>='
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: '0'
|
130
|
+
requirements: []
|
131
|
+
rubyforge_project:
|
132
|
+
rubygems_version: 2.4.2
|
133
|
+
signing_key:
|
134
|
+
specification_version: 4
|
135
|
+
summary: Financial Engine Gem. Financial methods and tools.
|
136
|
+
test_files:
|
137
|
+
- spec/entities/annuity_spec.rb
|
138
|
+
- spec/entities/eareay_spec.rb
|
139
|
+
- spec/entities/gordon_growth_model_spec.rb
|
140
|
+
- spec/entities/optionpricing_spec.rb
|
141
|
+
- spec/entities/tvm_spec.rb
|
142
|
+
- spec/spec_helper.rb
|