-
-
Save sletix/ce8c2c4ad916dd7aed030a6ec2cc772d to your computer and use it in GitHub Desktop.
IRR Calc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'date' | |
# ruby implemenation from js | |
# http://jsfiddle.net/exmmo/m5kbb0up/ | |
# https://habr.com/ru/post/233987/ | |
module IRRCalc | |
# args: | |
# | |
# * входящие данные - даты платежей | |
# dates = [ Date.new(2014, 9, 1), Date.new(2014, 10, 1), Date.new(2014, 11, 1), Date.new(2014, 12, 1) ] | |
# | |
# * входящие данные - суммы платежей | |
# payments = [-100000, 34002.21, 34002.21, 34002.21 ] | |
# | |
def self.perform(dates, payments) | |
m = dates.count # число платежей | |
bp = 30.0 # Задаем базвый период bp | |
cbp = (365 / bp).round # Считаем число базовых периодов в году: | |
# заполним массив с количеством дней с даты выдачи до даты к-го платежа | |
days = [] | |
m.times do |i| | |
days[i] = ((dates[i].to_time.to_i - dates[0].to_time.to_i) / (24.0 * 60 * 60)) | |
end | |
# посчитаем Ек и Qк для каждого платежа | |
e = [] | |
q = [] | |
m.times do |k| | |
e[k] = (days[k] % bp) / bp | |
q[k] = (days[k] / bp).floor | |
end | |
# Втупую методом перебора начиная с 0 ищем i до максимального приблежения с шагом s | |
i = 0 | |
x = 1 | |
x_m = 0 | |
s = 0.000001 | |
while (x > 0) do | |
x_m = x | |
x = 0 | |
m.times do |k| | |
x = x + payments[k] / ((1 + e[k] * i) * (1+i)**q[k]) | |
end | |
i = i + s | |
end | |
i = i - s if x > x_m | |
# считаем ПСК | |
(i * cbp * 100 * 1000).floor / 1000.0 | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
RSpec.describe IRRCalc do | |
let(:dates) { [ Date.new(2014, 9, 1), Date.new(2014, 10, 1), Date.new(2014, 11, 1), Date.new(2014, 12, 1) ] } | |
let(:payments) { [-100000, 34002.21, 34002.21, 34002.21 ] } | |
it 'should return calculated irr' do | |
expect(described_class.perform(dates, payments)).to eq 11.863 | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment