gold is an outlier buuuuuut

This commit is contained in:
Bel LaPointe
2023-10-27 18:06:02 -06:00
parent 859e47f9e1
commit d517ee8457

View File

@@ -4,11 +4,16 @@ import (
"maps" "maps"
"math" "math"
"regexp" "regexp"
"slices"
"time" "time"
"gogs.inhome.blapointe.com/ana-ledger/ledger" "gogs.inhome.blapointe.com/ana-ledger/ledger"
) )
const (
month = time.Hour * 24 * 365 / 12
)
type Predictor func(ledger.Balances, time.Duration) ledger.Balances type Predictor func(ledger.Balances, time.Duration) ledger.Balances
func NewInterestPredictor(namePattern string, currencyPattern string, apy float64) Predictor { func NewInterestPredictor(namePattern string, currencyPattern string, apy float64) Predictor {
@@ -20,7 +25,7 @@ func NewInterestPredictor(namePattern string, currencyPattern string, apy float6
result[k] = maps.Clone(v) result[k] = maps.Clone(v)
} }
monthsPassed := float64(delta) / float64(time.Hour*24.0*365.0/12.0) monthsPassed := float64(delta) / float64(month)
scalar := math.Pow(1.0+apy/12.0, monthsPassed) scalar := math.Pow(1.0+apy/12.0, monthsPassed)
for name := range result { for name := range result {
if !nameMatcher.MatchString(name) { if !nameMatcher.MatchString(name) {
@@ -44,7 +49,6 @@ func NewContributionPredictor(reg ledger.Register) Predictor {
func newContributionPredictor(monthlyRate map[string]ledger.Balance) Predictor { func newContributionPredictor(monthlyRate map[string]ledger.Balance) Predictor {
return func(given ledger.Balances, delta time.Duration) ledger.Balances { return func(given ledger.Balances, delta time.Duration) ledger.Balances {
month := time.Hour * 24 * 365 / 12
months := float64(delta) / float64(month) months := float64(delta) / float64(month)
result := make(ledger.Balances) result := make(ledger.Balances)
for k, v := range given { for k, v := range given {
@@ -63,7 +67,8 @@ func newContributionPredictor(monthlyRate map[string]ledger.Balance) Predictor {
} }
func getMonthlyContributionRates(reg ledger.Register) map[string]ledger.Balance { func getMonthlyContributionRates(reg ledger.Register) map[string]ledger.Balance {
window := time.Hour * 24 * 365 / 2 window := 6 * month
window = 12 * month
contributions := getRecentContributions(reg, window) contributions := getRecentContributions(reg, window)
result := make(map[string]ledger.Balance) result := make(map[string]ledger.Balance)
for name := range contributions { for name := range contributions {
@@ -88,11 +93,27 @@ func getMonthlyContributionRate(contributions []ledger.Balance, window time.Dura
// TODO better than average // TODO better than average
func getMonthlyContributionRateForCurrency(contributions []ledger.Balance, window time.Duration, currency ledger.Currency) float64 { func getMonthlyContributionRateForCurrency(contributions []ledger.Balance, window time.Duration, currency ledger.Currency) float64 {
sum := 0.0 values := []float64{}
for _, balance := range contributions { for i := range contributions {
sum += balance[currency] if v, ok := contributions[i][currency]; ok {
values = append(values, v)
}
} }
return sum / (float64(window) / float64(time.Hour*24.0*365.0/12.0)) slices.Sort(values)
start := int(len(values) / 4)
end := min(1+max(0, len(values)-len(values)/4), len(values))
subvalues := values[start:end]
sum := 0.0
for _, v := range subvalues {
sum += v
}
standard := sum / float64(end-start)
standard = subvalues[len(subvalues)/2]
totalIfAllWereStandard := standard * float64(len(contributions))
result := totalIfAllWereStandard / float64(window) * float64(month)
//log.Printf("%s: %v contributions of about %.2f over %v can TLDR as %.2f per month from %v", currency, len(contributions), standard, window, result, values[start:end])
return result
} }
func getRecentContributions(reg ledger.Register, window time.Duration) map[string][]ledger.Balance { func getRecentContributions(reg ledger.Register, window time.Duration) map[string][]ledger.Balance {