Module: Apy::Calculable
- Included in:
- Interest
- Defined in:
- lib/apy/calculable.rb
Instance Method Summary collapse
-
#compound(principal, rate:, times:, terms:) ⇒ Object
Simple compound, assuming no additional investment over successive maturity terms.
-
#dca_compound(matrix, times:) ⇒ Object
“DCA” compound, assuming a recurring investment continuously added to the principal amount, this new amount additionally compounded for the next period.
-
#weighted_harmonic_mean(matrix) ⇒ Object
Calculate the weighted harmonic mean for a set of values (∑w) / (∑w/i).
Instance Method Details
#compound(principal, rate:, times:, terms:) ⇒ Object
Simple compound, assuming no additional investment over successive maturity terms
45 46 47 48 49 |
# File 'lib/apy/calculable.rb', line 45 def compound(principal, rate:, times:, terms:) total_rate = 1 + (rate / times) principal * (total_rate**(times * terms)) end |
#dca_compound(matrix, times:) ⇒ Object
TODO:
Clean this up, there is most likely an optimized formula for this 🤨
“DCA” compound, assuming a recurring investment continuously added to the principal amount, this new amount additionally compounded for the next period
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/apy/calculable.rb', line 59 def dca_compound(matrix, times:) result = matrix.each_with_object( total: 0, interest: 0, data: { 0 => { ytd: 0, in: 0, interest: 0 } } ).with_index do |(ary, out), i| additional_investment, rate = ary prev_ytd = out[:data][i][:ytd] to_compound = prev_ytd + additional_investment current = compound(to_compound, rate: rate, times: times, terms: 1) interest_this_period = current - to_compound out[:total] += additional_investment + interest_this_period out[:interest] += interest_this_period out[:data][i + 1] = {ytd: current, in: additional_investment, interest: interest_this_period} end result.fetch(:total) end |
#weighted_harmonic_mean(matrix) ⇒ Object
TODO:
Can make this a bit more performant with ‘inject`
Calculate the weighted harmonic mean for a set of values (∑w) / (∑w/i)
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/apy/calculable.rb', line 13 def weighted_harmonic_mean(matrix) sum = matrix.sum { |(n, _)| n }.to_f total_weight = [] weighted_values = [] matrix.each do |(investment, price)| weight = investment / sum total_weight << weight weighted_values << (weight / price) end total_weight.sum / weighted_values.sum end |