-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathirr.go
36 lines (33 loc) · 855 Bytes
/
irr.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package financial
import (
"errors"
"math"
)
const (
irrMaxInterations = 20
irrAccuracy = 1E-7
irrInitialGuess = 0
)
// IRR returns the Internal Rate of Return (IRR).
func IRR(values []float64) (float64, error) {
if len(values) == 0 {
return 0, errors.New("values must include the initial investment (usually negative number) and period cash flows")
}
x0 := float64(irrInitialGuess)
var x1 float64
for i := 0; i < irrMaxInterations; i++ {
fValue := float64(0)
fDerivative := float64(0)
for k := 0; k < len(values); k++ {
fk := float64(k)
fValue += values[k] / math.Pow(1.0+x0, fk)
fDerivative += -fk * values[k] / math.Pow(1.0+x0, fk+1.0)
}
x1 = x0 - fValue/fDerivative
if math.Abs(x1-x0) <= irrAccuracy {
return x1, nil
}
x0 = x1
}
return 0, errors.New("could not find irr for the provided values")
}