Skip to content

Instantly share code, notes, and snippets.

@orcaman
Created June 3, 2017 14:15
Show Gist options
  • Save orcaman/ea104c4000ab0a55079aed8adb88e835 to your computer and use it in GitHub Desktop.
Save orcaman/ea104c4000ab0a55079aed8adb88e835 to your computer and use it in GitHub Desktop.
irr
package financial
import (
"fmt"
"math"
)
const irrMaxInterations = 20
const irrAccuracy = 1E-7
const irrInitialGuess = 0
// IRR return the Internal Rate of Return (IRR).
func IRR(values []float64) (float64, error) {
if len(values) == 0 {
return -1, fmt.Errorf("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 -1, fmt.Errorf("could not find irr for the provided values")
}
@sbinet
Copy link

sbinet commented Jun 12, 2017

const irrInitialGuess = 0

why not just:

const irrInitialGuess = 0.0

so you don't have to go through a cumbersome conversion at line 17?

@apmattil
Copy link

fk is unneeded variable
inner loop should be a function.. perhaps x0 and x1 in clousere function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment