First commit
This commit is contained in:
40
xirr.go
Normal file
40
xirr.go
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package goxirr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Transaction struct {
|
||||||
|
Date time.Time
|
||||||
|
Cash float64
|
||||||
|
}
|
||||||
|
|
||||||
|
func Xirr(transactions []Transaction) float64 {
|
||||||
|
var years []float64
|
||||||
|
for _, ta := range transactions {
|
||||||
|
years = append(years, (ta.Date.Sub(transactions[0].Date).Hours()/24)/365)
|
||||||
|
}
|
||||||
|
residual := 1.0
|
||||||
|
step := 0.05
|
||||||
|
guess := 0.05
|
||||||
|
epsilon := 0.0001
|
||||||
|
limit := 10000
|
||||||
|
|
||||||
|
for math.Abs(residual) > epsilon && limit > 0 {
|
||||||
|
limit -= 1
|
||||||
|
residual = 0.0
|
||||||
|
for i, trans := range transactions {
|
||||||
|
residual += trans.Cash / math.Pow(guess, years[i])
|
||||||
|
}
|
||||||
|
if math.Abs(residual) > epsilon {
|
||||||
|
if residual > 0 {
|
||||||
|
guess += step
|
||||||
|
} else {
|
||||||
|
guess -= step
|
||||||
|
step /= 2.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (guess - 1) * 100
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user