diff --git a/ledger/register.go b/ledger/register.go index dd4e7b6..73facd3 100644 --- a/ledger/register.go +++ b/ledger/register.go @@ -4,6 +4,7 @@ import ( "fmt" "io" "log" + "maps" "slices" "time" ) @@ -41,23 +42,56 @@ func RegisterWithContributionPrediction(reg map[string]Balances, windowAsPercent return result }() - result := make(map[string]Balances) + result := maps.Clone(reg) for name, datesBalance := range namesDatesBalance { - result[name] = func() Balances { - dates := func() []string { - result := make([]string, 0) - for k := range datesBalance { - result = append(result, k) - } - return result - }() - slices.Sort(dates) + dates := func() []int64 { + result := make([]int64, 0) + for k := range datesBalance { + v, _ := registerTime(k) + result = append(result, v.Unix()) + } + slices.Sort(result) + return result + }() + weightedAverageContribution := func() map[Currency]float64 { half := dates[len(dates)/2] threeQuarter := dates[int(3.0*(len(dates)/4.0))] sevenEighths := dates[int(7.0*(len(dates)/8.0))] - sum:= func(start, stop string) balance - panic(fmt.Sprintf("%s: %s .. %s .. %s (%v)", name, half, threeQuarter, sevenEighths, dates)) + get := func(a, b int64) []Balance { + result := make([]Balance, 0) + for date, balance := range datesBalance { + v, _ := registerTime(date) + if v2 := v.Unix(); a <= v2 && v2 <= b { + result = append(result, balance) + } + } + return result + } + halfUp := get(half, threeQuarter) + threeQuarterUp := get(threeQuarter, sevenEighths) + sevenEighthsUp := get(sevenEighths, time.Now().Add(time.Hour*24*365).Unix()) + weightedSum := make(map[Currency]float64, 0) + pushes := 0 + pushWithWeight := func(b []Balance, weight int) { + for i, b2 := range b[1:] { + for c := range b2 { + v := b2[c] - b[i][c] + for i := 0; i < weight; i++ { + weightedSum[c] += v + pushes += 1 + } + } + } + } + pushWithWeight(halfUp, 1) + pushWithWeight(threeQuarterUp, 2) + pushWithWeight(sevenEighthsUp, 4) + for k, v := range weightedSum { + weightedSum[k] = v / float64(pushes) + } + return weightedSum }() + panic(fmt.Sprintf("%s: %v", name, weightedAverageContribution)) } return result, nil }