doughnut 0.0.2 → 0.0.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f01e3a907f5a02640cb2165b3dd0a54b43bcbd6a
4
- data.tar.gz: 25c3d9761f3cc8ce7206d93074228273add535bb
3
+ metadata.gz: 7bc1546c0df232365b38159c778448b343458f94
4
+ data.tar.gz: 19f2d1ef046b25fd11e9835f059ad87c6e5f06a1
5
5
  SHA512:
6
- metadata.gz: 41484a070fc62ec719cb2c4b7508d6192e50abd4adb571b03a1929db1b7f22721284136f80621b873e00e9d1b4c3d33549b816099d55849c061afe7113909d6c
7
- data.tar.gz: d7fd4748a4e1ad7574f34e53ef37e945812d54ca4e744bd45b0512b83c46fa0420fa664793a4f14ead07b3251c481a22ed9399e6fa96fcb6732529847bc29f81
6
+ metadata.gz: 35a7b3618af9f8358f79fbb2e5a400fb447a94a07521b2a15124818d548538e333c685a0a98694b17506b5b3cd52a380d4b87be89ddc83c02e629cbf8e4e3786
7
+ data.tar.gz: 3b10b380cda929553691e32e602928107cc2a51f97916b2da4bd863175b46f65d3861b3491d0d8ff62236abe435296182cd09d22be9234e79d4e8d938ceeeb5e
@@ -1,5 +1,7 @@
1
+ require "doughnut/expenses"
2
+ require "doughnut/income"
3
+ require "doughnut/retirement_calculator"
1
4
  require "doughnut/version"
2
- require "doughnut/capm"
3
5
 
4
6
  module Doughnut
5
7
  end
@@ -0,0 +1,45 @@
1
+ module Doughnut
2
+
3
+ class Expenses
4
+
5
+ attr_accessor :monthly_expenses, :inflation_rate
6
+
7
+ def initialize
8
+ @monthly_expenses = 2500
9
+ @inflation_rate = 0.0322
10
+ end
11
+
12
+ def future_expenses(death_date, discount_rate)
13
+ output = []
14
+ (Date.today..death_date).each do |mydate|
15
+ output << present_value(mydate, discount_rate) if is_last_day(mydate)
16
+ end
17
+ output
18
+ end
19
+
20
+ def total_expenses(death_date, discount_rate)
21
+ output = 0
22
+ future_expenses(death_date, discount_rate).each do |h|
23
+ output += h[:expense]
24
+ end
25
+ output
26
+ end
27
+
28
+ private
29
+
30
+ def is_last_day(mydate)
31
+ mydate.month != mydate.next_day.month
32
+ end
33
+
34
+ def present_value(mydate, discount_rate)
35
+ { date: mydate, expense: @monthly_expenses*discount_factor(mydate, discount_rate) }
36
+ end
37
+
38
+ def discount_factor(mydate, discount_rate)
39
+ t = (mydate - Date.today)/30
40
+ ((1 + @inflation_rate/12)/(1 + discount_rate/12))**t
41
+ end
42
+
43
+ end
44
+
45
+ end
@@ -0,0 +1,45 @@
1
+ module Doughnut
2
+
3
+ class Income
4
+
5
+ attr_accessor :monthly_income, :income_growth_rate
6
+
7
+ def initialize
8
+ @monthly_income = 3700
9
+ @income_growth_rate = 0.01
10
+ end
11
+
12
+ def future_income(death_date, discount_rate)
13
+ output = []
14
+ (Date.today..death_date).each do |mydate|
15
+ output << present_value(mydate, discount_rate) if is_last_day(mydate)
16
+ end
17
+ output
18
+ end
19
+
20
+ def total_income(death_date, discount_rate)
21
+ output = 0
22
+ future_expenses(death_date, discount_rate).each do |h|
23
+ output += h[:income]
24
+ end
25
+ output
26
+ end
27
+
28
+ private
29
+
30
+ def is_last_day(mydate)
31
+ mydate.month != mydate.next_day.month
32
+ end
33
+
34
+ def present_value(mydate, discount_rate)
35
+ { date: mydate, income: @monthly_income*discount_factor(mydate, discount_rate) }
36
+ end
37
+
38
+ def discount_factor(mydate, discount_rate)
39
+ t = (mydate - Date.today)/30
40
+ ((1 + @income_growth_rate/12)/(1 + discount_rate/12))**t
41
+ end
42
+
43
+ end
44
+
45
+ end
@@ -0,0 +1,24 @@
1
+ module Doughnut
2
+
3
+ class RetirementCalculator
4
+
5
+ attr_accessor :death_date, :portfolio_return
6
+
7
+ def initialize
8
+ @death_date = Date.new(2067,7,19)
9
+ @portfolio_return = 0.1
10
+ end
11
+
12
+ def retirement_date(total_expenses, monthly_incomes)
13
+ return Date.today if total_expenses == 0
14
+ return @death_date if monthly_incomes.length == 0
15
+ running_income = 0
16
+ monthly_incomes.each do |h|
17
+ running_income += h[:income]
18
+ return h[:date] if running_income >= total_expenses
19
+ end
20
+ end
21
+
22
+ end
23
+
24
+ end
@@ -1,3 +1,3 @@
1
1
  module Doughnut
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -0,0 +1,164 @@
1
+ require "spec_helper"
2
+
3
+ module Doughnut
4
+
5
+ describe Expenses do
6
+
7
+ before(:each) do
8
+ @expenses = Expenses.new
9
+ end
10
+
11
+ describe "parameters" do
12
+
13
+ it "returns average monthly expenses of $2500" do
14
+ expect(@expenses.monthly_expenses).to eq 2500
15
+ end
16
+
17
+ it "updates the average monthly expenses" do
18
+ @expenses.monthly_expenses = 52.55
19
+ expect(@expenses.monthly_expenses).to eq 52.55
20
+ end
21
+
22
+ it "returns an inflation rate of 3.22%" do
23
+ expect(@expenses.inflation_rate).to eq 0.0322
24
+ end
25
+
26
+ it "updates the average inflation rate" do
27
+ @expenses.inflation_rate = 0.112
28
+ expect(@expenses.inflation_rate).to eq 0.112
29
+ end
30
+
31
+ end
32
+
33
+ describe "predicted expenses" do
34
+
35
+ context "no inflation" do
36
+
37
+ before(:each) do
38
+ @expenses.inflation_rate = 0
39
+ end
40
+
41
+ it "returns no expenses if the death date has passed" do
42
+ allow(Date).to receive(:today) { Date.new(2070,1,1) }
43
+ expect(@expenses.future_expenses(Date.new(2065,1,1), 0.1)).to eq []
44
+ end
45
+
46
+ it "returns one date if there is only one month to the death date" do
47
+ allow(Date).to receive(:today) { Date.new(2067,6,19) }
48
+ future_expenses = @expenses.future_expenses(Date.new(2067,7,19), 0.1)
49
+ expect(future_expenses.first[:date]).to eq Date.new(2067,6,30)
50
+ end
51
+
52
+ it "returns one expense if there is only one month to the death date" do
53
+ allow(Date).to receive(:today) { Date.new(2067,6,19) }
54
+ future_expenses = @expenses.future_expenses(Date.new(2067,7,19), 0.1)
55
+ lower_bound = 0.99696173*2500
56
+ upper_bound = 0.99696174*2500
57
+ expect(future_expenses.first[:expense]).to be > lower_bound
58
+ expect(future_expenses.first[:expense]).to be < upper_bound
59
+ end
60
+
61
+ it "returns two dates if there are two months to the death date" do
62
+ allow(Date).to receive(:today) { Date.new(2067,5,22) }
63
+ future_expenses = @expenses.future_expenses(Date.new(2067,7,19), 0.1)
64
+ expect(future_expenses.first[:date]).to eq Date.new(2067,5,31)
65
+ expect(future_expenses.last[:date]).to eq Date.new(2067,6,30)
66
+ end
67
+
68
+ it "returns two expenses if there are two months to the death date" do
69
+ allow(Date).to receive(:today) { Date.new(2067,5,22) }
70
+ future_expenses = @expenses.future_expenses(Date.new(2067,7,19), 0.1)
71
+ lower_bound_one = 0.997513455*2500
72
+ upper_bound_one = 0.997513456*2500
73
+ lower_bound_two = 0.989269542*2500
74
+ upper_bound_two = 0.989269543*2500
75
+ expect(future_expenses.first[:expense]).to be > lower_bound_one
76
+ expect(future_expenses.first[:expense]).to be < upper_bound_one
77
+ expect(future_expenses.last[:expense]).to be > lower_bound_two
78
+ expect(future_expenses.last[:expense]).to be < upper_bound_two
79
+ end
80
+
81
+ it "returns many expenses if there are many months up to the death date" do
82
+ allow(Date).to receive(:today) { Date.new(2060,1,2) }
83
+ expect(@expenses.future_expenses(Date.new(2067,7,19), 0.1).length).to eq 90
84
+ end
85
+
86
+ end
87
+
88
+ context "non-zero inflation" do
89
+
90
+ before(:each) do
91
+ @expenses.inflation_rate = 0.01
92
+ end
93
+
94
+ it "returns no expenses if the death date has passed" do
95
+ allow(Date).to receive(:today) { Date.new(2088,1,1) }
96
+ expect(@expenses.future_expenses(Date.new(2067,7,19), 0.1)).to eq []
97
+ end
98
+
99
+ it "returns one expense if there is only one month to the death date" do
100
+ allow(Date).to receive(:today) { Date.new(2067,6,2) }
101
+ lower_bound = 0.99305612*2500
102
+ upper_bound = 0.99305613*2500
103
+ expect(@expenses.future_expenses(Date.new(2067,7,19), 0.1).first[:expense]).to be > lower_bound
104
+ expect(@expenses.future_expenses(Date.new(2067,7,19), 0.1).first[:expense]).to be < upper_bound
105
+ end
106
+
107
+ it "returns one date if there is only one month to the death date" do
108
+ allow(Date).to receive(:today) { Date.new(2067,6,2) }
109
+ expect(@expenses.future_expenses(Date.new(2067,7,19), 0.1).first[:date]).to eq Date.new(2067,6,30)
110
+ end
111
+
112
+ it "returns two dates if there are two months to the death date" do
113
+ allow(Date).to receive(:today) { Date.new(2067,5,25) }
114
+ expect(@expenses.future_expenses(Date.new(2067,7,19), 0.1).first[:date]).to eq Date.new(2067,5,31)
115
+ expect(@expenses.future_expenses(Date.new(2067,7,19), 0.1).last[:date]).to eq Date.new(2067,6,30)
116
+ end
117
+
118
+ it "returns two expenses if there are two months to the death date" do
119
+ allow(Date).to receive(:today) { Date.new(2067,5,25) }
120
+ lower_bound_one = 0.99850795*2500
121
+ upper_bound_one = 0.99850796*2500
122
+ lower_bound_two = 0.99108103*2500
123
+ upper_bound_two = 0.99108104*2500
124
+ expect(@expenses.future_expenses(Date.new(2067,7,19), 0.1).first[:expense]).to be > lower_bound_one
125
+ expect(@expenses.future_expenses(Date.new(2067,7,19), 0.1).first[:expense]).to be < upper_bound_one
126
+ expect(@expenses.future_expenses(Date.new(2067,7,19), 0.1).last[:expense]).to be > lower_bound_two
127
+ expect(@expenses.future_expenses(Date.new(2067,7,19), 0.1).last[:expense]).to be < upper_bound_two
128
+ end
129
+
130
+ it "returns many expenses if there are many months up to the death date" do
131
+ allow(Date).to receive(:today) { Date.new(2060,1,2) }
132
+ expect(@expenses.future_expenses(Date.new(2067,7,19), 0.1).length).to eq 90
133
+ end
134
+
135
+ end
136
+
137
+ describe "total expenses" do
138
+
139
+ it "calculates the total for one expense" do
140
+ @expenses.inflation_rate = 0
141
+ allow(Date).to receive(:today) { Date.new(2067,6,19) }
142
+ lower_bound = 0.99696173*2500
143
+ upper_bound = 0.99696174*2500
144
+ expect(@expenses.total_expenses(Date.new(2067,7,19), 0.1)).to be > lower_bound
145
+ expect(@expenses.total_expenses(Date.new(2067,7,19), 0.1)).to be < upper_bound
146
+ end
147
+
148
+ it "calculates the total for two expenses" do
149
+ @expenses.inflation_rate = 0
150
+ allow(Date).to receive(:today) { Date.new(2067,5,22) }
151
+ lower_bound = 0.997513455*2500 + 0.989269542*2500
152
+ upper_bound = 0.997513456*2500 + 0.989269543*2500
153
+ expect(@expenses.total_expenses(Date.new(2067,7,19), 0.1)).to be > lower_bound
154
+ expect(@expenses.total_expenses(Date.new(2067,7,19), 0.1)).to be < upper_bound
155
+ end
156
+
157
+ end
158
+
159
+ end
160
+
161
+
162
+ end
163
+
164
+ end
@@ -0,0 +1,148 @@
1
+ require "spec_helper"
2
+
3
+ module Doughnut
4
+
5
+ describe Income do
6
+
7
+ before(:each) do
8
+ @income = Income.new
9
+ end
10
+
11
+ describe "parameters" do
12
+
13
+ it "returns average monthly income of $3700" do
14
+ expect(@income.monthly_income).to eq 3700
15
+ end
16
+
17
+ it "updates the average monthly income" do
18
+ @income.monthly_income = 200
19
+ expect(@income.monthly_income).to eq 200
20
+ end
21
+
22
+ it "returns an income growth rate of 1%" do
23
+ expect(@income.income_growth_rate).to eq 0.01
24
+ end
25
+
26
+ it "updates the income growth rate" do
27
+ @income.income_growth_rate = 0.37
28
+ expect(@income.income_growth_rate).to eq 0.37
29
+ end
30
+
31
+ end
32
+
33
+ describe "predicted income" do
34
+
35
+ context "no income growth" do
36
+
37
+ before(:each) do
38
+ @income.income_growth_rate = 0
39
+ end
40
+
41
+ it "returns no income if the death date has passed" do
42
+ allow(Date).to receive(:today) { Date.new(2075,1,1) }
43
+ expect(@income.future_income(Date.new(2065,1,1), 0.1)).to eq []
44
+ end
45
+
46
+ it "returns one date if there is only one month to the death date" do
47
+ allow(Date).to receive(:today) { Date.new(2067,6,19) }
48
+ future_income = @income.future_income(Date.new(2067,7,19), 0.1)
49
+ expect(future_income.first[:date]).to eq Date.new(2067,6,30)
50
+ end
51
+
52
+ it "returns one income if there is only one month to the death date" do
53
+ allow(Date).to receive(:today) { Date.new(2067,6,19) }
54
+ future_income = @income.future_income(Date.new(2067,7,19), 0.1)
55
+ lower_bound = 0.99696173*3700
56
+ upper_bound = 0.99696174*3700
57
+ expect(future_income.first[:income]).to be > lower_bound
58
+ expect(future_income.first[:income]).to be < upper_bound
59
+ end
60
+
61
+ it "returns two dates if there are two months to the death date" do
62
+ allow(Date).to receive(:today) { Date.new(2067,5,22) }
63
+ future_income = @income.future_income(Date.new(2067,7,19), 0.1)
64
+ expect(future_income.first[:date]).to eq Date.new(2067,5,31)
65
+ expect(future_income.last[:date]).to eq Date.new(2067,6,30)
66
+ end
67
+
68
+ it "returns two incomes if there are two months to the death date" do
69
+ allow(Date).to receive(:today) { Date.new(2067,5,22) }
70
+ future_income = @income.future_income(Date.new(2067,7,19), 0.1)
71
+ lower_bound_one = 0.997513455*3700
72
+ upper_bound_one = 0.997513456*3700
73
+ lower_bound_two = 0.989269542*3700
74
+ upper_bound_two = 0.989269543*3700
75
+ expect(future_income.first[:income]).to be > lower_bound_one
76
+ expect(future_income.first[:income]).to be < upper_bound_one
77
+ expect(future_income.last[:income]).to be > lower_bound_two
78
+ expect(future_income.last[:income]).to be < upper_bound_two
79
+ end
80
+
81
+ it "returns many incomes if there are many months up to the death date" do
82
+ allow(Date).to receive(:today) { Date.new(2060,1,2) }
83
+ future_income = @income.future_income(Date.new(2067,7,19), 0.1)
84
+ expect(future_income.length).to eq 90
85
+ end
86
+
87
+ end
88
+
89
+ context "non-zero income growth" do
90
+
91
+ before(:each) do
92
+ @income.income_growth_rate = 0.03
93
+ end
94
+
95
+ it "returns no incomes if the death date has passed" do
96
+ allow(Date).to receive(:today) { Date.new(2088,1,1) }
97
+ future_income = @income.future_income(Date.new(2067,7,19), 0.1)
98
+ expect(future_income).to eq []
99
+ end
100
+
101
+ it "returns one date if there is only one month to the death date" do
102
+ allow(Date).to receive(:today) { Date.new(2067,6,3) }
103
+ future_income = @income.future_income(Date.new(2067,7,19), 0.1)
104
+ expect(future_income.first[:date]).to eq Date.new(2067,6,30)
105
+ end
106
+
107
+ it "returns one income if there is only one month to the death date" do
108
+ allow(Date).to receive(:today) { Date.new(2067,6,3) }
109
+ future_income = @income.future_income(Date.new(2067,7,19), 0.1)
110
+ lower_bound = 0.99479187*3700
111
+ upper_bound = 0.99479188*3700
112
+ expect(future_income.first[:income]).to be > lower_bound
113
+ expect(future_income.first[:income]).to be < upper_bound
114
+ end
115
+
116
+ it "returns two dates if there are two months to the death date" do
117
+ allow(Date).to receive(:today) { Date.new(2067,5,25) }
118
+ future_income = @income.future_income(Date.new(2067,7,19), 0.1)
119
+ expect(future_income.first[:date]).to eq Date.new(2067,5,31)
120
+ expect(future_income.last[:date]).to eq Date.new(2067,6,30)
121
+ end
122
+
123
+ it "returns two incomes if there are two months to the death date" do
124
+ allow(Date).to receive(:today) { Date.new(2067,5,25) }
125
+ future_income = @income.future_income(Date.new(2067,7,19), 0.1)
126
+ lower_bound_one = 0.99884028*3700
127
+ upper_bound_one = 0.99884029*3700
128
+ lower_bound_two = 0.99306187*3700
129
+ upper_bound_two = 0.99306188*3700
130
+ expect(future_income.first[:income]).to be > lower_bound_one
131
+ expect(future_income.first[:income]).to be < upper_bound_one
132
+ expect(future_income.last[:income]).to be > lower_bound_two
133
+ expect(future_income.last[:income]).to be < upper_bound_two
134
+ end
135
+
136
+ it "returns many incomes if there are many months up to the death date" do
137
+ allow(Date).to receive(:today) { Date.new(2060,1,2) }
138
+ future_income = @income.future_income(Date.new(2067,7,19), 0.1)
139
+ expect(future_income.length).to eq 90
140
+ end
141
+
142
+ end
143
+
144
+ end
145
+
146
+ end
147
+
148
+ end
@@ -0,0 +1,75 @@
1
+ require "spec_helper"
2
+
3
+ module Doughnut
4
+
5
+ describe RetirementCalculator do
6
+
7
+ before(:each) do
8
+ @retire = RetirementCalculator.new
9
+ end
10
+
11
+ describe "parameters" do
12
+
13
+ context "defaults" do
14
+
15
+ it "returns a death date of 80 years old" do
16
+ expect(@retire.death_date).to eq Date.new(2067,7,19)
17
+ end
18
+
19
+ it "returns average portfolio return of 10%" do
20
+ expect(@retire.portfolio_return).to eq 0.1
21
+ end
22
+
23
+ it "updates the death date" do
24
+ @retire.death_date = Date.new(2001,3,7)
25
+ expect(@retire.death_date).to eq Date.new(2001,3,7)
26
+ end
27
+
28
+ it "updates the average portfolio return" do
29
+ @retire.portfolio_return = 0.99
30
+ expect(@retire.portfolio_return).to eq 0.99
31
+ end
32
+
33
+ end
34
+
35
+ end
36
+
37
+ describe "retirement date" do
38
+
39
+ it "returns today's date if there are no monthly expenses or incomes" do
40
+ expect(@retire.retirement_date(0,[])).to eq Date.today
41
+ end
42
+
43
+ it "returns today's date if there are no monthly expenses but positive incomes" do
44
+ expect(@retire.retirement_date(0, [{date: Date.new(2012,1,2), income: 100}])).to eq Date.today
45
+ end
46
+
47
+ it "returns the death date if there is no monthly income" do
48
+ expect(@retire.retirement_date(1,[])).to eq Date.new(2067,7,19)
49
+ end
50
+
51
+ it "returns the date of earned income if PV(income) > PV(expenses)" do
52
+ params = [{:date => Date.new(2040,1,2), :income => 2000}]
53
+ expect(@retire.retirement_date(1000, params)).to eq Date.new(2040,1,2)
54
+ end
55
+
56
+ it "returns the date of earned income if PV(income) = PV(expenses)" do
57
+ params = [{:date => Date.new(2041,2,8), :income => 1000}]
58
+ expect(@retire.retirement_date(1000, params)).to eq Date.new(2041,2,8)
59
+ end
60
+
61
+ it "returns the date of earned income if PV(income) > PV(expenses) for multiple incomes" do
62
+ params = [{:date => Date.new(2040,1,2), :income => 999}, {:date => Date.new(2049,7,8), :income => 1000}]
63
+ expect(@retire.retirement_date(1000, params)).to eq Date.new(2049,7,8)
64
+ end
65
+
66
+ it "returns the date of earned income if PV(income) = PV(expenses) for multiple incomes" do
67
+ params = [{:date => Date.new(2040,1,2), :income => 999}, {:date => Date.new(2049,7,8), :income => 1}]
68
+ expect(@retire.retirement_date(1000, params)).to eq Date.new(2049,7,8)
69
+ end
70
+
71
+ end
72
+
73
+ end
74
+
75
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: doughnut
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cyrus Vandrevala
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-08 00:00:00.000000000 Z
11
+ date: 2015-05-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -80,9 +80,13 @@ files:
80
80
  - Rakefile
81
81
  - doughnut.gemspec
82
82
  - lib/doughnut.rb
83
- - lib/doughnut/capm.rb
83
+ - lib/doughnut/expenses.rb
84
+ - lib/doughnut/income.rb
85
+ - lib/doughnut/retirement_calculator.rb
84
86
  - lib/doughnut/version.rb
85
- - spec/capm_spec.rb
87
+ - spec/expenses_spec.rb
88
+ - spec/income_spec.rb
89
+ - spec/retirement_calculator_spec.rb
86
90
  - spec/spec_helper.rb
87
91
  homepage: ''
88
92
  licenses:
@@ -109,5 +113,7 @@ signing_key:
109
113
  specification_version: 4
110
114
  summary: Generate statistics for a personal portfolio.
111
115
  test_files:
112
- - spec/capm_spec.rb
116
+ - spec/expenses_spec.rb
117
+ - spec/income_spec.rb
118
+ - spec/retirement_calculator_spec.rb
113
119
  - spec/spec_helper.rb
@@ -1,6 +0,0 @@
1
- module Doughnut
2
-
3
- class CAPM
4
- end
5
-
6
- end
@@ -1,30 +0,0 @@
1
- require "spec_helper"
2
-
3
- module Doughnut
4
-
5
- describe CAPM do
6
-
7
- describe "risk free rate" do
8
- it "retrieves the risk free interest rate from Yahoo Finance"
9
- it "uses a default rate if Yahoo cannot be accessed"
10
- end
11
-
12
- describe "broad market rate" do
13
- it "estimates a broad market rate based on historical data"
14
- end
15
-
16
- describe "beta" do
17
- it "calculates beta for two correlated assets"
18
- it "calculates beta for two uncorrelated assets"
19
- it "calculates beta for two random assets"
20
- end
21
-
22
- describe "beta" do
23
- it "calculates beta for two correlated assets"
24
- it "calculates beta for two uncorrelated assets"
25
- it "calculates beta for two random assets"
26
- end
27
-
28
- end
29
-
30
- end