-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcalculations.go
84 lines (73 loc) · 2.11 KB
/
calculations.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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package mortgauge
import "math"
func CalculateMonthlyPayment(
principal,
interestPercent float64,
termInMonths int,
) float64 {
step1 := (interestPercent / 100.0) / 12
step2 := math.Pow(1+step1, float64(termInMonths))
step3 := step2 - 1
step4 := step2 * step1
step5 := step4 / step3
return principal * step5
}
func AmortizationListing(
principal,
interestPercent float64,
termInMonths int,
) (listing []Amortization) {
iterator := NewAmortizationIterator(principal, interestPercent, termInMonths)
for iterator.NonZeroBalance() {
listing = append(listing, iterator.Next(0))
}
return listing
}
type Amortization struct {
StartingPrincipal float64
MonthlyPaymentOnPrincipal float64
ExtraPaymentOnPrincipal float64
MonthlyPaymentOnInterest float64
RemainingPrincipal float64
}
type AmortizationIterator struct {
principal float64
interestPercent float64
termInMonths int
payment float64
}
func NewAmortizationIterator(
principal,
interestPercent float64,
termInMonths int,
) *AmortizationIterator {
payment := CalculateMonthlyPayment(principal, interestPercent, termInMonths)
return &AmortizationIterator{
principal: principal,
interestPercent: interestPercent,
termInMonths: termInMonths,
payment: payment,
}
}
func (this *AmortizationIterator) MonthlyPayment() float64 {
return this.payment
}
func (this *AmortizationIterator) NonZeroBalance() bool {
return this.principal > 0
}
func (this *AmortizationIterator) Next(extraPayment float64) Amortization {
rate := (this.interestPercent / 100.0) / 12
paymentOnInterest := this.principal * rate
paymentOnPrincipal := (this.payment - paymentOnInterest) + extraPayment
defer this.applyPayment(paymentOnPrincipal)
return Amortization{
StartingPrincipal: this.principal,
MonthlyPaymentOnPrincipal: paymentOnPrincipal,
MonthlyPaymentOnInterest: paymentOnInterest,
ExtraPaymentOnPrincipal: extraPayment,
RemainingPrincipal: this.principal - paymentOnPrincipal,
}
}
func (this *AmortizationIterator) applyPayment(paymentOnPrincipal float64) {
this.principal -= paymentOnPrincipal
}