This repository has been archived by the owner on Dec 17, 2020. It is now read-only.
/
model.go
51 lines (44 loc) · 1.6 KB
/
model.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package model
import (
"fmt"
"math"
"time"
)
func yearsToMonths(years float64) float64 {
return years * 12
}
func durationDescription(now time.Time, years float64) string {
oneYear := float64(time.Hour) * 24 * 365.24
goalTime := now.Add(time.Duration(math.Round(oneYear * years)))
return fmt.Sprintf("%.1f months (%.2f years) = %s",
yearsToMonths(years), years, goalTime.Format("2006-01-02"))
}
// Yearly yield: 0.03 means assumed yearly yield of 3%.
func PrintFiInfo(
total float64,
yearlyYield float64,
monthlyGoal float64,
monthlySaving float64) {
yield := 1.0 + yearlyYield
//fmt.Printf("Model inputs: yearly yield %.2f%%, monthly goal %.2f\n", yearlyYield*100.0, monthlyGoal)
monthlyDividend := math.Pow(yield, 1.0/12)
monthlyDivP := monthlyDividend - 1.0
perpetuityTarget := monthlyGoal / monthlyDivP
fmt.Printf("Perpetuity model: spend ≤%.2g%% monthly → need ≥%.2f.", monthlyDivP*100, perpetuityTarget)
now := time.Now()
if perpetuityTarget > total {
fmt.Printf("\nSaving %.2f per month:\n", monthlySaving)
var needYears float64 = YearsUntilSavedUpLinear(total, perpetuityTarget, monthlySaving)
fmt.Printf("Linear: need %s.\n", durationDescription(now, needYears))
needYears = YearsUntilSavedUpExp(total, yearlyYield, perpetuityTarget, monthlySaving)
fmt.Printf(" Exp: need %s.\n", durationDescription(now, needYears))
} else {
fmt.Printf(" %.0f%% ✓\n", (total/perpetuityTarget)*100)
}
fmt.Println()
}
func YearsUntilSavedUpLinear(
total float64, targetNumber float64, monthlySaving float64) float64 {
needMonths := (targetNumber - total) / monthlySaving
return needMonths / 12
}