doughnut 0.0.2 → 0.0.3

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
  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