From 3acffe085d53885f8c5c2625d3768372ce0d9b36 Mon Sep 17 00:00:00 2001 From: Maksim Syomochkin Date: Thu, 16 Jan 2020 16:10:19 +0300 Subject: [PATCH] First commit --- go.mod | 3 +++ xirr.go | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 go.mod create mode 100644 xirr.go diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..b1d2454 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/maksim77/goxirr + +go 1.13 diff --git a/xirr.go b/xirr.go new file mode 100644 index 0000000..f9424ea --- /dev/null +++ b/xirr.go @@ -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 +}